use glob::glob; use hotload_plugin::HotloadPluginInfo; use std::env::current_exe; use std::path::PathBuf; pub struct Plugin { library: libloading::Library, } impl Plugin { pub fn new(library: libloading::Library) -> Self { Self { library } } pub fn get_info(&self) -> Result { let get_info_fn: libloading::Symbol *const HotloadPluginInfo> = unsafe { self.library .get(b"plugin_info\0") .map_err(|e| format!("{}", e))? }; let info = get_info_fn(); if info.is_null() { return Err(String::from("get_info function returned null")); } Ok(unsafe { (*info).clone() }) } } pub struct PluginManager { pub plugins: Vec, } impl PluginManager { pub fn new() -> PluginManager { println!("Loading librairies..."); let mut plugins = Vec::new(); let current_path = current_exe().unwrap(); let parent_path = current_path.parent().unwrap(); let lib_folder = parent_path.join("*.so"); for lib_file in glob(lib_folder.to_str().unwrap()).unwrap() { let plugin = Self::load_library(lib_file.unwrap()); plugins.push(plugin); } PluginManager { plugins } } fn load_library(lib_file: PathBuf) -> Plugin { println!("Loading library {:?}", lib_file.file_name().unwrap()); unsafe { let lib = libloading::Library::new(lib_file).unwrap(); Plugin::new(lib) } } }