use std::{mem::forget, sync::OnceLock}; use giterated_models::{ error::OperationError, instance::Instance, object::{ObjectRequest, ObjectRequestError, ObjectResponse}, user::{DisplayName, User}, }; use giterated_plugin::{ handle::PluginInitializationState, new_stack::{FFIPluginMeta, PluginState}, vtable::{HostVTable, InitializationVTable}, }; use giterated_plugin_sys::PluginStackBuilder; use tracing::{info, trace_span, Level}; static INIT_VTABLE: OnceLock = OnceLock::new(); #[no_mangle] pub extern "C" fn plugin_meta() -> FFIPluginMeta { const PLUGIN_NAME: &str = "Example Plugin"; const PLUGIN_VERSION: &str = "1.0.0"; FFIPluginMeta { name: PLUGIN_NAME.as_ptr(), name_len: PLUGIN_NAME.len(), version: PLUGIN_VERSION.as_ptr(), version_len: PLUGIN_VERSION.len(), } } #[no_mangle] pub extern "C" fn load_host_vtable(_vtable: &HostVTable) { println!("Loading vtable"); } #[no_mangle] pub extern "C" fn load_initialization_vtable(init_vtable: &InitializationVTable) { INIT_VTABLE.set(*init_vtable).unwrap(); println!("Loaded initialization vtable"); } #[no_mangle] pub extern "C" fn load_type_metadata(metadata: *mut ()) { unsafe { giterated_static_runtime::initialize_type_metadata(metadata) } println!("Initialized type metadata for plugin"); } #[no_mangle] pub extern "C" fn initialize() -> PluginState { tracing_subscriber::fmt() .pretty() .with_thread_names(true) .with_max_level(Level::TRACE) .init(); println!("Building runtime"); let runtime = tokio::runtime::Builder::new_multi_thread() .enable_all() .build() .unwrap(); let _guard = runtime.enter(); forget(_guard); PluginState { inner: Box::into_raw(Box::new(())), } } #[no_mangle] pub extern "C" fn initialize_registration( state: *mut PluginInitializationState, ) -> *mut PluginInitializationState { let _guard: tracing::span::EnteredSpan = trace_span!("initialize_registration").entered(); let init_vtable = INIT_VTABLE.get().unwrap(); let mut builder = PluginStackBuilder::new((), state, init_vtable); builder.object::().object::(); builder.operation(handler); builder.value(value_getter); builder.setting_getter(setting_getter); state } async fn handler( _state: (), object: Instance, operation: ObjectRequest, ) -> Result> { info!("handling operation!"); info!("Try get object {} from instance {}", operation.0, object); Ok(ObjectResponse(operation.0)) } async fn value_getter( _state: (), _object: User, ) -> Result> { info!("OwO, value gotten!"); Ok(DisplayName(String::from("heya!"))) } async fn setting_getter( _state: (), _object: User, ) -> Result> { info!("OwO, setting gotten!"); Ok(DisplayName(String::from("heya! (but from a setting)"))) }