summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/allocator.rs204
-rw-r--r--src/buffer.rs235
-rw-r--r--src/entity.rs133
-rw-r--r--src/input.rs84
-rw-r--r--src/lib.rs31
-rw-r--r--src/log.rs36
-rw-r--r--src/process.rs14
-rw-r--r--src/random.rs73
-rw-r--r--src/scene.rs32
-rw-r--r--src/script.rs44
-rw-r--r--src/state.rs99
-rw-r--r--src/storage.rs84
-rw-r--r--src/time.rs142
13 files changed, 3 insertions, 1208 deletions
diff --git a/src/allocator.rs b/src/allocator.rs
deleted file mode 100644
index eaaba5f..0000000
--- a/src/allocator.rs
+++ /dev/null
@@ -1,204 +0,0 @@
-use core::{
- alloc::{GlobalAlloc, Layout},
- sync::atomic::{AtomicUsize, Ordering::Relaxed},
-};
-
-pub struct TalcAllocator(
- talc::cell::TalcSyncCell<talc::wasm::WasmGrowAndExtend, talc::wasm::WasmBinning>,
-);
-
-impl TalcAllocator {
- pub const fn new() -> Self {
- Self(talc::cell::TalcSyncCell::new_wasm(
- talc::wasm::WasmGrowAndExtend::new(),
- ))
- }
-}
-
-impl Default for TalcAllocator {
- fn default() -> Self {
- Self::new()
- }
-}
-
-unsafe impl GlobalAlloc for TalcAllocator {
- unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
- unsafe { self.0.alloc(layout) }
- }
-
- unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
- unsafe {
- self.0.dealloc(ptr, layout);
- }
- }
-
- unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
- unsafe { self.0.alloc_zeroed(layout) }
- }
-
- unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
- unsafe { self.0.realloc(ptr, layout, new_size) }
- }
-}
-
-const CHUNK_SIZE: usize = 64;
-const PAGE_SIZE: usize = 64 * 1024;
-
-unsafe extern "C" {
- safe static __heap_base: usize;
-}
-
-pub struct BumpAllocator {
- offset: AtomicUsize,
- capacity: AtomicUsize,
- free_8: AtomicUsize,
- free_16: AtomicUsize,
- free_32: AtomicUsize,
- free_64: AtomicUsize,
- free_128: AtomicUsize,
- free_256: AtomicUsize,
- free_512: AtomicUsize,
- free_1024: AtomicUsize,
- free_2048: AtomicUsize,
- free_4096: AtomicUsize,
- free_8192: AtomicUsize,
- free_16384: AtomicUsize,
- free_32768: AtomicUsize,
-}
-
-fn space_for(layout: Layout) -> usize {
- usize::div_ceil(layout.size(), CHUNK_SIZE) * CHUNK_SIZE
-}
-
-fn pop_free_list(list: &AtomicUsize) -> Option<*mut u8> {
- let offset = list.swap(0, Relaxed);
- if offset != 0 {
- // safety: offset is a valid pointer for these operations when non-zero
- unsafe {
- let ptr = offset as *mut u8;
- let next = *ptr.cast::<usize>();
- list.swap(next, Relaxed);
- Some(ptr)
- }
- } else {
- None
- }
-}
-
-unsafe fn push_free_list(list: &AtomicUsize, ptr: *mut u8) {
- // safety: all of the pointers here are valid
- unsafe {
- let new_offset = ptr.addr();
- let current_head = list.swap(new_offset, Relaxed);
- *ptr.cast::<usize>() = current_head;
- }
-}
-
-impl BumpAllocator {
- pub const fn new() -> Self {
- Self {
- offset: AtomicUsize::new(8),
- capacity: AtomicUsize::new(PAGE_SIZE - 8),
- free_8: AtomicUsize::new(0),
- free_16: AtomicUsize::new(0),
- free_32: AtomicUsize::new(0),
- free_64: AtomicUsize::new(0),
- free_128: AtomicUsize::new(0),
- free_256: AtomicUsize::new(0),
- free_512: AtomicUsize::new(0),
- free_1024: AtomicUsize::new(0),
- free_2048: AtomicUsize::new(0),
- free_4096: AtomicUsize::new(0),
- free_8192: AtomicUsize::new(0),
- free_16384: AtomicUsize::new(0),
- free_32768: AtomicUsize::new(0),
- }
- }
-}
-
-impl Default for BumpAllocator {
- fn default() -> Self {
- Self::new()
- }
-}
-
-unsafe impl GlobalAlloc for BumpAllocator {
- unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
- self.offset.fetch_max(__heap_base, Relaxed);
- let space_needed = space_for(layout);
- let ptr = match space_needed {
- 8 => pop_free_list(&self.free_8),
- 16 => pop_free_list(&self.free_16),
- 32 => pop_free_list(&self.free_32),
- 64 => pop_free_list(&self.free_64),
- 128 => pop_free_list(&self.free_128),
- 256 => pop_free_list(&self.free_256),
- 512 => pop_free_list(&self.free_512),
- 1024 => pop_free_list(&self.free_1024),
- 2048 => pop_free_list(&self.free_2048),
- 4096 => pop_free_list(&self.free_4096),
- 8192 => pop_free_list(&self.free_8192),
- 16384 => pop_free_list(&self.free_16384),
- 32768 => pop_free_list(&self.free_32768),
- _ => None,
- };
- if let Some(ptr) = ptr {
- return ptr;
- }
-
- let offset = self.offset.fetch_add(space_needed, Relaxed);
- let pointer = offset as *mut u8;
- let available_space = self.capacity.load(Relaxed) - offset;
- if available_space < layout.size() {
- let pages = layout.size().div_ceil(PAGE_SIZE);
- core::arch::wasm32::memory_grow(0, pages);
- self.capacity.fetch_add(pages * PAGE_SIZE, Relaxed);
- }
-
- pointer
- }
-
- unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
- let space_used = space_for(layout);
- let ptr_offset = ptr.addr();
- if self
- .offset
- .compare_exchange(ptr_offset + space_used, ptr_offset, Relaxed, Relaxed)
- .is_ok()
- {
- return;
- }
-
- // safety: ptr must be valid and on the heap
- unsafe {
- match space_used {
- 8 => push_free_list(&self.free_8, ptr),
- 16 => push_free_list(&self.free_16, ptr),
- 32 => push_free_list(&self.free_32, ptr),
- 64 => push_free_list(&self.free_64, ptr),
- 128 => push_free_list(&self.free_128, ptr),
- 256 => push_free_list(&self.free_256, ptr),
- 512 => push_free_list(&self.free_512, ptr),
- 1024 => push_free_list(&self.free_1024, ptr),
- 2048 => push_free_list(&self.free_2048, ptr),
- 4096 => push_free_list(&self.free_4096, ptr),
- 8192 => push_free_list(&self.free_8192, ptr),
- 16384 => push_free_list(&self.free_16384, ptr),
- 32768 => push_free_list(&self.free_32768, ptr),
- _ => {}
- };
- }
- }
-
- unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
- let space_used = space_for(layout);
- if new_size <= space_used {
- return ptr;
- }
-
- unsafe {
- self.dealloc(ptr, layout);
- self.alloc(Layout::from_size_align(new_size, layout.align()).unwrap_unchecked())
- }
- }
-}
diff --git a/src/buffer.rs b/src/buffer.rs
deleted file mode 100644
index 78b6bd5..0000000
--- a/src/buffer.rs
+++ /dev/null
@@ -1,235 +0,0 @@
-use serde::{Deserialize, Serialize};
-
-use crate::ScriptContext;
-
-mod tortuise {
- #[link(wasm_import_module = "tortuise")]
- unsafe extern "C" {
- pub safe fn add_cell(
- context: u64,
- character: u32,
- location: u32,
- z: u32,
- foreground_color: u32,
- background_color: u32,
- underline_color: u32,
- attributes: u32,
- );
- pub safe fn window_size(context: u64) -> u32;
- }
-}
-
-#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Serialize, Deserialize)]
-pub struct Cell {
- pub character: char,
- pub foreground_color: Color,
- pub background_color: Color,
- pub underline_color: Color,
- pub attributes: Attributes,
- pub x: u16,
- pub y: u16,
- pub z: u8,
-}
-
-#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Serialize, Deserialize)]
-pub struct WindowSize {
- pub rows: u16,
- pub columns: u16,
-}
-
-#[derive(
- Copy, Clone, Debug, Default, PartialEq, Eq, Ord, PartialOrd, Hash, Serialize, Deserialize,
-)]
-pub enum Color {
- /// Resets the terminal color.
- #[default]
- Reset,
-
- /// Black color.
- Black,
-
- /// Dark grey color.
- DarkGrey,
-
- /// Light red color.
- Red,
-
- /// Dark red color.
- DarkRed,
-
- /// Light green color.
- Green,
-
- /// Dark green color.
- DarkGreen,
-
- /// Light yellow color.
- Yellow,
-
- /// Dark yellow color.
- DarkYellow,
-
- /// Light blue color.
- Blue,
-
- /// Dark blue color.
- DarkBlue,
-
- /// Light magenta color.
- Magenta,
-
- /// Dark magenta color.
- DarkMagenta,
-
- /// Light cyan color.
- Cyan,
-
- /// Dark cyan color.
- DarkCyan,
-
- /// White color.
- White,
-
- /// Grey color.
- Grey,
-
- /// An RGB color. See [RGB color model](https://en.wikipedia.org/wiki/RGB_color_model) for more info.
- ///
- /// Most UNIX terminals and Windows 10 supported only.
- /// See [Platform-specific notes](enum.Color.html#platform-specific-notes) for more info.
- Rgb { r: u8, g: u8, b: u8 },
-
- /// An ANSI color. See [256 colors - cheat sheet](https://jonasjacek.github.io/colors/) for more info.
- ///
- /// Most UNIX terminals and Windows 10 supported only.
- /// See [Platform-specific notes](enum.Color.html#platform-specific-notes) for more info.
- AnsiValue(u8),
-}
-
-#[derive(
- Copy, Clone, Debug, Default, PartialEq, Eq, Ord, PartialOrd, Hash, Serialize, Deserialize,
-)]
-pub struct Attributes(u32);
-
-pub enum Attribute {
- /// Increases the text intensity.
- Bold = 1,
- /// Decreases the text intensity.
- Dim = 2,
- /// Emphasises the text.
- Italic = 4,
- /// Underlines the text.
- Underlined = 8,
-
- // Other types of underlining
- /// Double underlines the text.
- DoubleUnderlined = 16,
- /// Undercurls the text.
- Undercurled = 32,
- /// Underdots the text.
- Underdotted = 64,
- /// Underdashes the text.
- Underdashed = 128,
-
- /// Makes the text blinking (< 150 per minute).
- SlowBlink = 256,
- /// Makes the text blinking (>= 150 per minute).
- RapidBlink = 512,
- /// Swaps foreground and background colors.
- Reverse = 1024,
- /// Hides the text (also known as Conceal).
- Hidden = 2048,
- /// Crosses the text.
- CrossedOut = 4096,
- /// Sets the [Fraktur](https://en.wikipedia.org/wiki/Fraktur) typeface.
- ///
- /// Mostly used for [mathematical alphanumeric symbols](https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols).
- Fraktur = 8192,
- /// Makes the text framed.
- Framed = 16384,
- /// Makes the text encircled.
- Encircled = 32768,
- /// Draws a line at the top of the text.
- OverLined = 65536,
-}
-
-fn color_to_u32(color: Color) -> u32 {
- match color {
- Color::Reset => 1 << 24,
- Color::Black => 1 << 24 | 1,
- Color::DarkGrey => 1 << 24 | 2,
- Color::Red => 1 << 24 | 3,
- Color::DarkRed => 1 << 24 | 4,
- Color::Green => 1 << 24 | 5,
- Color::DarkGreen => 1 << 24 | 6,
- Color::Yellow => 1 << 24 | 7,
- Color::DarkYellow => 1 << 24 | 8,
- Color::Blue => 1 << 24 | 9,
- Color::DarkBlue => 1 << 24 | 10,
- Color::Magenta => 1 << 24 | 11,
- Color::DarkMagenta => 1 << 24 | 12,
- Color::Cyan => 1 << 24 | 13,
- Color::DarkCyan => 1 << 24 | 14,
- Color::White => 1 << 24 | 15,
- Color::Grey => 1 << 24 | 16,
- Color::AnsiValue(num) => 2 << 24 | num as u32,
- Color::Rgb { r, g, b } => 3 << 24 | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32),
- }
-}
-
-impl Attributes {
- pub fn none() -> Self {
- Self(0)
- }
-
- pub fn with(self, attribute: Attribute) -> Self {
- Self(self.0 | attribute as u32)
- }
-
- pub fn without(self, attribute: Attribute) -> Self {
- Self(self.0 & !(attribute as u32))
- }
-
- pub fn set(&mut self, attribute: Attribute) {
- self.0 |= attribute as u32;
- }
-
- pub fn unset(&mut self, attribute: Attribute) {
- self.0 &= !(attribute as u32)
- }
-
- pub fn has(self, attribute: Attribute) -> bool {
- self.0 & (attribute as u32) != 0
- }
-
- pub fn extend(&mut self, attributes: Attributes) {
- self.0 |= attributes.0
- }
-
- pub fn is_empty(self) -> bool {
- self.0 == 0
- }
-}
-
-impl ScriptContext {
- pub fn add_cell(&self, cell: Cell) {
- tortuise::add_cell(
- self.0,
- cell.character as u32,
- (cell.x as u32) << 16 | cell.y as u32,
- cell.z as u32,
- color_to_u32(cell.foreground_color),
- color_to_u32(cell.background_color),
- color_to_u32(cell.underline_color),
- cell.attributes.0,
- );
- }
-
- pub fn window_size(&self) -> WindowSize {
- let size = tortuise::window_size(self.0);
- WindowSize {
- rows: (size >> 16) as u16,
- columns: (size & 0xffff) as u16,
- }
- }
-}
diff --git a/src/entity.rs b/src/entity.rs
deleted file mode 100644
index 9cf6f17..0000000
--- a/src/entity.rs
+++ /dev/null
@@ -1,133 +0,0 @@
-use core::{
- alloc::Layout,
- marker::PhantomData,
- ops::{Deref, DerefMut},
-};
-
-use alloc::{
- alloc::{alloc, dealloc},
- borrow::Cow,
- string::String,
-};
-use serde::{Deserialize, Serialize};
-
-use crate::ScriptContext;
-
-mod tortuise {
- #[link(wasm_import_module = "tortuise")]
- unsafe extern "C" {
- pub unsafe fn entity_size(context: u64, name: *const u8, name_len: usize) -> usize;
- pub unsafe fn load_entity(context: u64, name: *const u8, name_len: usize, offset: *mut u8);
- pub unsafe fn save_entity(
- context: u64,
- name: *const u8,
- name_len: usize,
- offset: *const u8,
- size: usize,
- );
- }
-}
-
-fn load_entity<'de, T: Deserialize<'de>>(context: u64, name: &str) -> Option<T> {
- unsafe {
- let size = tortuise::entity_size(context, name.as_ptr(), name.len());
- let Ok(layout) = Layout::array::<u8>(size) else {
- log::error!("Failed to create layout for size: {size}");
- panic!();
- };
- let ptr = alloc(layout);
- tortuise::load_entity(context, name.as_ptr(), name.len(), ptr);
- let data = core::slice::from_raw_parts(ptr, size);
- let data = messagepack_serde::from_slice(data).ok()?;
- dealloc(ptr, layout);
- Some(data)
- }
-}
-
-fn save_entity<T: Serialize>(context: u64, name: &str, state: &T) {
- unsafe {
- let data = messagepack_serde::to_vec(state).unwrap();
- tortuise::save_entity(
- context,
- name.as_ptr(),
- name.len(),
- data.as_ptr(),
- data.len(),
- );
- }
-}
-
-pub struct Entity<T> {
- name: Cow<'static, str>,
- default: fn() -> T,
-}
-
-pub struct EntityRef<'entity, T> {
- entity: PhantomData<&'entity Entity<T>>,
- data: T,
-}
-
-pub struct EntityMut<'entity, T: Serialize> {
- context: u64,
- entity: &'entity Entity<T>,
- data: T,
-}
-
-impl<'de, T: Serialize + Deserialize<'de>> Entity<T> {
- pub const fn new(name: &'static str, default: fn() -> T) -> Self {
- Self {
- name: Cow::Borrowed(name),
- default,
- }
- }
-
- pub const fn from_string(name: String, default: fn() -> T) -> Self {
- Self {
- name: Cow::Owned(name),
- default,
- }
- }
-
- pub fn get(&self, context: &ScriptContext) -> EntityRef<'_, T> {
- EntityRef {
- entity: PhantomData,
- data: load_entity(context.0, &self.name).unwrap_or_else(self.default),
- }
- }
-
- pub fn get_mut(&mut self, context: &ScriptContext) -> EntityMut<'_, T> {
- EntityMut {
- context: context.0,
- entity: self,
- data: load_entity(context.0, &self.name).unwrap_or_else(self.default),
- }
- }
-}
-
-impl<T> Deref for EntityRef<'_, T> {
- type Target = T;
-
- fn deref(&self) -> &Self::Target {
- &self.data
- }
-}
-
-impl<T: Serialize> Deref for EntityMut<'_, T> {
- type Target = T;
-
- fn deref(&self) -> &Self::Target {
- &self.data
- }
-}
-
-impl<T: Serialize> DerefMut for EntityMut<'_, T> {
- fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.data
- }
-}
-
-impl<T: Serialize> Drop for EntityMut<'_, T> {
- fn drop(&mut self) {
- save_entity(self.context, &self.entity.name, &self.data);
- }
-}
diff --git a/src/input.rs b/src/input.rs
deleted file mode 100644
index a72597d..0000000
--- a/src/input.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-use serde::{Deserialize, Serialize};
-
-use crate::ScriptContext;
-
-mod tortuise {
- #[link(wasm_import_module = "tortuise")]
- unsafe extern "C" {
- pub safe fn is_key_pressed_this_frame(context: u64, keycode: u32) -> u32;
- }
-}
-
-/// Represents a key.
-#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash, Serialize, Deserialize)]
-pub enum KeyCode {
- /// Backspace key (Delete on macOS, Backspace on other platforms).
- Backspace,
- /// Enter key.
- Enter,
- /// Left arrow key.
- Left,
- /// Right arrow key.
- Right,
- /// Up arrow key.
- Up,
- /// Down arrow key.
- Down,
- /// Home key.
- Home,
- /// End key.
- End,
- /// Page up key.
- PageUp,
- /// Page down key.
- PageDown,
- /// Tab key.
- Tab,
- /// Shift + Tab key.
- BackTab,
- /// Delete key. (Fn+Delete on macOS, Delete on other platforms)
- Delete,
- /// Insert key.
- Insert,
- /// F key.
- ///
- /// `KeyCode::F(1)` represents F1 key, etc.
- F(u8),
- /// A character.
- ///
- /// `KeyCode::Char('c')` represents `c` character, etc.
- Char(char),
- /// Null.
- Null,
- /// Escape key.
- Esc,
-}
-
-fn key_code_to_number(key_code: KeyCode) -> u32 {
- match key_code {
- KeyCode::Null => 0,
- KeyCode::Backspace => 1 << 24,
- KeyCode::Enter => 2 << 24,
- KeyCode::Left => 3 << 24,
- KeyCode::Right => 4 << 24,
- KeyCode::Up => 5 << 24,
- KeyCode::Down => 6 << 24,
- KeyCode::Home => 7 << 24,
- KeyCode::End => 8 << 24,
- KeyCode::PageUp => 9 << 24,
- KeyCode::PageDown => 10 << 24,
- KeyCode::Tab => 11 << 24,
- KeyCode::BackTab => 12 << 24,
- KeyCode::Delete => 13 << 24,
- KeyCode::Insert => 14 << 24,
- KeyCode::F(f) => 15 << 24 | f as u32,
- KeyCode::Char(c) => 16 << 24 | c as u32,
- KeyCode::Esc => 17 << 24,
- }
-}
-
-impl ScriptContext {
- pub fn is_key_pressed_this_frame(&self, key_code: KeyCode) -> bool {
- tortuise::is_key_pressed_this_frame(self.0, key_code_to_number(key_code)) > 0
- }
-}
diff --git a/src/lib.rs b/src/lib.rs
index bc94658..c78eccb 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,29 +1,4 @@
-#![no_std]
-
-extern crate alloc;
-
-pub mod allocator;
-pub mod buffer;
-pub mod entity;
-pub mod input;
-pub mod log;
-pub mod process;
-pub mod random;
-pub mod scene;
-pub mod script;
-pub mod state;
-pub mod storage;
-pub mod time;
-
-#[derive(Clone, Copy)]
-#[repr(transparent)]
-pub struct ScriptContext(u64);
-
-#[macro_export]
-macro_rules! prelude {
- () => {
- #[global_allocator]
- static ALLOCATOR: $crate::allocator::BumpAllocator =
- $crate::allocator::BumpAllocator::new();
- };
+cfg_select! {
+ target_arch = "wasm32" => { pub use tortuise_script_wasm::*; }
+ _ => { pub use tortuise_script_compiled::*; }
}
diff --git a/src/log.rs b/src/log.rs
deleted file mode 100644
index 306a0d5..0000000
--- a/src/log.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-use alloc::string::ToString;
-use log::{LevelFilter, Log, Metadata, Record, SetLoggerError, set_logger, set_max_level};
-
-mod tortuise {
- use log::Level;
-
- #[link(wasm_import_module = "tortuise")]
- unsafe extern "C" {
- pub unsafe fn log(severity: Level, message: *const u8, length: usize);
- }
-}
-
-static LOG: TortuiseLogger = TortuiseLogger;
-
-pub struct TortuiseLogger;
-
-impl TortuiseLogger {
- pub fn init() -> Result<(), SetLoggerError> {
- set_logger(&LOG).map(|()| set_max_level(LevelFilter::Trace))
- }
-}
-
-impl Log for TortuiseLogger {
- fn enabled(&self, _: &Metadata) -> bool {
- true
- }
-
- fn log(&self, record: &Record) {
- let message = record.args().to_string();
- unsafe {
- tortuise::log(record.level(), message.as_ptr(), message.len());
- }
- }
-
- fn flush(&self) {}
-}
diff --git a/src/process.rs b/src/process.rs
deleted file mode 100644
index ed8c542..0000000
--- a/src/process.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-use crate::ScriptContext;
-
-mod tortuise {
- #[link(wasm_import_module = "tortuise")]
- unsafe extern "C" {
- pub safe fn exit(context: u64) -> !;
- }
-}
-
-impl ScriptContext {
- pub fn exit(&self) -> ! {
- tortuise::exit(self.0)
- }
-}
diff --git a/src/random.rs b/src/random.rs
deleted file mode 100644
index 334b6bf..0000000
--- a/src/random.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-use rand::{Rng, SeedableRng, TryRng, rngs::SmallRng};
-
-mod tortuise {
- #[link(wasm_import_module = "tortuise")]
- unsafe extern "C" {
- pub safe fn random_u64() -> u64;
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct TortuiseRng(SmallRng);
-
-impl TortuiseRng {
- pub fn new() -> Self {
- Self::seed_from_u64(tortuise::random_u64())
- }
-}
-
-impl Default for TortuiseRng {
- fn default() -> Self {
- Self::new()
- }
-}
-
-impl SeedableRng for TortuiseRng {
- type Seed = <SmallRng as SeedableRng>::Seed;
-
- fn from_seed(seed: Self::Seed) -> Self {
- Self(SmallRng::from_seed(seed))
- }
-
- fn seed_from_u64(state: u64) -> Self {
- Self(SmallRng::seed_from_u64(state))
- }
-
- fn from_rng<R: Rng + ?Sized>(rng: &mut R) -> Self {
- Self(SmallRng::from_rng(rng))
- }
-
- fn try_from_rng<R: TryRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
- Ok(Self(SmallRng::try_from_rng(rng)?))
- }
-
- fn fork(&mut self) -> Self
- where
- Self: Rng,
- {
- Self(self.0.fork())
- }
-
- fn try_fork(&mut self) -> Result<Self, <Self as TryRng>::Error>
- where
- Self: TryRng,
- {
- Ok(Self(self.0.try_fork()?))
- }
-}
-
-impl TryRng for TortuiseRng {
- type Error = <SmallRng as TryRng>::Error;
-
- fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
- self.0.try_next_u32()
- }
-
- fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
- self.0.try_next_u64()
- }
-
- fn try_fill_bytes(&mut self, dst: &mut [u8]) -> Result<(), Self::Error> {
- self.0.try_fill_bytes(dst)
- }
-}
diff --git a/src/scene.rs b/src/scene.rs
deleted file mode 100644
index 95284e9..0000000
--- a/src/scene.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-use crate::ScriptContext;
-
-mod tortuise {
- #[link(wasm_import_module = "tortuise")]
- unsafe extern "C" {
- pub unsafe fn scene_id_by_name(context: u64, name: *const u8, length: usize) -> usize;
- pub safe fn preload_scene(context: u64, id: usize);
- pub safe fn is_scene_loaded(context: u64, id: usize) -> u32;
- pub safe fn switch_scene(context: u64, id: usize);
- }
-}
-
-impl ScriptContext {
- pub fn scene_id(&self, name: &str) -> usize {
- unsafe { tortuise::scene_id_by_name(self.0, name.as_ptr(), name.len()) }
- }
-
- pub fn preload_scene(&self, name: &str) {
- let id = self.scene_id(name);
- tortuise::preload_scene(self.0, id);
- }
-
- pub fn is_scene_loaded(&self, name: &str) -> bool {
- let id = self.scene_id(name);
- tortuise::is_scene_loaded(self.0, id) > 0
- }
-
- pub fn switch_scene(&self, name: &str) {
- let id = self.scene_id(name);
- tortuise::switch_scene(self.0, id);
- }
-}
diff --git a/src/script.rs b/src/script.rs
deleted file mode 100644
index 0de2b54..0000000
--- a/src/script.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-use crate::ScriptContext;
-
-mod tortuise {
- #[link(wasm_import_module = "tortuise")]
- unsafe extern "C" {
- pub unsafe fn script_id_by_name(context: u64, name: *const u8, length: usize) -> usize;
- pub safe fn preload_script(context: u64, id: usize);
- pub safe fn is_script_loaded(context: u64, id: usize) -> u32;
- pub safe fn unload_script(context: u64, id: usize);
- pub safe fn activate_script(context: u64, id: usize);
- pub safe fn deactivate_script(context: u64, id: usize);
- }
-}
-
-impl ScriptContext {
- pub fn script_id(&self, name: &str) -> usize {
- unsafe { tortuise::script_id_by_name(self.0, name.as_ptr(), name.len()) }
- }
-
- pub fn preload_script(&self, name: &str) {
- let id = self.script_id(name);
- tortuise::preload_script(self.0, id)
- }
-
- pub fn is_script_loaded(&self, name: &str) -> bool {
- let id = self.script_id(name);
- tortuise::is_script_loaded(self.0, id) > 0
- }
-
- pub fn unload_script(&self, name: &str) {
- let id = self.script_id(name);
- tortuise::unload_script(self.0, id)
- }
-
- pub fn activate_script(&self, name: &str) {
- let id = self.script_id(name);
- tortuise::activate_script(self.0, id)
- }
-
- pub fn deactivate_script(&self, name: &str) {
- let id = self.script_id(name);
- tortuise::deactivate_script(self.0, id)
- }
-}
diff --git a/src/state.rs b/src/state.rs
deleted file mode 100644
index 8b4de18..0000000
--- a/src/state.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-use core::{
- alloc::Layout,
- ops::{Deref, DerefMut},
-};
-
-use alloc::alloc::{alloc, dealloc};
-use serde::{Serialize, de::DeserializeOwned};
-
-use crate::ScriptContext;
-
-mod tortuise {
- #[link(wasm_import_module = "tortuise")]
- unsafe extern "C" {
- pub safe fn state_size(context: u64) -> usize;
- pub unsafe fn load_state(context: u64, offset: *mut u8);
- pub unsafe fn save_state(context: u64, offset: *const u8, size: usize);
-
- }
-}
-
-impl ScriptContext {
- pub fn load_state<T: DeserializeOwned>(&self) -> Option<T> {
- unsafe {
- let size = tortuise::state_size(self.0);
- let layout = Layout::array::<u8>(size).unwrap();
- let ptr = alloc(layout);
- tortuise::load_state(self.0, ptr);
- let data = core::slice::from_raw_parts(ptr, size);
- let data = messagepack_serde::from_reader(data).ok()?;
- dealloc(ptr, layout);
- Some(data)
- }
- }
-}
-
-fn save_state<T: Serialize>(context: u64, state: &T) {
- unsafe {
- let data = messagepack_serde::to_vec(state).unwrap();
- tortuise::save_state(context, data.as_ptr(), data.len());
- }
-}
-
-pub struct StateMut<T: Serialize> {
- context: u64,
- data: T,
-}
-
-impl<T: Serialize + DeserializeOwned> StateMut<T> {
- pub fn load(context: &ScriptContext) -> Option<Self> {
- Some(Self {
- context: context.0,
- data: context.load_state()?,
- })
- }
-
- pub fn load_or(context: &ScriptContext, default: T) -> Self {
- Self {
- context: context.0,
- data: context.load_state().unwrap_or(default),
- }
- }
-
- pub fn load_or_else(context: &ScriptContext, default: impl FnOnce() -> T) -> Self {
- Self {
- context: context.0,
- data: context.load_state().unwrap_or_else(default),
- }
- }
-
- pub fn load_or_default(context: &ScriptContext) -> Self
- where
- T: Default,
- {
- Self {
- context: context.0,
- data: context.load_state().unwrap_or_default(),
- }
- }
-}
-
-impl<T: Serialize> Deref for StateMut<T> {
- type Target = T;
-
- fn deref(&self) -> &Self::Target {
- &self.data
- }
-}
-
-impl<T: Serialize> DerefMut for StateMut<T> {
- fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.data
- }
-}
-
-impl<T: Serialize> Drop for StateMut<T> {
- fn drop(&mut self) {
- save_state(self.context, &self.data);
- }
-}
diff --git a/src/storage.rs b/src/storage.rs
deleted file mode 100644
index 48fdcb4..0000000
--- a/src/storage.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-use core::{
- alloc::Layout,
- ops::{Deref, DerefMut},
-};
-
-use alloc::alloc::{alloc, dealloc};
-use serde::{Deserialize, Serialize};
-
-use crate::ScriptContext;
-
-mod tortuise {
- #[link(wasm_import_module = "tortuise")]
- unsafe extern "C" {
- pub safe fn storage_size(context: u64) -> usize;
- pub unsafe fn load_storage(context: u64, ptr: *mut u8);
- pub unsafe fn save_storage(context: u64, ptr: *const u8, size: usize);
- }
-}
-
-fn load_storage<'de, T: Deserialize<'de>>(context: u64) -> Option<T> {
- unsafe {
- let size = tortuise::storage_size(context);
- let layout = Layout::array::<u8>(size).unwrap();
- let ptr = alloc(layout);
- tortuise::load_storage(context, ptr);
- let data = core::slice::from_raw_parts(ptr, size);
- let data = messagepack_serde::from_slice(data).ok()?;
- dealloc(ptr, layout);
- Some(data)
- }
-}
-
-fn save_storage<T: Serialize>(context: u64, state: &T) {
- unsafe {
- let data = messagepack_serde::to_vec(state).unwrap();
- tortuise::save_storage(context, data.as_ptr(), data.len());
- }
-}
-
-pub struct Storage<T> {
- initial_state: fn() -> T,
-}
-
-pub struct StorageMut<T: Serialize> {
- context: u64,
- data: T,
-}
-
-impl<'de, T: Serialize + Deserialize<'de>> Storage<T> {
- pub const fn new(initial_state: fn() -> T) -> Self {
- Self { initial_state }
- }
-
- pub fn load(&self, context: &ScriptContext) -> T {
- load_storage(context.0).unwrap_or_else(self.initial_state)
- }
-
- pub fn load_mut(&self, context: &ScriptContext) -> StorageMut<T> {
- StorageMut {
- context: context.0,
- data: load_storage(context.0).unwrap_or_else(self.initial_state),
- }
- }
-}
-
-impl<T: Serialize> Deref for StorageMut<T> {
- type Target = T;
-
- fn deref(&self) -> &Self::Target {
- &self.data
- }
-}
-
-impl<T: Serialize> DerefMut for StorageMut<T> {
- fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.data
- }
-}
-
-impl<T: Serialize> Drop for StorageMut<T> {
- fn drop(&mut self) {
- save_storage(self.context, &self.data);
- }
-}
diff --git a/src/time.rs b/src/time.rs
deleted file mode 100644
index 35e1a86..0000000
--- a/src/time.rs
+++ /dev/null
@@ -1,142 +0,0 @@
-use core::{
- ops::{Add, AddAssign, Sub, SubAssign},
- time::Duration,
-};
-
-use serde::{Deserialize, Serialize};
-
-use crate::ScriptContext;
-
-mod tortuise {
-
- #[link(wasm_import_module = "tortuise")]
- unsafe extern "C" {
- pub safe fn system_now(context: u64) -> u64;
- pub safe fn monotonic_now(context: u64) -> u64;
- pub safe fn delta_time(context: u64) -> u64;
- }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
-#[repr(transparent)]
-#[serde(transparent)]
-pub struct SystemTime(u128);
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
-#[repr(transparent)]
-#[serde(transparent)]
-pub struct Instant(u128);
-
-impl ScriptContext {
- pub fn delta_time(&self) -> Duration {
- Duration::from_nanos(tortuise::delta_time(self.0))
- }
-}
-
-impl SystemTime {
- pub const UNIX_EPOCH: Self = Self(0);
-
- pub fn now(context: &ScriptContext) -> Self {
- Self(tortuise::system_now(context.0) as u128)
- }
-
- pub fn duration_since(self, earlier: SystemTime) -> Option<Duration> {
- if self < earlier {
- return None;
- }
-
- Some(Duration::from_nanos_u128(self.0 - earlier.0))
- }
-
- pub fn checked_add(self, duration: Duration) -> Option<Self> {
- Some(Self(self.0.checked_add(duration.as_nanos())?))
- }
-
- pub fn checked_sub(self, duration: Duration) -> Option<Self> {
- Some(Self(self.0.checked_sub(duration.as_nanos())?))
- }
-}
-
-impl Add<Duration> for SystemTime {
- type Output = Self;
-
- fn add(self, rhs: Duration) -> Self::Output {
- self.checked_add(rhs).unwrap()
- }
-}
-
-impl AddAssign<Duration> for SystemTime {
- fn add_assign(&mut self, rhs: Duration) {
- *self = self.add(rhs);
- }
-}
-
-impl Sub<Duration> for SystemTime {
- type Output = Self;
-
- fn sub(self, rhs: Duration) -> Self::Output {
- self.checked_sub(rhs).unwrap()
- }
-}
-
-impl SubAssign<Duration> for SystemTime {
- fn sub_assign(&mut self, rhs: Duration) {
- *self = self.sub(rhs)
- }
-}
-
-impl Instant {
- pub fn now(context: &ScriptContext) -> Self {
- Self(tortuise::monotonic_now(context.0) as u128)
- }
-
- pub fn duration_since(self, earlier: Instant) -> Option<Duration> {
- if earlier > self {
- return None;
- }
-
- Some(Duration::from_nanos_u128(self.0 - earlier.0))
- }
-
- pub fn elapsed(self, context: &ScriptContext) -> Duration {
- Self::now(context)
- .duration_since(self)
- .unwrap_or(Duration::ZERO)
- }
-
- pub fn checked_add(self, duration: Duration) -> Option<Self> {
- Some(Self(self.0.checked_add(duration.as_nanos())?))
- }
-
- pub fn checked_sub(self, duration: Duration) -> Option<Self> {
- Some(Self(self.0.checked_sub(duration.as_nanos())?))
- }
-}
-
-impl Add<Duration> for Instant {
- type Output = Self;
-
- fn add(self, rhs: Duration) -> Self::Output {
- self.checked_add(rhs).unwrap()
- }
-}
-
-impl AddAssign<Duration> for Instant {
- fn add_assign(&mut self, rhs: Duration) {
- *self = self.add(rhs);
- }
-}
-
-impl Sub<Duration> for Instant {
- type Output = Self;
-
- fn sub(self, rhs: Duration) -> Self::Output {
- self.checked_sub(rhs).unwrap()
- }
-}
-
-impl SubAssign<Duration> for Instant {
- fn sub_assign(&mut self, rhs: Duration) {
- *self = self.sub(rhs)
- }
-}