asr/runtime/sys.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
use core::num::NonZeroU64;
use crate::Address;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(transparent)]
pub struct NonZeroAddress(pub NonZeroU64);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(transparent)]
pub struct Process(NonZeroU64);
/// A process id is a unique identifier for a process. It is not guaranteed to
/// be the same across multiple runs of the same process. It is only guaranteed
/// to be unique for the duration of the process. This matches the operating
/// system's definition of a process id.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(transparent)]
pub struct ProcessId(pub u64);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(transparent)]
pub struct TimerState(u32);
impl TimerState {
/// The timer is not running.
pub const NOT_RUNNING: Self = Self(0);
/// The timer is running.
pub const RUNNING: Self = Self(1);
/// The timer started but got paused. This is separate from the game
/// time being paused. Game time may even always be paused.
pub const PAUSED: Self = Self(2);
/// The timer has ended, but didn't get reset yet.
pub const ENDED: Self = Self(3);
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(transparent)]
pub struct SettingsMap(NonZeroU64);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(transparent)]
pub struct SettingsList(NonZeroU64);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(transparent)]
pub struct SettingValue(NonZeroU64);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(transparent)]
pub struct SettingValueType(u32);
impl SettingValueType {
/// The setting value is a settings map.
pub const MAP: Self = Self(1);
/// The setting value is a settings list.
pub const LIST: Self = Self(2);
/// The setting value is a boolean.
pub const BOOL: Self = Self(3);
/// The setting value is a 64-bit signed integer.
pub const I64: Self = Self(4);
/// The setting value is a 64-bit floating point number.
pub const F64: Self = Self(5);
/// The setting value is a string.
pub const STRING: Self = Self(6);
}
extern "C" {
/// Gets the state that the timer currently is in.
pub fn timer_get_state() -> TimerState;
/// Starts the timer.
pub fn timer_start();
/// Splits the current segment.
pub fn timer_split();
/// Skips the current split.
pub fn timer_skip_split();
/// Undoes the previous split.
pub fn timer_undo_split();
/// Resets the timer.
pub fn timer_reset();
/// 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.
pub fn timer_set_variable(
key_ptr: *const u8,
key_len: usize,
value_ptr: *const u8,
value_len: usize,
);
/// Sets the game time.
pub fn timer_set_game_time(secs: i64, nanos: i32);
/// Pauses the game time. This does not pause the timer, only the
/// automatic flow of time for the game time.
pub fn timer_pause_game_time();
/// Resumes the game time. This does not resume the timer, only the
/// automatic flow of time for the game time.
pub fn timer_resume_game_time();
/// Attaches to a process based on its name. The pointer needs to point to
/// valid UTF-8 encoded text with the given length.
pub fn process_attach(name_ptr: *const u8, name_len: usize) -> Option<Process>;
/// Attaches to a process based on its process id.
pub fn process_attach_by_pid(pid: ProcessId) -> Option<Process>;
/// Detaches from a process.
pub fn process_detach(process: Process);
/// Lists processes based on their name. The name pointer needs to point to
/// valid UTF-8 encoded text with the given length. Returns `false` if
/// listing the processes failed. If it was successful, the buffer is now
/// filled with the process ids. They are in no specific order. The
/// `list_len_ptr` will be updated to the amount of process ids that were
/// found. If this is larger than the original value provided, the buffer
/// provided was too small and not all process ids could be stored. This is
/// still considered successful and can optionally be treated as an error
/// condition by the caller by checking if the length increased and
/// potentially reallocating a larger buffer. If the length decreased after
/// the call, the buffer was larger than needed and the remaining entries
/// are untouched.
pub fn process_list_by_name(
name_ptr: *const u8,
name_len: usize,
list_ptr: *mut ProcessId,
list_len_ptr: *mut usize,
) -> bool;
/// Checks whether is a process is still open. You should detach from a
/// process and stop using it if this returns `false`.
pub fn process_is_open(process: Process) -> bool;
/// Reads memory from a process at the address given. This will write
/// the memory to the buffer given. Returns `false` if this fails.
pub fn process_read(
process: Process,
address: Address,
buf_ptr: *mut u8,
buf_len: usize,
) -> bool;
/// Gets the address of a module in a process. The pointer needs to point to
/// valid UTF-8 encoded text with the given length.
pub fn process_get_module_address(
process: Process,
name_ptr: *const u8,
name_len: usize,
) -> Option<NonZeroAddress>;
/// Gets the size of a module in a process. The pointer needs to point to
/// valid UTF-8 encoded text with the given length.
pub fn process_get_module_size(
process: Process,
name_ptr: *const u8,
name_len: usize,
) -> Option<NonZeroU64>;
/// Stores the file system path of a module in a process in the buffer
/// given. The pointer to the module name needs to point to valid UTF-8
/// encoded text with the given length. The path is a path that is
/// accessible through the WASI file system, so a Windows path of
/// `C:\foo\bar.exe` would be returned as `/mnt/c/foo/bar.exe`. Returns
/// `false` if the buffer is too small. After this call, no matter whether
/// it was successful or not, the `buf_len_ptr` will be set to the required
/// buffer size. If `false` is returned and the `buf_len_ptr` got set to 0,
/// the path or the module does not exist or it failed to get read. The path
/// is guaranteed to be valid UTF-8 and is not nul-terminated.
#[cfg(feature = "alloc")]
pub fn process_get_module_path(
process: Process,
name_ptr: *const u8,
name_len: usize,
buf_ptr: *mut u8,
buf_len_ptr: *mut usize,
) -> bool;
/// Stores the file system path of the executable in the buffer given. The
/// path is a path that is accessible through the WASI file system, so a
/// Windows path of `C:\foo\bar.exe` would be returned as
/// `/mnt/c/foo/bar.exe`. Returns `false` if the buffer is too small. After
/// this call, no matter whether it was successful or not, the `buf_len_ptr`
/// will be set to the required buffer size. If `false` is returned and the
/// `buf_len_ptr` got set to 0, the path does not exist or failed to get
/// read. The path is guaranteed to be valid UTF-8 and is not
/// nul-terminated.
#[cfg(feature = "alloc")]
pub fn process_get_path(process: Process, buf_ptr: *mut u8, buf_len_ptr: *mut usize) -> bool;
/// Gets the number of memory ranges in a given process.
pub fn process_get_memory_range_count(process: Process) -> Option<NonZeroU64>;
/// Gets the start address of a memory range by its index.
pub fn process_get_memory_range_address(process: Process, idx: u64) -> Option<NonZeroAddress>;
/// Gets the size of a memory range by its index.
pub fn process_get_memory_range_size(process: Process, idx: u64) -> Option<NonZeroU64>;
/// Gets the flags of a memory range by its index.
#[cfg(feature = "flags")]
pub fn process_get_memory_range_flags(process: Process, idx: u64) -> Option<NonZeroU64>;
/// Sets the tick rate of the runtime. This influences the amount of
/// times the `update` function is called per second.
pub fn runtime_set_tick_rate(ticks_per_second: f64);
/// Prints a log message for debugging purposes. The pointer needs to point
/// to valid UTF-8 encoded text with the given length.
pub fn runtime_print_message(text_ptr: *const u8, text_len: usize);
/// Stores the name of the operating system that the runtime is running
/// on in the buffer given. Returns `false` if the buffer is too small.
/// After this call, no matter whether it was successful or not, the
/// `buf_len_ptr` will be set to the required buffer size. The name is
/// guaranteed to be valid UTF-8 and is not nul-terminated.
/// Example values: `windows`, `linux`, `macos`
pub fn runtime_get_os(buf_ptr: *mut u8, buf_len_ptr: *mut usize) -> bool;
/// Stores the name of the architecture that the runtime is running on
/// in the buffer given. Returns `false` if the buffer is too small.
/// After this call, no matter whether it was successful or not, the
/// `buf_len_ptr` will be set to the required buffer size. The name is
/// guaranteed to be valid UTF-8 and is not nul-terminated.
/// Example values: `x86`, `x86_64`, `arm`, `aarch64`
pub fn runtime_get_arch(buf_ptr: *mut u8, buf_len_ptr: *mut usize) -> bool;
/// Adds a new boolean setting that the user can modify. This will return
/// either the specified default value or the value that the user has set.
/// The key is used to store the setting and needs to be unique across all
/// types of settings. The pointers need to point to valid UTF-8 encoded
/// text with the respective given length.
pub fn user_settings_add_bool(
key_ptr: *const u8,
key_len: usize,
description_ptr: *const u8,
description_len: usize,
default_value: bool,
) -> bool;
/// Adds a new title to the user settings. This is used to group settings
/// together. The heading level determines the size of the title. The top
/// level titles use a heading level of 0. The key needs to be unique across
/// all types of settings. The pointers need to point to valid UTF-8 encoded
/// text with the respective given length.
pub fn user_settings_add_title(
key_ptr: *const u8,
key_len: usize,
description_ptr: *const u8,
description_len: usize,
heading_level: u32,
);
/// Adds a new choice setting that the user can modify. This allows the user
/// to choose between various options. The key is used to store the setting
/// in the settings map and needs to be unique across all types of settings.
/// The description is what's shown to the user. The key of the default
/// option to show needs to be specified. The pointers need to point to
/// valid UTF-8 encoded text with the respective given length.
pub fn user_settings_add_choice(
key_ptr: *const u8,
key_len: usize,
description_ptr: *const u8,
description_len: usize,
default_option_key_ptr: *const u8,
default_option_key_len: usize,
);
/// Adds a new option to a choice setting. The key needs to match the key of
/// the choice setting that it's supposed to be added to. The option key is
/// used as the value to store when the user chooses this option. The
/// description is what's shown to the user. The pointers need to point to
/// valid UTF-8 encoded text with the respective given length. Returns
/// `true` if the option is at this point in time chosen by the user.
pub fn user_settings_add_choice_option(
key_ptr: *const u8,
key_len: usize,
option_key_ptr: *const u8,
option_key_len: usize,
option_description_ptr: *const u8,
option_description_len: usize,
) -> bool;
/// Adds a new file select setting that the user can modify. This allows the
/// user to choose a file from the file system. The key is used to store the
/// path of the file in the settings map and needs to be unique across all
/// types of settings. The description is what's shown to the user. The
/// pointers need to point to valid UTF-8 encoded text with the respective
/// given length. The path is a path that is accessible through the WASI
/// file system, so a Windows path of `C:\foo\bar.exe` would be stored as
/// `/mnt/c/foo/bar.exe`.
pub fn user_settings_add_file_select(
key_ptr: *const u8,
key_len: usize,
description_ptr: *const u8,
description_len: usize,
);
/// Adds a filter to a file select setting. The key needs to match the key
/// of the file select setting that it's supposed to be added to. The
/// description is what's shown to the user for the specific filter. The
/// description is optional. You may provide a null pointer if you don't
/// want to specify a description. The pattern is a [glob
/// pattern](https://en.wikipedia.org/wiki/Glob_(programming)) that is used
/// to filter the files. The pattern generally only supports `*` wildcards,
/// not `?` or brackets. This may however differ between frontends.
/// Additionally `;` can't be used in Windows's native file dialog if it's
/// part of the pattern. Multiple patterns may be specified by separating
/// them with ASCII space characters. There are operating systems where glob
/// patterns are not supported. A best effort lookup of the fitting MIME
/// type may be used by a frontend on those operating systems instead. The
/// pointers need to point to valid UTF-8 encoded text with the respective
/// given length.
pub fn user_settings_add_file_select_name_filter(
key_ptr: *const u8,
key_len: usize,
description_ptr: *const u8,
description_len: usize,
pattern_ptr: *const u8,
pattern_len: usize,
);
/// Adds a filter to a file select setting. The key needs to match the key
/// of the file select setting that it's supposed to be added to. The MIME
/// type is what's used to filter the files. Most operating systems do not
/// support MIME types, but the frontends are encouraged to look up the file
/// extensions that are associated with the MIME type and use those as a
/// filter in those cases. You may also use wildcards as part of the MIME
/// types such as `image/*`. The support likely also varies between
/// frontends however. The pointers need to point to valid UTF-8 encoded
/// text with the respective given length.
pub fn user_settings_add_file_select_mime_filter(
key_ptr: *const u8,
key_len: usize,
mime_type_ptr: *const u8,
mime_type_len: usize,
);
/// Adds a tooltip to a setting based on its key. A tooltip is useful for
/// explaining the purpose of a setting to the user. The pointers need to
/// point to valid UTF-8 encoded text with the respective given length.
pub fn user_settings_set_tooltip(
key_ptr: *const u8,
key_len: usize,
tooltip_ptr: *const u8,
tooltip_len: usize,
);
/// Creates a new settings map. You own the settings map and are responsible
/// for freeing it.
pub fn settings_map_new() -> SettingsMap;
/// Frees a settings map.
pub fn settings_map_free(map: SettingsMap);
/// Loads a copy of the currently set global settings map. Any changes to it
/// are only perceived if it's stored back. You own the settings map and are
/// responsible for freeing it.
pub fn settings_map_load() -> SettingsMap;
/// Stores a copy of the settings map as the new global settings map. This
/// will overwrite the previous global settings map. You still retain
/// ownership of the map, which means you still need to free it. There's a
/// chance that the settings map was changed in the meantime, so those
/// changes could get lost. Prefer using `settings_map_store_if_unchanged`
/// if you want to avoid that.
pub fn settings_map_store(map: SettingsMap);
/// Stores a copy of the new settings map as the new global settings map if
/// the map has not changed in the meantime. This is done by comparing the
/// old map. You still retain ownership of both maps, which means you still
/// need to free them. Returns `true` if the map was stored successfully.
/// Returns `false` if the map was changed in the meantime.
pub fn settings_map_store_if_unchanged(old_map: SettingsMap, new_map: SettingsMap) -> bool;
/// Copies a settings map. No changes inside the copy affect the original
/// settings map. You own the new settings map and are responsible for
/// freeing it.
pub fn settings_map_copy(map: SettingsMap) -> SettingsMap;
/// Inserts a copy of the setting value into the settings map based on the
/// key. If the key already exists, it will be overwritten. You still retain
/// ownership of the setting value, which means you still need to free it.
/// The pointer needs to point to valid UTF-8 encoded text with the given
/// length.
pub fn settings_map_insert(
map: SettingsMap,
key_ptr: *const u8,
key_len: usize,
value: SettingValue,
);
/// Gets a copy of the setting value from the settings map based on the key.
/// Returns `None` if the key does not exist. Any changes to it are only
/// perceived if it's stored back. You own the setting value and are
/// responsible for freeing it. The pointer needs to point to valid UTF-8
/// encoded text with the given length.
pub fn settings_map_get(
map: SettingsMap,
key_ptr: *const u8,
key_len: usize,
) -> Option<SettingValue>;
/// Gets the length of a settings map.
pub fn settings_map_len(map: SettingsMap) -> u64;
/// Gets the key of a setting value from the settings map based on the index
/// by storing it into the buffer provided. Returns `false` if the buffer is
/// too small. After this call, no matter whether it was successful or not,
/// the `buf_len_ptr` will be set to the required buffer size. If `false` is
/// returned and the `buf_len_ptr` got set to 0, the index is out of bounds.
/// The key is guaranteed to be valid UTF-8 and is not nul-terminated.
pub fn settings_map_get_key_by_index(
map: SettingsMap,
idx: u64,
buf_ptr: *mut u8,
buf_len_ptr: *mut usize,
) -> bool;
/// Gets a copy of the setting value from the settings map based on the
/// index. Returns `None` if the index is out of bounds. Any changes to it
/// are only perceived if it's stored back. You own the setting value and
/// are responsible for freeing it.
pub fn settings_map_get_value_by_index(map: SettingsMap, idx: u64) -> Option<SettingValue>;
/// Creates a new settings list. You own the settings list and are
/// responsible for freeing it.
pub fn settings_list_new() -> SettingsList;
/// Frees a settings list.
pub fn settings_list_free(list: SettingsList);
/// Copies a settings list. No changes inside the copy affect the original
/// settings list. You own the new settings list and are responsible for
/// freeing it.
pub fn settings_list_copy(list: SettingsList) -> SettingsList;
/// Gets the length of a settings list.
pub fn settings_list_len(list: SettingsList) -> u64;
/// Gets a copy of the setting value from the settings list based on the
/// index. Returns `None` if the index is out of bounds. Any changes to it
/// are only perceived if it's stored back. You own the setting value and
/// are responsible for freeing it.
pub fn settings_list_get(list: SettingsList, idx: u64) -> Option<SettingValue>;
/// Pushes a copy of the setting value to the end of the settings list. You
/// still retain ownership of the setting value, which means you still need
/// to free it.
pub fn settings_list_push(list: SettingsList, value: SettingValue);
/// Inserts a copy of the setting value into the settings list at the index
/// given. Returns `false` if the index is out of bounds. No matter what
/// happens, you still retain ownership of the setting value, which means
/// you still need to free it.
pub fn settings_list_insert(list: SettingsList, idx: u64, value: SettingValue) -> bool;
/// Creates a new setting value from a settings map. The value is a copy of
/// the settings map. Any changes to the original settings map afterwards
/// are not going to be perceived by the setting value. You own the setting
/// value and are responsible for freeing it. You also retain ownership of
/// the settings map, which means you still need to free it.
pub fn setting_value_new_map(value: SettingsMap) -> SettingValue;
/// Creates a new setting value from a settings list. The value is a copy of
/// the settings list. Any changes to the original settings list afterwards
/// are not going to be perceived by the setting value. You own the setting
/// value and are responsible for freeing it. You also retain ownership of
/// the settings list, which means you still need to free it.
pub fn setting_value_new_list(value: SettingsList) -> SettingValue;
/// Creates a new boolean setting value. You own the setting value and are
/// responsible for freeing it.
pub fn setting_value_new_bool(value: bool) -> SettingValue;
/// Creates a new 64-bit signed integer setting value. You own the setting
/// value and are responsible for freeing it.
pub fn setting_value_new_i64(value: i64) -> SettingValue;
/// Creates a new 64-bit floating point setting value. You own the setting
/// value and are responsible for freeing it.
pub fn setting_value_new_f64(value: f64) -> SettingValue;
/// Creates a new string setting value. The pointer needs to point to valid
/// UTF-8 encoded text with the given length. You own the setting value and
/// are responsible for freeing it.
pub fn setting_value_new_string(value_ptr: *const u8, value_len: usize) -> SettingValue;
/// Frees a setting value.
pub fn setting_value_free(value: SettingValue);
/// Copies a setting value. No changes inside the copy affect the original
/// setting value. You own the new setting value and are responsible for
/// freeing it.
pub fn setting_value_copy(value: SettingValue) -> SettingValue;
/// Gets the type of a setting value.
pub fn setting_value_get_type(value: SettingValue) -> SettingValueType;
/// Gets the value of a setting value as a settings map by storing it into
/// the pointer provided. Returns `false` if the setting value is not a
/// settings map. No value is stored into the pointer in that case. No
/// matter what happens, you still retain ownership of the setting value,
/// which means you still need to free it. You own the settings map and are
/// responsible for freeing it.
pub fn setting_value_get_map(value: SettingValue, value_ptr: *mut SettingsMap) -> bool;
/// Gets the value of a setting value as a settings list by storing it into
/// the pointer provided. Returns `false` if the setting value is not a
/// settings list. No value is stored into the pointer in that case. No
/// matter what happens, you still retain ownership of the setting value,
/// which means you still need to free it. You own the settings list and are
/// responsible for freeing it.
pub fn setting_value_get_list(value: SettingValue, value_ptr: *mut SettingsList) -> bool;
/// Gets the value of a boolean setting value by storing it into the pointer
/// provided. Returns `false` if the setting value is not a boolean. No
/// value is stored into the pointer in that case. No matter what happens,
/// you still retain ownership of the setting value, which means you still
/// need to free it.
pub fn setting_value_get_bool(value: SettingValue, value_ptr: *mut bool) -> bool;
/// Gets the value of a 64-bit signed integer setting value by storing it
/// into the pointer provided. Returns `false` if the setting value is not a
/// 64-bit signed integer. No value is stored into the pointer in that case.
/// No matter what happens, you still retain ownership of the setting value,
/// which means you still need to free it.
pub fn setting_value_get_i64(value: SettingValue, value_ptr: *mut i64) -> bool;
/// Gets the value of a 64-bit floating point setting value by storing it
/// into the pointer provided. Returns `false` if the setting value is not a
/// 64-bit floating point number. No value is stored into the pointer in
/// that case. No matter what happens, you still retain ownership of the
/// setting value, which means you still need to free it.
pub fn setting_value_get_f64(value: SettingValue, value_ptr: *mut f64) -> bool;
/// Gets the value of a string setting value by storing it into the buffer
/// provided. Returns `false` if the buffer is too small or if the setting
/// value is not a string. After this call, no matter whether it was
/// successful or not, the `buf_len_ptr` will be set to the required buffer
/// size. If `false` is returned and the `buf_len_ptr` got set to 0, the
/// setting value is not a string. The string is guaranteed to be valid
/// UTF-8 and is not nul-terminated. No matter what happens, you still
/// retain ownership of the setting value, which means you still need to
/// free it.
pub fn setting_value_get_string(
value: SettingValue,
buf_ptr: *mut u8,
buf_len_ptr: *mut usize,
) -> bool;
}