diff --git a/src/runtime/sys.rs b/src/runtime/sys.rs index 4fef9ff5..ab1d6838 100644 --- a/src/runtime/sys.rs +++ b/src/runtime/sys.rs @@ -79,6 +79,18 @@ extern "C" { pub fn timer_undo_split(); /// Resets the timer. pub fn timer_reset(); + /// Accesses the index of the split the attempt is currently on. + /// If there's no attempt in progress, `-1` is returned instead. + /// This returns an index that is equal to the amount of segments + /// when the attempt is finished, but has not been reset. + /// So you need to be careful when using this value for indexing. + /// Same index does not imply same split on undo and then split. + pub fn timer_current_split_index() -> i64; + /// Whether the segment at `idx` was splitted this attempt. + /// Returns `1` if the segment was splitted, or `0` if skipped. + /// If `idx` is greater than or equal to the current split index, + /// `-1` is returned instead. + pub fn timer_segment_splitted(idx: u64) -> i32; /// Sets a custom key value pair. This may be arbitrary information that the /// auto splitter wants to provide for visualization. The pointers need to /// point to valid UTF-8 encoded text with the respective given length. diff --git a/src/runtime/timer.rs b/src/runtime/timer.rs index b1eb218d..2b286081 100644 --- a/src/runtime/timer.rs +++ b/src/runtime/timer.rs @@ -112,6 +112,38 @@ pub fn state() -> TimerState { } } +/// Accesses the index of the split the attempt is currently on. +/// If there's no attempt in progress, `None` is returned instead. +/// This returns an index that is equal to the amount of segments +/// when the attempt is finished, but has not been reset. +/// So you need to be careful when using this value for indexing. +/// Same index does not imply same split on undo and then split. +pub fn current_split_index() -> Option { + // SAFETY: It is always safe to call this function. + let i = unsafe { sys::timer_current_split_index() }; + if i.is_negative() { + return None; + } + Some(i as u64) +} + +/// Whether the segment at `idx` was splitted this attempt. +/// Returns `Some(true)` if the segment was splitted, +/// or `Some(false)` if skipped. +/// If `idx` is greater than or equal to the current split index, +/// `None` is returned instead. +pub fn segment_splitted(idx: u64) -> Option { + // SAFETY: It is always safe to call this function. + // Even when `idx` is out of bounds, + // timer_segment_splitted returns `-1`, + // and then segment_splitted returns `None`. + match unsafe { sys::timer_segment_splitted(idx) } { + 1 => Some(true), + 0 => Some(false), + _ => None, + } +} + /// Sets the game time. #[inline] pub fn set_game_time(time: time::Duration) {