use crate::*;
pub struct PluginRef<'a> {
pub id: PluginIndex,
pub(crate) epoch_timer_tx: std::sync::mpsc::SyncSender<TimerAction>,
plugin: *mut Plugin,
_t: std::marker::PhantomData<&'a ()>,
}
impl<'a> PluginRef<'a> {
pub fn init(mut self, data: *const u8, data_len: usize) -> Self {
trace!("PluginRef::init: {}", self.id,);
self.as_mut().memory.reset();
self.as_mut().set_input(data, data_len);
self
}
pub fn new(ctx: &'a mut Context, plugin_id: PluginIndex, clear_error: bool) -> Option<Self> {
trace!("Loading plugin {plugin_id}");
let epoch_timer_tx = ctx.epoch_timer_tx.clone();
if !ctx.plugin_exists(plugin_id) {
error!("Plugin does not exist: {plugin_id}");
return ctx.error(format!("Plugin does not exist: {plugin_id}"), None);
}
if clear_error {
trace!("Clearing context error");
ctx.error = None;
}
let plugin = ctx.plugin(plugin_id).unwrap();
{
let plugin = unsafe { &mut *plugin };
if clear_error {
trace!("Clearing plugin error: {plugin_id}");
plugin.clear_error();
}
if plugin.should_reinstantiate {
plugin.should_reinstantiate = false;
if let Err(e) = plugin.reinstantiate() {
error!("Failed to reinstantiate: {e:?}");
return plugin.error(format!("Failed to reinstantiate: {e:?}"), None);
}
}
}
Some(PluginRef {
id: plugin_id,
plugin,
epoch_timer_tx,
_t: std::marker::PhantomData,
})
}
}
impl<'a> AsRef<Plugin> for PluginRef<'a> {
fn as_ref(&self) -> &Plugin {
unsafe { &*self.plugin }
}
}
impl<'a> AsMut<Plugin> for PluginRef<'a> {
fn as_mut(&mut self) -> &mut Plugin {
unsafe { &mut *self.plugin }
}
}
impl<'a> Drop for PluginRef<'a> {
fn drop(&mut self) {
trace!("Dropping PluginRef {}", self.id);
}
}