livesplit_auto_splitting/lib.rs
1//! livesplit-auto-splitting is a library that provides a runtime for running
2//! auto splitters that can control a speedrun timer. These auto splitters are
3//! provided as WebAssembly modules.
4//!
5//! # Requirements for the Auto Splitters
6//!
7//! The auto splitters must provide an `update` function with the following
8//! signature:
9//!
10//! ```rust
11//! #[no_mangle]
12//! pub extern "C" fn update() {}
13//! ```
14//!
15//! This function is called periodically by the runtime at the configured tick
16//! rate. The tick rate is 120 Hz by default, but can be changed by the auto
17//! splitter.
18//!
19//! In addition the WebAssembly module is expected to export a memory called
20//! `memory`.
21//!
22//! # API exposed to the Auto Splitters
23//!
24//! The following functions are provided to the auto splitters in the module
25//! `env`:
26//!
27//! ```rust
28//! # use core::num::NonZeroU64;
29//!
30//! #[repr(transparent)]
31//! pub struct Address(pub u64);
32//!
33//! #[repr(transparent)]
34//! pub struct NonZeroAddress(pub NonZeroU64);
35//!
36//! #[repr(transparent)]
37//! pub struct ProcessId(NonZeroU64);
38//!
39//! #[repr(transparent)]
40//! pub struct TimerState(u32);
41//!
42//! impl TimerState {
43//! /// The timer is not running.
44//! pub const NOT_RUNNING: Self = Self(0);
45//! /// The timer is running.
46//! pub const RUNNING: Self = Self(1);
47//! /// The timer started but got paused. This is separate from the game
48//! /// time being paused. Game time may even always be paused.
49//! pub const PAUSED: Self = Self(2);
50//! /// The timer has ended, but didn't get reset yet.
51//! pub const ENDED: Self = Self(3);
52//! }
53//!
54//! extern "C" {
55//! /// Gets the state that the timer currently is in.
56//! pub fn timer_get_state() -> TimerState;
57//!
58//! /// Starts the timer.
59//! pub fn timer_start();
60//! /// Splits the current segment.
61//! pub fn timer_split();
62//! /// Resets the timer.
63//! pub fn timer_reset();
64//! /// Sets a custom key value pair. This may be arbitrary information that
65//! /// the auto splitter wants to provide for visualization.
66//! pub fn timer_set_variable(
67//! key_ptr: *const u8,
68//! key_len: usize,
69//! value_ptr: *const u8,
70//! value_len: usize,
71//! );
72//!
73//! /// Sets the game time.
74//! pub fn timer_set_game_time(secs: i64, nanos: i32);
75//! /// Pauses the game time. This does not pause the timer, only the
76//! /// automatic flow of time for the game time.
77//! pub fn timer_pause_game_time();
78//! /// Resumes the game time. This does not resume the timer, only the
79//! /// automatic flow of time for the game time.
80//! pub fn timer_resume_game_time();
81//!
82//! /// Attaches to a process based on its name.
83//! pub fn process_attach(name_ptr: *const u8, name_len: usize) -> Option<ProcessId>;
84//! /// Detaches from a process.
85//! pub fn process_detach(process: ProcessId);
86//! /// Checks whether is a process is still open. You should detach from a
87//! /// process and stop using it if this returns `false`.
88//! pub fn process_is_open(process: ProcessId) -> bool;
89//! /// Reads memory from a process at the address given. This will write
90//! /// the memory to the buffer given. Returns `false` if this fails.
91//! pub fn process_read(
92//! process: ProcessId,
93//! address: Address,
94//! buf_ptr: *mut u8,
95//! buf_len: usize,
96//! ) -> bool;
97//! /// Gets the address of a module in a process.
98//! pub fn process_get_module_address(
99//! process: ProcessId,
100//! name_ptr: *const u8,
101//! name_len: usize,
102//! ) -> Option<NonZeroAddress>;
103//! /// Gets the size of a module in a process.
104//! pub fn process_get_module_size(
105//! process: ProcessId,
106//! name_ptr: *const u8,
107//! name_len: usize,
108//! ) -> Option<NonZeroU64>;
109//!
110//! /// Sets the tick rate of the runtime. This influences the amount of
111//! /// times the `update` function is called per second.
112//! pub fn runtime_set_tick_rate(ticks_per_second: f64);
113//! /// Prints a log message for debugging purposes.
114//! pub fn runtime_print_message(text_ptr: *const u8, text_len: usize);
115//!
116//! /// Adds a new setting that the user can modify. This will return either
117//! /// the specified default value or the value that the user has set.
118//! pub fn user_settings_add_bool(
119//! key_ptr: *const u8,
120//! key_len: usize,
121//! description_ptr: *const u8,
122//! description_len: usize,
123//! default_value: bool,
124//! ) -> bool;
125//! }
126//! ```
127//!
128//! On top of the runtime's API, there's also unstable `WASI` support via the
129//! `unstable` feature.
130
131#![warn(
132 clippy::complexity,
133 clippy::correctness,
134 clippy::perf,
135 clippy::style,
136 clippy::missing_const_for_fn,
137 missing_docs,
138 rust_2018_idioms
139)]
140
141mod process;
142mod runtime;
143mod settings;
144mod timer;
145
146pub use runtime::{CreationError, InterruptHandle, Runtime};
147pub use settings::{SettingValue, SettingsStore, UserSetting};
148pub use time;
149pub use timer::{Timer, TimerState};