diff --git a/Cargo.lock b/Cargo.lock index 73fbcb7..af65d32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1465,7 +1465,7 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "livesplit-auto-splitting" version = "0.1.0" -source = "git+https://github.com/LiveSplit/livesplit-core#7649ba092a0e0723c4dbafe600778ddac78ede4d" +source = "git+https://github.com/AlexKnauth/livesplit-core?branch=Refragg-2#652d2b481a627e5c0d971b6646fc78aacdb650e6" dependencies = [ "anyhow", "arc-swap", @@ -1489,7 +1489,7 @@ dependencies = [ [[package]] name = "livesplit-core" version = "0.13.0" -source = "git+https://github.com/LiveSplit/livesplit-core#7649ba092a0e0723c4dbafe600778ddac78ede4d" +source = "git+https://github.com/AlexKnauth/livesplit-core?branch=Refragg-2#652d2b481a627e5c0d971b6646fc78aacdb650e6" dependencies = [ "arc-swap", "base64-simd", @@ -1525,7 +1525,7 @@ dependencies = [ [[package]] name = "livesplit-hotkey" version = "0.8.0" -source = "git+https://github.com/LiveSplit/livesplit-core#7649ba092a0e0723c4dbafe600778ddac78ede4d" +source = "git+https://github.com/AlexKnauth/livesplit-core?branch=Refragg-2#652d2b481a627e5c0d971b6646fc78aacdb650e6" dependencies = [ "bitflags 2.9.3", "cfg-if", @@ -1542,7 +1542,7 @@ dependencies = [ [[package]] name = "livesplit-title-abbreviations" version = "0.3.0" -source = "git+https://github.com/LiveSplit/livesplit-core#7649ba092a0e0723c4dbafe600778ddac78ede4d" +source = "git+https://github.com/AlexKnauth/livesplit-core?branch=Refragg-2#652d2b481a627e5c0d971b6646fc78aacdb650e6" [[package]] name = "log" diff --git a/Cargo.toml b/Cargo.toml index 4d97112..975a5b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ members = ["obs"] crate-type = ["cdylib"] [dependencies] -livesplit-core = { git = "https://github.com/LiveSplit/livesplit-core", features = [ +livesplit-core = { git = "https://github.com/AlexKnauth/livesplit-core", branch = "Refragg-2", features = [ "software-rendering", "font-loading", ] } diff --git a/src/lib.rs b/src/lib.rs index d74da5c..d4949bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -493,7 +493,11 @@ impl State { unsafe { debug!("Loading settings."); - let global_timer = get_global_timer(splits_path); + let global_timer = get_global_timer( + splits_path, + #[cfg(feature = "auto-splitting")] + &local_auto_splitter, + ); global_timer .timer .auto_save @@ -506,11 +510,6 @@ impl State { let texture = gs_texture_create(width, height, GS_RGBA, 1, ptr::null_mut(), GS_DYNAMIC); obs_leave_graphics(); - #[cfg(feature = "auto-splitting")] - if let Some(local_auto_splitter) = &local_auto_splitter { - auto_splitter_load(&global_timer, local_auto_splitter.clone()) - } - Self { #[cfg(feature = "auto-splitting")] local_auto_splitter, @@ -627,6 +626,9 @@ unsafe extern "C" fn reset( return; } + // Update AutoSplitter Settings Map before reset-autosaving + #[cfg(feature = "auto-splitting")] + update_auto_splitter_settings_map(&state.global_timer); drop(state.global_timer.timer.reset(None)); } } @@ -921,6 +923,9 @@ unsafe extern "C" fn save_splits( ) -> bool { unsafe { let state: &mut State = &mut (*data.cast::>()).lock().unwrap(); + // Update AutoSplitter Settings Map before saving + #[cfg(feature = "auto-splitting")] + update_auto_splitter_settings_map(&state.global_timer); state.global_timer.timer.save(); false } @@ -1181,6 +1186,17 @@ fn auto_splitter_load(global_timer: &GlobalTimer, path: PathBuf) { .store(enabled, atomic::Ordering::Relaxed); } +/// Update AutoSplitter Settings Map, from the +/// auto_splitting::Runtime to the Inner Timer Run, +/// to prepare for it to be saved to a splits file +#[cfg(feature = "auto-splitting")] +fn update_auto_splitter_settings_map(global_timer: &GlobalTimer) -> Option<()> { + let m = global_timer.auto_splitter.settings_map()?; + let mut t = global_timer.timer.timer.write().ok()?; + t.run_auto_splitter_settings_map_store(m); + Some(()) +} + #[cfg(feature = "auto-splitting")] unsafe extern "C" fn auto_splitter_activate_clicked( _props: *mut obs_properties_t, @@ -1313,6 +1329,9 @@ unsafe extern "C" fn media_play_pause(data: *mut c_void, pause: bool) { unsafe extern "C" fn media_restart(data: *mut c_void) { unsafe { let state: &mut State = &mut (*data.cast::>()).lock().unwrap(); + // Update AutoSplitter Settings Map before reset-autosaving + #[cfg(feature = "auto-splitting")] + update_auto_splitter_settings_map(&state.global_timer); drop(state.global_timer.timer.reset(None)); drop(state.global_timer.timer.start()); } @@ -1321,6 +1340,9 @@ unsafe extern "C" fn media_restart(data: *mut c_void) { unsafe extern "C" fn media_stop(data: *mut c_void) { unsafe { let state: &mut State = &mut (*data.cast::>()).lock().unwrap(); + // Update AutoSplitter Settings Map before reset-autosaving + #[cfg(feature = "auto-splitting")] + update_auto_splitter_settings_map(&state.global_timer); drop(state.global_timer.timer.reset(None)); } } @@ -1838,23 +1860,62 @@ unsafe extern "C" fn update(data: *mut c_void, settings_obj: *mut obs_data_t) { match &widget.kind { WidgetKind::Title { .. } => {} WidgetKind::Bool { default_value } => { - let value = obs_data_get_bool(settings_obj, data_key.as_ptr()); - if value != *default_value { - map.insert(key.clone(), Value::Bool(value)); + let old_value = state + .auto_splitter_map + .get(&key) + .and_then(|v| v.to_bool()) + .unwrap_or(*default_value); + let asr_value = map + .get(&key) + .and_then(|v| v.to_bool()) + .unwrap_or(*default_value); + if asr_value != old_value { + obs_data_set_bool(settings_obj, data_key.as_ptr(), asr_value); + state + .auto_splitter_map + .insert(key.clone(), Value::Bool(asr_value)); } else { map.remove(key); + let obs_value = obs_data_get_bool(settings_obj, data_key.as_ptr()); + if obs_value != *default_value { + map.insert(key.clone(), Value::Bool(obs_value)); + } else { + map.remove(key); + } } } WidgetKind::Choice { default_option_key, .. } => { - if let Some(value) = + let old_value = state + .auto_splitter_map + .get(&key) + .and_then(|v| v.as_string()) + .unwrap_or(default_option_key); + let asr_value = map + .get(&key) + .and_then(|v| v.as_string()) + .unwrap_or(default_option_key); + if asr_value != old_value { + if let Ok(new_value) = + CString::from_vec_with_nul(format!("{}\0", asr_value).into()) + { + obs_data_set_string( + settings_obj, + data_key.as_ptr(), + new_value.as_ptr(), + ); + } + state + .auto_splitter_map + .insert(key.clone(), Value::String(asr_value.clone())); + } else if let Some(obs_value) = CStr::from_ptr(obs_data_get_string(settings_obj, data_key.as_ptr())) .to_str() .ok() .filter(|v| *v != &**default_option_key) { - map.insert(key.clone(), Value::String(Arc::from(value))); + map.insert(key.clone(), Value::String(Arc::from(obs_value))); } else { map.remove(key); } @@ -1881,6 +1942,13 @@ unsafe extern "C" fn update(data: *mut c_void, settings_obj: *mut obs_data_t) { .set_settings_map_if_unchanged(&original, map.clone()) != Some(false) { + state + .global_timer + .timer + .timer + .write() + .unwrap() + .run_auto_splitter_settings_map_store(map.clone()); state.auto_splitter_map = map; break; } @@ -1908,10 +1976,17 @@ unsafe extern "C" fn update(data: *mut c_void, settings_obj: *mut obs_data_t) { } fn handle_splits_path_change(state: &mut State, splits_path: PathBuf) { - state.global_timer = get_global_timer(splits_path); + state.global_timer = get_global_timer( + splits_path, + #[cfg(feature = "auto-splitting")] + &state.local_auto_splitter, + ); } -fn get_global_timer(splits_path: PathBuf) -> Arc { +fn get_global_timer( + splits_path: PathBuf, + #[cfg(feature = "auto-splitting")] local_auto_splitter: &Option, +) -> Arc { let mut timers = TIMERS.lock().unwrap(); timers.retain(|timer| timer.strong_count() > 0); if let Some(timer) = timers.iter().find_map(|timer| { @@ -1942,6 +2017,10 @@ fn get_global_timer(splits_path: PathBuf) -> Arc { #[cfg(feature = "auto-splitting")] auto_splitter_is_enabled: AtomicBool::new(false), }); + #[cfg(feature = "auto-splitting")] + if let Some(local_auto_splitter) = local_auto_splitter { + auto_splitter_load(&global_timer, local_auto_splitter.clone()); + } timers.push(Arc::downgrade(&global_timer)); global_timer }