[work]: converting the service to an Arc<Vec<ServiceItem>>

This could likely save us some performance
This commit is contained in:
Chris Cochrun 2026-04-09 12:51:37 -05:00
parent d955551cd2
commit ea2d40a224
4 changed files with 49 additions and 28 deletions

View file

@ -9,6 +9,7 @@ use std::{
io::Write,
iter,
path::{Path, PathBuf},
sync::Arc,
};
use tar::{Archive, Builder};
use tracing::{debug, error};
@ -16,7 +17,7 @@ use zstd::{Decoder, Encoder};
#[allow(clippy::too_many_lines)]
pub fn save(
list: Vec<ServiceItem>,
list: Arc<Vec<ServiceItem>>,
path: impl AsRef<Path>,
overwrite: bool,
) -> Result<()> {
@ -85,7 +86,7 @@ pub fn save(
Ok(())
};
for item in list {
for item in list.iter() {
let background;
let audio: Option<PathBuf>;
match &item.kind {
@ -131,11 +132,11 @@ pub fn save(
debug!(?path);
append_file(path)?;
}
for slide in item.slides {
if let Some(svg) = slide.text_svg
&& let Some(path) = svg.path
for slide in &item.slides {
if let Some(svg) = &slide.text_svg
&& let Some(path) = &svg.path
{
append_file(path)?;
append_file(path.to_path_buf())?;
}
}
}
@ -515,7 +516,7 @@ mod test {
fn test_save() {
let path = PathBuf::from("./test.pres");
let list = get_items();
match save(list, &path, true) {
match save(Arc::new(list), &path, true) {
Ok(_) => {
assert!(path.is_file());
let Ok(file) = fs::File::open(path) else {

View file

@ -150,7 +150,7 @@ struct App {
file: PathBuf,
presenter: Presenter,
windows: Vec<window::Id>,
service: Vec<ServiceItem>,
service: Arc<Vec<ServiceItem>>,
selected_items: Vec<usize>,
current_item: (usize, usize),
hovered_item: Option<usize>,
@ -342,7 +342,7 @@ impl cosmic::Application for App {
// item
// })
// .collect();
let items: Vec<ServiceItem> = vec![];
let items: Arc<Vec<ServiceItem>> = Arc::new(vec![]);
let presenter = Presenter::with_items(items.clone());
let song_editor = SongEditor::new(Arc::clone(&fontdb));
@ -1252,7 +1252,7 @@ impl cosmic::Application for App {
Task::none()
}
Message::AddServiceItem(index, item) => {
self.service.insert(index, item);
Arc::make_mut(&mut self.service).insert(index, item);
self.presenter.update_items(self.service.clone());
self.hovered_dnd = None;
Task::none()
@ -1337,7 +1337,7 @@ impl cosmic::Application for App {
Task::batch(tasks)
}
Message::RemoveServiceItem(index) => {
self.service.remove(index);
Arc::make_mut(&mut self.service).remove(index);
self.presenter.update_items(self.service.clone());
Task::none()
}
@ -1367,7 +1367,7 @@ impl cosmic::Application for App {
.unwrap_or(slide)
})
.collect();
self.service.push(item);
Arc::make_mut(&mut self.service).push(item);
self.presenter.update_items(self.service.clone());
Task::none()
}
@ -1376,8 +1376,10 @@ impl cosmic::Application for App {
self.update(Message::AppendServiceItem(item))
}
Message::ReorderService(index, target_index) => {
let item = self.service.remove(index);
self.service.insert(target_index, item);
let item =
Arc::make_mut(&mut self.service).remove(index);
Arc::make_mut(&mut self.service)
.insert(target_index, item);
self.presenter.update_items(self.service.clone());
Task::none()
}
@ -1468,8 +1470,8 @@ impl cosmic::Application for App {
)
}
Message::OpenLoadItems(items) => {
self.service = items.clone();
self.presenter.service = items;
self.service = Arc::new(items);
self.presenter.service = self.service.clone();
Task::none()
}
Message::Save => {
@ -1477,7 +1479,9 @@ impl cosmic::Application for App {
let file = self.file.clone();
let file_name = self.file.file_name().expect("Since we are saving we should have given a name by now").to_owned();
Task::perform(
async move { file::save(service, file, true) },
async move {
file::save(service.to_owned(), file, true)
},
move |res| match res {
Ok(()) => {
tracing::info!(

View file

@ -48,7 +48,7 @@ static DEFAULT_SLIDE: LazyLock<Slide> = LazyLock::new(Slide::default);
// #[derive(Default, Clone, Debug)]
pub(crate) struct Presenter {
pub service: Vec<ServiceItem>,
pub service: Arc<Vec<ServiceItem>>,
pub current_slide: Slide,
pub current_item: usize,
pub current_slide_index: usize,
@ -138,7 +138,7 @@ impl menu::Action for MenuAction {
}
impl Presenter {
pub fn with_items(items: Vec<ServiceItem>) -> Self {
pub fn with_items(items: Arc<Vec<ServiceItem>>) -> Self {
let video = {
items.first().and_then(|item| {
item.slides.first().and_then(|slide| {
@ -904,7 +904,7 @@ impl Presenter {
}
}
pub fn update_items(&mut self, items: Vec<ServiceItem>) {
pub fn update_items(&mut self, items: Arc<Vec<ServiceItem>>) {
let total_slides: usize =
items.iter().fold(0, |a, item| a + item.slides.len());
self.service = items;
@ -1072,7 +1072,7 @@ mod test {
#[test]
fn test_next_slide() -> Result<()> {
let service = test_service();
let mut presenter = Presenter::with_items(service);
let mut presenter = Presenter::with_items(Arc::new(service));
presenter.update(Message::NextSlide);
dbg!(&presenter.service);
assert_eq!(presenter.current_item, 1);

View file

@ -7,12 +7,12 @@ use cosmic::{
iced_widget::{column, row},
theme,
widget::{
Space, button, container, icon,
Space, button, container, icon, slider,
space::{self, horizontal},
text, text_input,
},
};
use iced_video_player::{Video, VideoPlayer};
use iced_video_player::{Position, Video, VideoPlayer};
use tracing::{debug, error, warn};
use url::Url;
@ -42,6 +42,7 @@ pub enum Message {
None,
PauseVideo,
UpdateVideoFile(videos::Video),
VideoPos(f64),
}
impl VideoEditor {
@ -81,6 +82,19 @@ impl VideoEditor {
warn!(?video);
return Action::UpdateVideo(video);
}
Message::VideoPos(position) => {
if let Some(video) = self.video.as_mut() {
let pausing = video.paused();
video.set_paused(true);
let position = Position::Time(
std::time::Duration::from_secs_f64(position),
);
if let Err(e) = video.seek(position, false) {
error!(?e);
}
video.set_paused(pausing);
}
}
Message::PickVideo => {
let video_id = self
.core_video
@ -119,12 +133,14 @@ impl VideoEditor {
icon::from_name("media-playback-pause")
})
.on_press(Message::PauseVideo);
let video_track = cosmic::iced_widget::progress_bar(
0.0..=video.duration().as_secs_f32(),
video.position().as_secs_f32(),
let video_track = slider(
0.0..=video.duration().as_secs_f64(),
video.position().as_secs_f64(),
|pos| Message::VideoPos(pos),
)
.girth(cosmic::theme::spacing().space_s)
.length(Length::Fill);
.step(0.1)
.width(Length::Fill)
.height(cosmic::theme::spacing().space_s);
container(
row![play_button, video_track]
.align_y(Vertical::Center)