Added PluginContext
This commit is contained in:
@@ -21,14 +21,14 @@ pub struct ConfigPlugins {
|
||||
|
||||
impl Config {
|
||||
pub fn new(path: &Path) -> Result<Self, ConfigError> {
|
||||
let path = path.join("main.toml");
|
||||
let cfg_path = path.join("main.toml");
|
||||
|
||||
if !path.exists() {
|
||||
if !cfg_path.exists() {
|
||||
println!("ERROR: {:?} doesnt exist", path);
|
||||
}
|
||||
|
||||
let mut cfg: Self = toml::from_str(
|
||||
&std::fs::read_to_string(&path)?
|
||||
&std::fs::read_to_string(&cfg_path)?
|
||||
)?;
|
||||
|
||||
cfg.config_dir = path.to_path_buf();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#![allow(internal_features)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::{process::ExitCode, time::Duration};
|
||||
|
||||
use std::{ffi::c_char, process::ExitCode, time::Duration};
|
||||
use clap::Parser;
|
||||
|
||||
mod display;
|
||||
mod plugman;
|
||||
mod config;
|
||||
mod util;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
struct CliArgs {
|
||||
@@ -19,6 +19,8 @@ struct CliArgs {
|
||||
pub debug: bool
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type c_str = *const c_char;
|
||||
|
||||
// TODO: Clean up main function
|
||||
// TODO: Make ffi safe abstraction for logger
|
||||
@@ -57,7 +59,7 @@ fn main() -> ExitCode {
|
||||
return ExitCode::from(3);
|
||||
}
|
||||
|
||||
pm.init_plugins();
|
||||
pm.init_plugins(&config);
|
||||
|
||||
loop {
|
||||
let vals = pm.poll_plugins();
|
||||
|
||||
@@ -49,9 +49,9 @@ impl PlugMan {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn init_plugins(&mut self) {
|
||||
pub fn init_plugins(&mut self, cfg: &crate::config::Config) {
|
||||
for plugin in &self.plugins {
|
||||
plugin.init();
|
||||
plugin.init(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
31
src/plugman/plugin/context.rs
Normal file
31
src/plugman/plugin/context.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
use std::ffi::{c_char, CString};
|
||||
|
||||
pub struct PluginContextContainer {
|
||||
pub inner: PluginContext,
|
||||
_config_dir: CString
|
||||
}
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
pub struct PluginContext {
|
||||
pub config_dir: *const c_char
|
||||
}
|
||||
|
||||
impl PluginContext {
|
||||
pub fn new(config_dir: &CString) -> Self {
|
||||
Self {
|
||||
config_dir: config_dir.as_ptr()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl PluginContextContainer {
|
||||
pub fn new(config_dir: &String) -> Self {
|
||||
let _config_dir = CString::new(config_dir.clone()).unwrap();
|
||||
Self {
|
||||
inner: PluginContext::new(&_config_dir),
|
||||
_config_dir,
|
||||
}
|
||||
}
|
||||
}
|
||||
42
src/plugman/plugin/loader.rs
Normal file
42
src/plugman/plugin/loader.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
use std::ffi::c_char;
|
||||
|
||||
use dlopen::raw::Library;
|
||||
|
||||
use super::{context::PluginContext, Plugin, PluginInfo};
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct PluginSyms {
|
||||
pub(super) init: unsafe extern "C" fn(ctx: *const PluginContext),
|
||||
pub(super) pre_reload: unsafe extern "C" fn() -> *const (),
|
||||
pub(super) post_reload: unsafe extern "C" fn(state: *const ()),
|
||||
pub(super) poll: unsafe extern "C" fn(buf: *mut c_char, len: usize),
|
||||
pub(super) free: unsafe extern "C" fn(),
|
||||
pub(super) get_info: unsafe extern "C" fn() -> *const PluginInfo,
|
||||
}
|
||||
|
||||
impl Plugin {
|
||||
pub fn reload_symbols(&mut self) -> Result<(), dlopen::Error> {
|
||||
log::debug!("Loading {:?}", self.path);
|
||||
let lib = Library::open(&self.path)?;
|
||||
let symbols = PluginSyms {
|
||||
init: unsafe { lib.symbol("plug_init")? },
|
||||
pre_reload: unsafe { lib.symbol("plug_pre_reload")? },
|
||||
post_reload: unsafe { lib.symbol("plug_post_reload")? },
|
||||
poll: unsafe { lib.symbol("plug_poll")? },
|
||||
free: unsafe { lib.symbol("plug_free")? },
|
||||
|
||||
get_info: unsafe { lib.symbol("plug_get_info")? },
|
||||
};
|
||||
unsafe {
|
||||
if (symbols.get_info)().is_null() {
|
||||
log::error!("Info fields for plugin {:?} are null", self.path);
|
||||
self.disable();
|
||||
}
|
||||
}
|
||||
|
||||
self.syms = Some(symbols);
|
||||
self.lib = Some(lib);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2,32 +2,30 @@ use std::{alloc::Layout, ffi::{c_char, CStr}, path::PathBuf};
|
||||
|
||||
use dlopen::raw::Library;
|
||||
|
||||
#[derive(Debug, Clone, Copy,)]
|
||||
pub struct PluginSyms {
|
||||
init: unsafe extern "C" fn(),
|
||||
pre_reload: unsafe extern "C" fn() -> *const (),
|
||||
post_reload: unsafe extern "C" fn(state: *const ()),
|
||||
poll: unsafe extern "C" fn(buf: *mut i8, len: usize),
|
||||
free: unsafe extern "C" fn(),
|
||||
get_info: unsafe extern "C" fn() -> *const PluginInfo,
|
||||
}
|
||||
use crate::{c_str, config::Config};
|
||||
|
||||
use self::context::{PluginContext, PluginContextContainer};
|
||||
|
||||
pub mod loader;
|
||||
pub mod context;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct PluginInfo {
|
||||
name: *const c_char,
|
||||
version: *const c_char,
|
||||
license: *const c_char,
|
||||
name: c_str,
|
||||
version: c_str,
|
||||
license: c_str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Plugin {
|
||||
syms: Option<PluginSyms>,
|
||||
syms: Option<loader::PluginSyms>,
|
||||
path: PathBuf,
|
||||
lib: Option<Library>,
|
||||
enabled: bool,
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl Plugin {
|
||||
pub fn load(path: PathBuf) -> Result<Self, dlopen::Error> {
|
||||
let mut s = Self::default();
|
||||
@@ -36,37 +34,17 @@ impl Plugin {
|
||||
s.reload_symbols()?;
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
fn reload_symbols(&mut self) -> Result<(), dlopen::Error> {
|
||||
log::debug!("Loading {:?}", self.path);
|
||||
let lib = Library::open(&self.path)?;
|
||||
let symbols = PluginSyms {
|
||||
init: unsafe { lib.symbol("plug_init")? },
|
||||
pre_reload: unsafe { lib.symbol("plug_pre_reload")? },
|
||||
post_reload: unsafe { lib.symbol("plug_post_reload")? },
|
||||
poll: unsafe { lib.symbol("plug_poll")? },
|
||||
free: unsafe { lib.symbol("plug_free")? },
|
||||
|
||||
get_info: unsafe { lib.symbol("plug_get_info")? },
|
||||
};
|
||||
unsafe {
|
||||
if (symbols.get_info)().is_null() {
|
||||
log::error!("Info fields for plugin {:?} are null", self.path);
|
||||
self.disable();
|
||||
}
|
||||
}
|
||||
|
||||
self.syms = Some(symbols);
|
||||
self.lib = Some(lib);
|
||||
Ok(())
|
||||
}
|
||||
pub fn syms(&self) -> PluginSyms {
|
||||
|
||||
pub fn syms(&self) -> loader::PluginSyms {
|
||||
self.syms.unwrap()
|
||||
}
|
||||
|
||||
pub fn init(&self) {
|
||||
pub fn init(&self, cfg: &Config) {
|
||||
unsafe {
|
||||
(self.syms().init)()
|
||||
let conf_dir = &cfg.config_dir.join(self.name()).to_string_lossy().to_string();
|
||||
|
||||
let ctx = PluginContextContainer::new(conf_dir);
|
||||
(self.syms().init)(&ctx.inner as *const PluginContext)
|
||||
}
|
||||
}
|
||||
pub fn reload(&mut self) -> Result<(), dlopen::Error> {
|
||||
0
src/util.rs
Normal file
0
src/util.rs
Normal file
Reference in New Issue
Block a user