141 lines
6.2 KiB
Rust
141 lines
6.2 KiB
Rust
// file: crates/ksp-app-config-desk/src/tw_splash.rs
|
|
// version: 5
|
|
|
|
//! Tauri-window lifecycle for the Config Desk splash window.
|
|
|
|
use tauri::Emitter; // rust-rules: trait-import
|
|
use tauri::Manager; // rust-rules: trait-import
|
|
|
|
/// Crate-internal `WINDOW_LABEL_SPLASH` constant.
|
|
pub(crate) const WINDOW_LABEL_SPLASH: &str = "splash";
|
|
|
|
const SPLASH_EVENT_NAME: &str = "ksp-splash-order";
|
|
|
|
/// Resolves the required splash window or returns a typed error.
|
|
pub(crate) fn require_splash_window(manager: &impl Manager<tauri::Wry>) -> ksp_core_lib::Result<tauri::WebviewWindow> {
|
|
let window = manager.get_webview_window(WINDOW_LABEL_SPLASH);
|
|
return match window {
|
|
std::option::Option::Some(value) => std::result::Result::Ok(value),
|
|
std::option::Option::None => std::result::Result::Err(
|
|
ksp_core_lib::Error::new(crate::ERROR_CODE_TAURI_WINDOW_MISSING, "Config Desk splash window is missing")
|
|
.with_context("window_label", WINDOW_LABEL_SPLASH),
|
|
),
|
|
};
|
|
}
|
|
|
|
/// Executes the crate-internal splash frontend ready service operation for the owning module.
|
|
pub(crate) async fn splash_frontend_ready_service(
|
|
app: tauri::AppHandle,
|
|
invoking_window: tauri::WebviewWindow,
|
|
state: &crate::AppState,
|
|
) -> ksp_core_lib::Result<()> {
|
|
if invoking_window.label() != WINDOW_LABEL_SPLASH {
|
|
return std::result::Result::Err(
|
|
ksp_core_lib::Error::new(crate::ERROR_CODE_SPLASH_ORIGIN_INVALID, "Splash readiness may only originate from the splash window")
|
|
.with_context("window_label", invoking_window.label()),
|
|
);
|
|
}
|
|
if !state.begin_splash_sequence() {
|
|
ksp_logging_lib::trace!(
|
|
target: crate::TRACING_TARGET,
|
|
domain = crate::TRACING_DOMAIN_WINDOWS,
|
|
window_label = WINDOW_LABEL_SPLASH,
|
|
"duplicate splash frontend readiness ignored"
|
|
);
|
|
return std::result::Result::Ok(());
|
|
}
|
|
let settings = state.splash_settings();
|
|
let lifecycle_started = std::time::Instant::now();
|
|
ksp_logging_lib::debug!(
|
|
target: crate::TRACING_TARGET,
|
|
domain = crate::TRACING_DOMAIN_WINDOWS,
|
|
window_label = WINDOW_LABEL_SPLASH,
|
|
minimum_ms = settings.minimum_ms(),
|
|
minimum_source = settings.minimum_source(),
|
|
fade_ms = settings.fade_ms(),
|
|
fade_source = settings.fade_source(),
|
|
expected_backend_lifecycle_ms = settings.expected_backend_lifecycle_ms(),
|
|
"splash frontend readiness accepted; starting splash to main lifecycle"
|
|
);
|
|
let fade_in = emit_order(
|
|
&invoking_window,
|
|
crate::SplashOrderDto::new("fade_in", std::option::Option::Some("Initialisation de KSP Config Desk..."), std::option::Option::Some(settings.fade_ms())),
|
|
);
|
|
if let std::result::Result::Err(error) = fade_in {
|
|
return std::result::Result::Err(error);
|
|
}
|
|
let minimum_wait_started = std::time::Instant::now();
|
|
tokio::time::sleep(std::time::Duration::from_millis(settings.minimum_ms())).await;
|
|
ksp_logging_lib::debug!(
|
|
target: crate::TRACING_TARGET,
|
|
domain = crate::TRACING_DOMAIN_WINDOWS,
|
|
window_label = WINDOW_LABEL_SPLASH,
|
|
configured_wait_ms = settings.minimum_ms(),
|
|
actual_wait_ms = minimum_wait_started.elapsed().as_secs_f64() * 1000.0,
|
|
lifecycle_elapsed_ms = lifecycle_started.elapsed().as_secs_f64() * 1000.0,
|
|
"splash minimum wait completed"
|
|
);
|
|
let fade_out = emit_order(
|
|
&invoking_window,
|
|
crate::SplashOrderDto::new("fade_out", std::option::Option::Some("Initialisation terminée."), std::option::Option::Some(settings.fade_ms())),
|
|
);
|
|
if let std::result::Result::Err(error) = fade_out {
|
|
return std::result::Result::Err(error);
|
|
}
|
|
let fade_wait_started = std::time::Instant::now();
|
|
tokio::time::sleep(std::time::Duration::from_millis(u64::from(settings.fade_ms()))).await;
|
|
ksp_logging_lib::debug!(
|
|
target: crate::TRACING_TARGET,
|
|
domain = crate::TRACING_DOMAIN_WINDOWS,
|
|
window_label = WINDOW_LABEL_SPLASH,
|
|
configured_wait_ms = settings.fade_ms(),
|
|
actual_wait_ms = fade_wait_started.elapsed().as_secs_f64() * 1000.0,
|
|
lifecycle_elapsed_ms = lifecycle_started.elapsed().as_secs_f64() * 1000.0,
|
|
"splash fade-out wait completed"
|
|
);
|
|
let show_main = crate::show_main_window(&app);
|
|
if let std::result::Result::Err(error) = show_main {
|
|
return std::result::Result::Err(error);
|
|
}
|
|
let destroyed = invoking_window.destroy();
|
|
if let std::result::Result::Err(error) = destroyed {
|
|
return std::result::Result::Err(
|
|
ksp_core_lib::Error::new(crate::ERROR_CODE_TAURI_WINDOW_OPERATION_FAILED, "Cannot destroy Config Desk splash window")
|
|
.with_context("window_label", WINDOW_LABEL_SPLASH)
|
|
.with_source(error),
|
|
);
|
|
}
|
|
ksp_logging_lib::debug!(
|
|
target: crate::TRACING_TARGET,
|
|
domain = crate::TRACING_DOMAIN_WINDOWS,
|
|
window_label = WINDOW_LABEL_SPLASH,
|
|
expected_backend_lifecycle_ms = settings.expected_backend_lifecycle_ms(),
|
|
actual_backend_lifecycle_ms = lifecycle_started.elapsed().as_secs_f64() * 1000.0,
|
|
"splash window destroyed after main activation"
|
|
);
|
|
return std::result::Result::Ok(());
|
|
}
|
|
|
|
fn emit_order(window: &tauri::WebviewWindow, order: crate::SplashOrderDto) -> ksp_core_lib::Result<()> {
|
|
let action = order.action.clone();
|
|
let emitted = window.emit(SPLASH_EVENT_NAME, order);
|
|
return match emitted {
|
|
std::result::Result::Ok(()) => {
|
|
ksp_logging_lib::trace!(
|
|
target: crate::TRACING_TARGET,
|
|
domain = crate::TRACING_DOMAIN_WINDOWS,
|
|
window_label = WINDOW_LABEL_SPLASH,
|
|
action = action.as_str(),
|
|
"splash order emitted"
|
|
);
|
|
std::result::Result::Ok(())
|
|
},
|
|
std::result::Result::Err(error) => std::result::Result::Err(
|
|
ksp_core_lib::Error::new(crate::ERROR_CODE_TAURI_WINDOW_OPERATION_FAILED, "Cannot emit Config Desk splash order")
|
|
.with_context("window_label", WINDOW_LABEL_SPLASH)
|
|
.with_context("action", action)
|
|
.with_source(error),
|
|
),
|
|
};
|
|
}
|