96 lines
2.9 KiB
Rust
96 lines
2.9 KiB
Rust
mod utils;
|
|
use crate::{config::Config, errors::PluginError};
|
|
use abi_stable::{
|
|
external_types::crossbeam_channel::{self, RReceiver, RSender},
|
|
library::{lib_header_from_path, LibraryError, LibrarySuffix, RawLibrary},
|
|
sabi_trait::prelude::TD_Opaque,
|
|
std_types::{RBox, RErr, ROk, RResult, RSome, RStr, RString, RVec},
|
|
};
|
|
use core_extensions::*;
|
|
use radarg_plugin_interface::{Plugin, PluginId, PluginMod_Ref, Plugin_TO};
|
|
use std::{
|
|
collections::{HashMap, VecDeque},
|
|
io, mem,
|
|
path::{Path, PathBuf},
|
|
sync::{Arc, Mutex},
|
|
};
|
|
|
|
fn compute_plugin_path(base_name: &str) -> io::Result<PathBuf> {
|
|
let debug_dir = "./etws_loader/target/debug"
|
|
.as_ref_::<Path>()
|
|
.into_::<PathBuf>();
|
|
let release_dir = "./etws_loader/target/release"
|
|
.as_ref_::<Path>()
|
|
.into_::<PathBuf>();
|
|
|
|
let debug_path = RawLibrary::path_in_directory(&debug_dir, base_name, LibrarySuffix::NoSuffix);
|
|
|
|
let release_path =
|
|
RawLibrary::path_in_directory(&release_dir, base_name, LibrarySuffix::NoSuffix);
|
|
|
|
match (debug_path.exists(), release_path.exists()) {
|
|
(false, false) => debug_path,
|
|
(true, false) => debug_path,
|
|
(false, true) => release_path,
|
|
(true, true) => {
|
|
if debug_path.metadata()?.modified()? < release_path.metadata()?.modified()? {
|
|
release_path
|
|
} else {
|
|
debug_path
|
|
}
|
|
}
|
|
}
|
|
.piped(Ok)
|
|
}
|
|
|
|
pub fn init_plugin(
|
|
base_name: impl AsRef<str>,
|
|
) -> Result<(PluginId, Plugin_TO<'static, RBox<()>>), PluginError> {
|
|
let library_path: PathBuf = compute_plugin_path(base_name.as_ref())?;
|
|
let res = (|| {
|
|
let header = lib_header_from_path(&library_path)?;
|
|
header.init_root_module::<PluginMod_Ref>()
|
|
})()?;
|
|
|
|
let plugin_constructor = res.new();
|
|
let new_id = PluginId {
|
|
named: base_name.as_ref().to_owned().into(),
|
|
instance: 0,
|
|
};
|
|
|
|
let plugin = plugin_constructor(new_id.clone()).unwrap();
|
|
|
|
Ok((new_id, plugin))
|
|
}
|
|
|
|
pub struct PluginManager {
|
|
registered_plugins: HashMap<PluginId, Plugin_TO<'static, RBox<()>>>,
|
|
}
|
|
|
|
impl PluginManager {
|
|
pub fn new() -> Result<Self, PluginError> {
|
|
use crate::CONFIG;
|
|
let mut this = Self {
|
|
registered_plugins: HashMap::new(),
|
|
};
|
|
for (plugin_name, config) in CONFIG.lock().unwrap().plugins.iter() {
|
|
if let Ok((id, p)) = init_plugin(plugin_name.to_owned()) {
|
|
println!("Loaded plugin: {}", plugin_name);
|
|
this.registered_plugins.insert(id, p);
|
|
}
|
|
}
|
|
Ok(this)
|
|
}
|
|
|
|
pub fn get_plugin(&self, id: &PluginId) -> Option<&Plugin_TO<'static, RBox<()>>> {
|
|
self.registered_plugins.get(id)
|
|
}
|
|
|
|
pub fn get_plugin_by_name(&self, name: &str) -> Option<&Plugin_TO<'static, RBox<()>>> {
|
|
self.registered_plugins
|
|
.iter()
|
|
.find(|(id, _)| id.named == name)
|
|
.map(|(_, p)| p)
|
|
}
|
|
}
|