summaryrefslogtreecommitdiff
path: root/platforms/tortuise-script-wasm/src/script.rs
blob: ee4d91df1bd1298569ad7b18a77e6764bacfc4ce (plain)
use core::alloc::Layout;

use alloc::string::String;

use crate::ScriptContext;

mod tortuise {
	#[link(wasm_import_module = "tortuise")]
	unsafe extern "C" {
		pub safe fn script_name_size(context: u64) -> usize;
		pub unsafe fn load_script_name(context: u64, offset: *const u8);
		pub unsafe fn script_id_by_name(context: u64, name: *const u8, length: usize) -> usize;
		pub safe fn activate_script(context: u64, id: usize);
		pub safe fn deactivate_script(context: u64, id: usize);
	}
}

impl ScriptContext<'_> {
	pub fn current_script_name(&self) -> String {
		// safety: the length is correct and the string will fit into offset
		unsafe {
			let len = tortuise::script_name_size(self.0);
			if len == 0 {
				return String::new();
			}
			let offset = alloc::alloc::alloc(Layout::array::<u8>(len).unwrap());
			tortuise::load_script_name(self.0, offset);
			String::from_raw_parts(offset, len, len)
		}
	}

	pub fn script_id(&self, name: &str) -> Option<usize> {
		let id = unsafe { tortuise::script_id_by_name(self.0, name.as_ptr(), name.len()) };
		(id < usize::MAX).then_some(id)
	}

	pub fn activate_script(&mut self, name: &str) -> Option<()> {
		let id = self.script_id(name)?;
		tortuise::activate_script(self.0, id);
		Some(())
	}

	pub fn deactivate_script(&mut self, name: &str) -> Option<()> {
		let id = self.script_id(name)?;
		tortuise::deactivate_script(self.0, id);
		Some(())
	}
}