# Cygnixy Plugin Interface for Dynamic Lua Integration The Cygnixy Plugin Interface provides a robust system for managing Lua plugins within the **[Cygnixy framework](https://cygnixy.com)**. It enables seamless dynamic loading, unloading, and registration of Lua functions using Rust. Built with the mlua crate, this interface supports dynamic libraries for modular and extensible plugin development. ## Features * **Dynamic Plugin Loading**: Load plugins from shared libraries ( `.dll` , `.so` , `.dylib` ) at runtime. * **Plugin Interface**: Define and implement plugins with a common trait ( `PluginLua` ) to ensure consistent behavior. * **Lua Function Registration**: Automatically register Lua functions exposed by plugins into the Lua runtime. * **Lifecycle Management**: Manage plugin initialization ( `on_load` ) and cleanup ( `on_unload` ) seamlessly. * **Logging**: Integrated with `tracing` for structured logs during plugin operations. ## How It Works 1. **Trait Definition**: Each plugin implements the `PluginLua` trait to define its behavior and expose Lua functions. 2. **Plugin Manager**: The `PluginManager` structure handles loading plugins, maintaining references to them, and ensuring they are correctly initialized and cleaned up. 3. **Dynamic Libraries**: Plugins are compiled as shared libraries and loaded dynamically at runtime using the `libloading` crate. 4. **Lua Integration**: Functions provided by plugins are registered into the Lua runtime and made accessible for scripting. ## Usage ### Define a Plugin To create a plugin, implement the `PluginLua` trait and define Lua functions: ```rust use mlua::{Function, Lua}; use plugin_interface::{export_plugin, PluginLua}; use std::collections::HashMap; pub struct MyPlugin; impl PluginLua for MyPlugin { fn name(&self) -> &str { "my_plugin" } fn on_load(&mut self) -> Result<(), Box> { println!("MyPlugin loaded!"); Ok(()) } fn on_unload(&mut self) -> Result<(), Box> { println!("MyPlugin unloaded!"); Ok(()) } fn get_lua_functions(&self, lua: &Lua) -> HashMap { let mut functions = HashMap::new(); functions.insert( "hello".to_string(), lua.create_function(|_, name: String| { println!("Hello, {}!", name); Ok(()) }).unwrap(), ); functions } } export_plugin!(MyPlugin); ``` ### Load a Plugin Use the `PluginManager` to load, unload, and manage plugins: ```rust use plugin_manager::PluginManager; use mlua::Lua; fn main() -> Result<(), Box> { let lua = Lua::new(); let mut manager = PluginManager::new(); // Load a plugin from a shared library manager.load_plugin("path/to/plugin.dll")?; // Register plugin functions with Lua manager.register_all_plugins(&lua)?; // Unload the plugin manager.unload_plugin("my_plugin")?; Ok(()) } ``` ## Safety Considerations * **Dynamic Loading**: Uses `unsafe` blocks to load and interact with shared libraries. Ensure plugins are trusted and well-tested. * **Thread Safety**: Plugins must be thread-safe ( `Send + Sync` ) to avoid undefined behavior in multithreaded contexts. ## Dependencies * [`mlua`](https://crates.io/crates/mlua): For Lua integration. * [`libloading`](https://crates.io/crates/libloading): For dynamic library loading. * [`tracing`](https://crates.io/crates/tracing): For structured logging. ## License This project is licensed under the MIT License.