use sm_ext::{cell_t, native, register_natives, HandleError, HandleRef, HandleType, HasHandleType, IExtension, IExtensionInterface, IHandleSys, IPluginContext, IShareSys, SMExtension, SMInterfaceApi, TryIntoPlugin};
#[derive(Debug)]
struct RustContext(i32);
impl HasHandleType for RustContext {
fn handle_type<'ty>() -> &'ty HandleType<Self> {
MyExtension::handle_type()
}
}
impl<'ctx> TryIntoPlugin<'ctx> for RustContext {
type Error = HandleError;
fn try_into_plugin(self, ctx: &'ctx IPluginContext) -> Result<cell_t, Self::Error> {
let handle = MyExtension::handle_type().create_handle(self, ctx.get_identity())?;
Ok(handle.into())
}
}
#[native]
fn native_obj_new(_ctx: &IPluginContext) -> RustContext {
println!(">>> Rust.Rust()");
RustContext(0)
}
#[native]
fn native_obj_add(_ctx: &IPluginContext, mut this: HandleRef<RustContext>, number: i32) {
println!(">>> Rust.Add({:?}, {:?})", this, number);
this.0 += number;
}
#[native]
fn native_obj_result(_ctx: &IPluginContext, this: HandleRef<RustContext>) -> i32 {
println!(">>> Rust.Result({:?})", this);
this.0
}
#[derive(Default, SMExtension)]
#[extension(name = "Rusty", description = "Sample extension written in Rust")]
pub struct MyExtension {
handle_type: Option<HandleType<RustContext>>,
}
impl MyExtension {
fn get() -> &'static Self {
EXTENSION_GLOBAL.with(|ext| unsafe { &(*ext.borrow().unwrap()).delegate })
}
fn handle_type() -> &'static HandleType<RustContext> {
Self::get().handle_type.as_ref().unwrap()
}
}
impl IExtensionInterface for MyExtension {
fn on_extension_load(&mut self, myself: IExtension, sys: IShareSys, late: bool) -> Result<(), Box<dyn std::error::Error>> {
println!(">>> Rusty extension loaded! me = {:?}, sys = {:?}, late = {:?}", myself, sys, late);
let handlesys: IHandleSys = sys.request_interface(&myself)?;
println!(">>> Got interface: {:?} v{:?}", handlesys.get_interface_name(), handlesys.get_interface_version());
self.handle_type = Some(handlesys.create_type("RustContext", myself.get_identity())?);
register_natives!(
&sys,
&myself,
[
("Rust.Rust", native_obj_new), ("Rust.Add", native_obj_add), ("Rust.Result.get", native_obj_result), ]
);
Ok(())
}
fn on_extension_unload(&mut self) {
self.handle_type = None;
}
}