### Rust: Calling SourcePawn Functions and Executing Forwards Dynamically Source: https://context7.com/viniciusred/sm-ext-rs/llms.txt Provides examples of executing SourcePawn callbacks and creating/executing private forwards dynamically from Rust. It uses the `sm-ext` crate to interact with SourcePawn's function and forward management systems. The functions demonstrate pushing parameters and retrieving results. ```rust use sm_ext::{c_str, native, ExecType, Executable, IForwardManager, IPluginContext, IPluginFunction, ParamType}; use std::error::Error; #[native] fn execute_callback(ctx: &IPluginContext, mut func: IPluginFunction) -> Result> { // Call a SourcePawn function with parameters func.push(100)?; func.push(c_str!("test message"))?; func.push(42.5)?; let result = func.execute()?; println!("Callback returned: {}", result); Ok(i32::from(result)) } #[native] fn create_and_execute_forward(ctx: &IPluginContext, mut callback: IPluginFunction) -> Result> { let forwardsys = MyExtension::forwardsys(); // Create a private forward dynamically let mut forward = forwardsys.create_private_forward( None, ExecType::Single, &[ParamType::Cell, ParamType::String, ParamType::Float] )?; forward.add_function(&mut callback); forward.push(10)?; forward.push(c_str!("Hello from Rust"))?; forward.push(3.14)?; let result = forward.execute()?; Ok(i32::from(result)) } ``` -------------------------------- ### Initialize SourceMod Extension and Log Messages (Rust) Source: https://context7.com/viniciusred/sm-ext-rs/llms.txt This snippet demonstrates how to set up a SourceMod extension in Rust. It requests necessary interfaces like ISourceMod, IForwardManager, and IHandleSys from the ShareSys. It also shows how to log messages and errors using the ISourceMod interface and print interface versions. Dependencies include the 'sm-ext' crate. ```rust use sm_ext::{IExtension, IForwardManager, IHandleSys, IShareSys, ISourceMod, SMInterfaceApi}; fn extension_setup(myself: &IExtension, sys: &IShareSys) -> Result<(), Box> { // Request standard interfaces let sourcemod: ISourceMod = sys.request_interface(myself)?; let forwardsys: IForwardManager = sys.request_interface(myself)?; let handlesys: IHandleSys = sys.request_interface(myself)?; // Log messages sourcemod.log_message(myself, "Extension initialized successfully".to_string()); sourcemod.log_error(myself, "This is an error message".to_string()); // Check interface versions println!("ISourceMod v{}", sourcemod.get_interface_version()); println!("IForwardManager v{}", forwardsys.get_interface_version()); println!("IHandleSys v{}", handlesys.get_interface_version()); Ok(()) } ``` -------------------------------- ### Rust: Game Frame Hooks and Async Integration with SourceMod Source: https://context7.com/viniciusred/sm-ext-rs/llms.txt Illustrates how to hook into game frames and integrate asynchronous Rust code with SourceMod using the `sm-ext` crate. It shows setting up frame hooks, adding frame actions, and spawning asynchronous tasks using `async-std` and `futures`. This enables non-blocking operations within the SourceMod extension. ```rust use sm_ext::{GameFrameHookId, ISourceMod, SMExtension}; use async_std::task; use futures::executor::{LocalPool, LocalSpawner}; use futures::task::LocalSpawnExt; use std::cell::RefCell; use std::time::Duration; #[derive(Default, SMExtension)] #[extension(name = "Rusty", description = "Async example")] pub struct MyExtension { sourcemod: Option, frame_hook: Option, pool: RefCell, } impl MyExtension { fn get() -> &'static Self { EXTENSION_GLOBAL.with(|ext| unsafe { &(*ext.borrow().unwrap()).delegate }) } fn spawner() -> LocalSpawner { Self::get().pool.borrow().spawner() } } extern "C" fn on_game_frame(_simulating: bool) { MyExtension::get().pool.borrow_mut().run_until_stalled() } // In on_extension_load: fn setup(sys: &IShareSys, myself: &IExtension) -> Result<(), Box> { let sourcemod: ISourceMod = sys.request_interface(myself)?; // Add a frame hook let frame_hook = sourcemod.add_game_frame_hook(on_game_frame); // Add a one-time frame action with closure sourcemod.add_frame_action(|| { println!("This runs on the next frame"); }); // Spawn async tasks MyExtension::spawner().spawn_local(async move { task::sleep(Duration::from_secs(5)).await; println!("Async task completed after 5 seconds"); })?; Ok(()) } ``` -------------------------------- ### Rust: Working with Custom Handle Types for Safe Object Passing Source: https://context7.com/viniciusred/sm-ext-rs/llms.txt Demonstrates how to define and use custom handle types in Rust to safely pass Rust objects to SourcePawn. It involves implementing `TryIntoPlugin` and utilizing `sm-ext`'s handle system for type creation, reading, and writing. This enables managing Rust object lifecycles from SourcePawn. ```rust use sm_ext::{cell_t, native, HandleError, HandleId, HandleType, IHandleSys, IPluginContext, TryIntoPlugin, SMExtension}; use std::cell::RefCell; use std::rc::Rc; #[derive(Debug)] struct Counter { value: i32, } impl<'ctx> TryIntoPlugin<'ctx> for Counter { type Error = HandleError; fn try_into_plugin(self, ctx: &'ctx IPluginContext) -> Result { let object = Rc::new(RefCell::new(self)); let handle = MyExtension::handle_type() .create_handle(object, ctx.get_identity(), None)?; Ok(handle.into()) } } #[native] fn counter_new(_ctx: &IPluginContext, initial: i32) -> Counter { Counter { value: initial } } #[native] fn counter_increment(ctx: &IPluginContext, handle: HandleId, amount: i32) -> Result<(), Box> { let counter = MyExtension::handle_type().read_handle(handle, ctx.get_identity())?; let mut counter = counter.try_borrow_mut()?; counter.value += amount; Ok(()) } #[native] fn counter_get(ctx: &IPluginContext, handle: HandleId) -> Result> { let counter = MyExtension::handle_type().read_handle(handle, ctx.get_identity())?; let counter = counter.try_borrow()?; Ok(counter.value) } #[derive(Default, SMExtension)] #[extension(name = "Rusty", description = "Handle example")] pub struct MyExtension { handle_type: Option>>, } impl MyExtension { fn get() -> &'static Self { EXTENSION_GLOBAL.with(|ext| unsafe { &(*ext.borrow().unwrap()).delegate }) } fn handle_type() -> &'static HandleType> { Self::get().handle_type.as_ref().unwrap() } } // In on_extension_load: fn setup(sys: &IShareSys, myself: &IExtension) -> Result<(), Box> { let handlesys: IHandleSys = sys.request_interface(myself)?; let handle_type = handlesys.create_type::>( "Counter", None, myself.get_identity() )?; // Store handle_type in extension struct Ok(()) } ``` -------------------------------- ### Create Basic SourceMod Extension in Rust Source: https://context7.com/viniciusred/sm-ext-rs/llms.txt Defines a minimal SourceMod extension using the `sm_ext` crate, including necessary metadata and lifecycle hooks for loading and unloading the extension. This serves as the foundation for more complex extensions. ```rust use sm_ext::{IExtension, IExtensionInterface, IShareSys, SMExtension}; #[derive(Default, SMExtension)] #[extension(name = "Rusty", description = "Sample extension written in Rust")] pub struct MyExtension; impl IExtensionInterface for MyExtension { fn on_extension_load(&mut self, myself: IExtension, sys: IShareSys, late: bool) -> Result<(), Box> { println!("Extension loaded! late = {}", late); Ok(()) } fn on_extension_unload(&mut self) { println!("Extension unloading"); } } ``` -------------------------------- ### Register Native Functions in Rust for SourceMod Source: https://context7.com/viniciusred/sm-ext-rs/llms.txt Registers Rust functions as SourcePawn natives, making them callable from SourceMod plugins. It demonstrates registering functions with different argument and return types, including basic types, strings, and mutable references. ```rust use sm_ext::{native, register_natives, IExtension, IPluginContext, IShareSys}; use std::ffi::CStr; #[native] fn rust_add(_ctx: &IPluginContext, a: i32, b: i32) -> i32 { a + b } #[native] fn rust_greet(ctx: &IPluginContext, name: &str, count: &mut i32) -> Result<(), &'static str> { println!("Hello, {}!", name); *count += 1; Ok(()) } #[native] fn rust_process(_ctx: &IPluginContext, value: i32, factor: f32, text: &CStr, output: &mut i32, result: &mut f32) -> f32 { *output = value * 2; *result = factor * 1.5; factor + value as f32 } // In on_extension_load: fn setup(sys: &IShareSys, myself: &IExtension) { register_natives!( sys, myself, [ ("Rust_Add", rust_add), ("Rust_Greet", rust_greet), ("Rust_Process", rust_process), ] ); } ``` -------------------------------- ### Create and Use Forwards in Rust for SourceMod Source: https://context7.com/viniciusred/sm-ext-rs/llms.txt Defines and utilizes global forwards to invoke SourcePawn functions from Rust code. This snippet illustrates how to register forwards using `sm_ext::forwards` macro and execute them with specific arguments, handling potential errors during execution. ```rust use sm_ext::{c_str, forwards, native, ExecType, IForwardManager, IPluginContext}; use std::ffi::CStr; #[forwards] struct MyForwards { #[global_forward("OnPlayerConnect", ExecType::Hook)] on_player_connect: fn(client: i32, name: &CStr) -> i32, #[global_forward("OnDataProcessed", ExecType::Ignore)] on_data_processed: fn(value: i32, result: f32) -> (), } #[native] fn trigger_event(_ctx: &IPluginContext, client_id: i32) -> Result { let result = MyForwards::on_player_connect(|fwd| { fwd.execute(client_id, c_str!("Player")) })?; MyForwards::on_data_processed(|fwd| { fwd.execute(42, 3.14) })?; Ok(result) } // In on_extension_load: fn setup(sys: &IShareSys, myself: &IExtension) -> Result<(), Box> { let forward_manager: IForwardManager = sys.request_interface(myself)?; MyForwards::register(&forward_manager)?; Ok(()) } // In on_extension_unload: fn cleanup() { MyForwards::unregister(); } ``` -------------------------------- ### SourceMod Cell_t Type Conversions (Rust) Source: https://context7.com/viniciusred/sm-ext-rs/llms.txt This Rust code illustrates how to perform conversions between standard Rust numeric types (i32, f32) and the SourceMod 'cell_t' type using the 'sm-ext' crate. It shows casting integers and floats to 'cell_t' and back. This is useful for interacting with SourcePawn or SourceMod functions that expect or return 'cell_t' values. ```rust use sm_ext::cell_t; fn cell_conversions() { let int_cell: cell_t = 42i32.into(); let int_value: i32 = int_cell.into(); let float_cell: cell_t = 3.14f32.into(); let float_value: f32 = float_cell.into(); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.