From c106e697edefa0af5be96b1f6a7528d08906345e Mon Sep 17 00:00:00 2001 From: cat_or_not <41955154+catornot@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:01:15 -0400 Subject: [PATCH] add examples --- Cargo.toml | 16 ++++++++ examples/async_engine.rs | 46 +++++++++++++++++++++++ examples/cvar_example.rs | 73 ++++++++++++++++++++++++++++++++++++ examples/squirrel_example.rs | 50 ++++++++++++++++++++++++ src/prelude.rs | 3 ++ 5 files changed, 188 insertions(+) create mode 100644 examples/async_engine.rs create mode 100644 examples/cvar_example.rs create mode 100644 examples/squirrel_example.rs diff --git a/Cargo.toml b/Cargo.toml index 02e14c6..bcdc98a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,3 +29,19 @@ targets = ["x86_64-pc-windows-msvc", "x86_64-pc-windows-gnu"] # hopefully docs.r [features] # default = ["async_engine"] async_engine = [] + +[[example]] +crate-type = ["cdylib"] +name = "squirrel_example" +path = "examples/squirrel_example.rs" + +[[example]] +crate-type = ["cdylib"] +name = "cvar_example" +path = "examples/cvar_example.rs" + +[[example]] +crate-type = ["cdylib"] +name = "async_engine" +path = "examples/async_engine.rs" +required-features = ["async_engine"] \ No newline at end of file diff --git a/examples/async_engine.rs b/examples/async_engine.rs new file mode 100644 index 0000000..79cb27d --- /dev/null +++ b/examples/async_engine.rs @@ -0,0 +1,46 @@ +use rrplug::{bindings::cvar::convar::FCVAR_GAMEDLL, prelude::*}; + +pub struct ExamplePlugin; + +impl Plugin for ExamplePlugin { + const PLUGIN_INFO: PluginInfo = + PluginInfo::new(c"example", c"EXAMPLLEE", c"EXAMPLE", PluginContext::all()); + + fn new(_reloaded: bool) -> Self { + Self {} + } + + fn on_dll_load( + &self, + engine_data: Option<&EngineData>, + _dll_ptr: &DLLPointer, + engine_token: EngineToken, + ) { + let Some(engine_data) = engine_data else { + return; + }; + + engine_data + .register_concommand( + "set_max_score", + set_max_score, + "this will set the game's max score", + FCVAR_GAMEDLL as i32, + engine_token, + ) + .expect("could not create set_max_score concommand"); + } +} + +entry!(ExamplePlugin); + +#[rrplug::concommand] +fn set_max_score(command: CCommandResult) -> Option<()> { + _ = async_execute(AsyncEngineMessage::run_squirrel_func( + "SetScoreLimit", + ScriptContext::SERVER, + command.get_arg(0)?.parse::().ok()?, + )); + + None +} diff --git a/examples/cvar_example.rs b/examples/cvar_example.rs new file mode 100644 index 0000000..06cbf7e --- /dev/null +++ b/examples/cvar_example.rs @@ -0,0 +1,73 @@ +use rrplug::{bindings::cvar::convar::FCVAR_GAMEDLL, prelude::*}; +use std::cell::RefCell; + +static HELLO_COUNT: EngineGlobal>> = + EngineGlobal::new(RefCell::new(None)); + +pub struct ExamplePlugin; + +impl Plugin for ExamplePlugin { + const PLUGIN_INFO: PluginInfo = + PluginInfo::new(c"example", c"EXAMPLLEE", c"EXAMPLE", PluginContext::all()); + + fn new(_reloaded: bool) -> Self { + Self {} + } + + fn on_dll_load( + &self, + engine_data: Option<&EngineData>, + _dll_ptr: &DLLPointer, + engine_token: EngineToken, + ) { + let Some(engine_data) = engine_data else { + return; + }; + + engine_data + .register_concommand( + "hello_world", + hello_world, + "this will set the game's max score", + FCVAR_GAMEDLL as i32, + engine_token, + ) + .expect("could not create set_max_score concommand"); + + let convar = ConVarStruct::try_new( + &ConVarRegister { + callback: Some(hello_count), // prints the amount of hellos on each update + ..ConVarRegister::mandatory("hello_count", "0", FCVAR_GAMEDLL as i32, "todo") + }, + engine_token, + ) + .expect("could not create hello_count convar"); + + _ = HELLO_COUNT.get(engine_token).borrow_mut().replace(convar); + } +} + +entry!(ExamplePlugin); + +#[rrplug::concommand] +fn hello_world() { + log::info!("hello world"); + + let mut convar = HELLO_COUNT.get(engine_token).borrow_mut(); + if let Some(convar) = convar.as_mut() { + convar.set_value_i32(convar.get_value_i32() + 1, engine_token); + } +} + +#[rrplug::convar] +fn hello_count() { + log::info!( + "hellos {}", + HELLO_COUNT + .get(engine_token) + .borrow() + .as_ref() + .map(|convar| convar.get_value_i32()) + .unwrap_or(0) + ); +} diff --git a/examples/squirrel_example.rs b/examples/squirrel_example.rs new file mode 100644 index 0000000..8d26847 --- /dev/null +++ b/examples/squirrel_example.rs @@ -0,0 +1,50 @@ +use rrplug::{ + bindings::squirreldatatypes::SQClosure, + high::squirrel::{call_sq_object_function, SQHandle}, + prelude::*, +}; + +pub struct ExamplePlugin; + +impl Plugin for ExamplePlugin { + const PLUGIN_INFO: PluginInfo = + PluginInfo::new(c"example", c"EXAMPLLEE", c"EXAMPLE", PluginContext::all()); + + fn new(_reloaded: bool) -> Self { + register_sq_functions(great_person); + register_sq_functions(call_with_random_number); + register_sq_functions(sum); + + Self {} + } +} + +entry!(ExamplePlugin); + +// if it returns an error the function will throw a error in the sqvm which can be caught at the call site +#[rrplug::sqfunction(VM = "SERVER", ExportName = "GreatPerson")] +fn great_person(function: SQHandle) -> Result { + // non type safe way of getting a return from a function + // this could be changed if the crate gets some attention + let name = call_sq_object_function(sqvm, sq_functions, function)?; + + log::info!("hello, {}", name); + + Ok(name) +} + +#[rrplug::sqfunction(VM = "SERVER", ExportName = "CallWithRandomNumber")] +fn call_with_random_number(mut function: SquirrelFn<(i32, String)>) { + const TOTALY_RANDOM_NUMBER: i32 = 37; + + _ = function.call( + sqvm, + sq_functions, + (TOTALY_RANDOM_NUMBER, TOTALY_RANDOM_NUMBER.to_string()), + ); +} + +#[rrplug::sqfunction(VM = "SERVER", ExportName = "Sum")] +fn sum(vec: Vector3, numbers: Vec) -> f32 { + vec.x + vec.y + vec.z + numbers.into_iter().sum::() +} diff --git a/src/prelude.rs b/src/prelude.rs index 66d8c9c..34fb1ce 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -30,6 +30,9 @@ pub use crate::{ }; pub use log; +#[cfg(feature = "async_engine")] +pub use crate::high::engine_sync::{async_execute, AsyncEngineMessage}; + // consider adding more stuff ^ /// puts a thread on sleep in milliseconds