Skip to content

Commit

Permalink
Playtime: Decompress app *and* load app library async on start
Browse files Browse the repository at this point in the history
  • Loading branch information
helgoboss committed Nov 22, 2023
1 parent da19ec2 commit 2dd899a
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 38 deletions.
55 changes: 24 additions & 31 deletions main/src/infrastructure/plugin/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,6 @@ pub struct App {
message_panel: SharedView<MessagePanel>,
osc_feedback_processor: Rc<RefCell<OscFeedbackProcessor>>,
#[cfg(feature = "playtime")]
app_decompression_result: RefCell<Option<Result<(), String>>>,
#[cfg(feature = "playtime")]
app_library: std::cell::OnceCell<anyhow::Result<crate::infrastructure::ui::AppLibrary>>,
#[cfg(feature = "playtime")]
clip_engine_hub: playtime_clip_engine::proto::ClipEngineHub,
Expand Down Expand Up @@ -288,14 +286,14 @@ impl App {
);
// This doesn't yet activate the accelerator (will happen on wake up)
let accelerator = RealearnAccelerator::new(shared_main_processors, RealearnSnitch);
// Silently decompress app so it's immediately available when needed (async)
// Silently decompress app and load library in background so it's ready when needed
#[cfg(feature = "playtime")]
let _ = std::thread::Builder::new()
.name("Decompress Helgobox app".to_string())
.name("Helgobox app loader".to_string())
.spawn(|| {
let result = decompress_app().map_err(|e| e.to_string());
let result = decompress_app().and_then(|_| load_app_library());
let _ = Global::task_support().do_later_in_main_thread_asap(|| {
*App::get().app_decompression_result.borrow_mut() = Some(result);
let _ = App::get().app_library.set(result);
});
});
// REAPER registers/unregisters actions automatically depending on presence of plug-in
Expand Down Expand Up @@ -331,8 +329,6 @@ impl App {
message_panel: Default::default(),
osc_feedback_processor: Rc::new(RefCell::new(osc_feedback_processor)),
#[cfg(feature = "playtime")]
app_decompression_result: Default::default(),
#[cfg(feature = "playtime")]
app_library: std::cell::OnceCell::new(),
#[cfg(feature = "playtime")]
clip_engine_hub: playtime_clip_engine::proto::ClipEngineHub::new(),
Expand Down Expand Up @@ -951,27 +947,14 @@ impl App {
}

#[cfg(feature = "playtime")]
pub fn get_or_load_app_library(
&self,
) -> anyhow::Result<&'static crate::infrastructure::ui::AppLibrary> {
let result = match App::get().app_library.get() {
None => {
// Check if decompression was successful
let decompression_result = self.app_decompression_result.borrow();
match decompression_result.as_ref() {
None => bail!("App is not decompressed yet"),
Some(Err(e)) => bail!("App decompression failed: {e}"),
_ => {}
}
// Load library
App::get()
.app_library
.get_or_init(load_app_library)
.as_ref()
}
Some(l) => l.as_ref(),
};
result.map_err(|e| anyhow::anyhow!(format!("{e:?}")))
pub fn get_app_library() -> anyhow::Result<&'static crate::infrastructure::ui::AppLibrary> {
use anyhow::Context;
let app_library = App::get()
.app_library
.get()
.context("App not loaded yet. Please try again later.")?
.as_ref();
app_library.map_err(|e| anyhow::anyhow!(format!("{e:?}")))
}

pub fn has_session(&self, session_id: &str) -> bool {
Expand Down Expand Up @@ -2041,8 +2024,18 @@ impl RealearnWindowSnitch for RealearnSnitch {

#[cfg(feature = "playtime")]
fn load_app_library() -> anyhow::Result<crate::infrastructure::ui::AppLibrary> {
tracing::info!("Loading app library...");
let app_base_dir = App::app_base_dir_path();
crate::infrastructure::ui::AppLibrary::load(app_base_dir)
let lib = crate::infrastructure::ui::AppLibrary::load(app_base_dir);
match lib.as_ref() {
Ok(_) => {
tracing::info!("App library loaded successfully");
}
Err(e) => {
tracing::warn!("App library loading failed: {e}");
}
}
lib
}

#[cfg(feature = "playtime")]
Expand All @@ -2065,6 +2058,6 @@ fn decompress_app() -> anyhow::Result<()> {
archive
.unpack(destination_dir)
.context("Couldn't unpack app archive.")?;
tracing::info!("App successfully decompressed");
tracing::info!("App decompressed successfully");
Ok(())
}
10 changes: 4 additions & 6 deletions main/src/infrastructure/ui/app/app_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ impl AppInstance for ParentedAppInstance {
return Ok(());
}
// Fail fast if library not available
App::get().get_or_load_app_library()?;
App::get_app_library()?;
// Then open. This actually only opens the SWELL window. The real stuff is done
// in the "opened" handler of the SWELL window.
self.panel.clone().open(owning_window);
Expand Down Expand Up @@ -161,7 +161,7 @@ impl AppInstance for StandaloneAppInstance {
}

fn start_or_show(&mut self, _owning_window: Window) -> Result<()> {
let app_library = App::get().get_or_load_app_library()?;
let app_library = App::get_app_library()?;
if let Some(running_state) = &self.running_state {
app_library.show_app_instance(None, running_state.common_state.app_handle)?;
return Ok(());
Expand Down Expand Up @@ -296,7 +296,7 @@ impl AppPanel {

fn open_internal(&self, window: Window) -> Result<()> {
window.set_text("Playtime");
let app_library = App::get().get_or_load_app_library()?;
let app_library = App::get_app_library()?;
let session_id = extract_session_id(&self.session)?;
let app_handle = app_library.start_app_instance(Some(window), session_id)?;
let running_state = ParentedAppRunningState {
Expand Down Expand Up @@ -328,9 +328,7 @@ impl CommonAppRunningState {
}

pub fn stop(&self, window: Option<Window>) -> Result<()> {
App::get()
.get_or_load_app_library()?
.stop_app_instance(window, self.app_handle)
App::get_app_library()?.stop_app_instance(window, self.app_handle)
}
}

Expand Down
2 changes: 1 addition & 1 deletion playtime-clip-engine

0 comments on commit 2dd899a

Please sign in to comment.