Skip to content

Commit

Permalink
unstable: timer_current_split_index
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexKnauth committed Jun 14, 2024
1 parent 4efe669 commit fd82dad
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ serde_json = { version = "1" }

xmltree = { version = "0.10.3" }

[features]
unstable = []

[lib]
crate-type = ["cdylib"]

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod legacy_xml;
mod settings_gui;
mod splits;
mod timer;
mod unstable;

use asr::future::{next_tick, retry};
use asr::Process;
Expand Down
46 changes: 45 additions & 1 deletion src/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
use asr::timer::TimerState;
use serde::{Deserialize, Serialize};

use crate::unstable::maybe_timer_current_split_index;

pub fn is_timer_state_between_runs(s: TimerState) -> bool {
s == TimerState::NotRunning || s == TimerState::Ended
}
Expand Down Expand Up @@ -66,6 +68,13 @@ pub struct Timer {
/// [1,n): Running
/// n: Ended without knowing auto-reset safe
i: usize,
/// The last observed timer_current_split_index.
/// Just in case timer_current_split_index is a tad out-of-date.
/// -2: Unknown
/// -1: NotRunning
/// [0,n-1): Running
/// n-1: Ended
last_split_index: i32,
/// Number of autosplits including both start and end.
/// One more than the number of segments.
n: usize,
Expand All @@ -84,10 +93,12 @@ impl Resettable for Timer {
impl Timer {
pub fn new(n: usize, auto_reset: &'static [TimerState]) -> Timer {
let asr_state = asr::timer::state();
let asr_index = maybe_timer_current_split_index();
Timer {
state: asr_state,
last_state: asr_state,
i: 0,
last_split_index: asr_index.unwrap_or(-2),
n,
auto_reset,
}
Expand All @@ -111,6 +122,12 @@ impl Timer {
}

pub fn update<R: Resettable>(&mut self, r: &mut R) {
self.update_state(r);
#[cfg(feature = "unstable")]
self.update_index();
}

fn update_state<R: Resettable>(&mut self, r: &mut R) {
let asr_state = asr::timer::state();
if asr_state == self.state || asr_state == self.last_state {
self.last_state = asr_state;
Expand Down Expand Up @@ -146,6 +163,33 @@ impl Timer {
self.last_state = asr_state;
}

#[cfg(feature = "unstable")]
fn update_index(&mut self) -> Option<()> {
let asr_index = maybe_timer_current_split_index()?;
if asr_index == self.last_split_index
{
return Some(());
}
let delta = asr_index + 1 - self.i as i32;
if delta == 0 || delta >= self.n as i32 {
return Some(());
}
match delta {
-1 => asr::print_message("Detected a manual undo."),
1 => asr::print_message("Detected a manual split or skip."),
d if d.is_negative() => asr::print_message(&format!("Detected a {} manual undos.", -d)),
d if d.is_positive() => asr::print_message(&format!("Detected a {} manual splits or skips.", d)),
_ => (),
}
let new_i = (self.i as i32 + delta) as usize;
if new_i >= self.n && self.is_auto_reset_safe() {
self.i = 0;
} else {
self.i = new_i;
}
Some(())
}

pub fn action<R: Resettable>(&mut self, a: SplitterAction, r: &mut R) {
match a {
SplitterAction::Pass => (),
Expand All @@ -169,7 +213,7 @@ impl Timer {
self.i += 1;
}
SplitterAction::ManualSplit => {
if 0 < self.i && self.i + 1 < self.n {
if self.last_split_index == -2 && 0 < self.i && self.i + 1 < self.n {
self.i += 1;
}
}
Expand Down
22 changes: 22 additions & 0 deletions src/unstable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

#[cfg(feature = "unstable")]
extern "C" {
/// 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.
fn timer_current_split_index() -> i32;
}

/// 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.
pub fn maybe_timer_current_split_index() -> Option<i32> {
#[cfg(feature = "unstable")]
return Some(unsafe { timer_current_split_index() });
#[allow(unreachable_code)]
None
}

0 comments on commit fd82dad

Please sign in to comment.