pub mod process;
pub mod thread;
use crate::{
common::{
error::{err, Result},
log::thread::LogThread,
protocol::{
PluginAcceptUpstreamRequest, PluginInitializeRequest, PluginInitializeResponse,
PluginToSimulator, PluginUserInitializeRequest, SimulatorToPlugin,
},
types::{ArbCmd, ArbData, PluginType},
},
host::configuration::PluginLogConfiguration,
};
use std::fmt::Debug;
#[macro_export]
macro_rules! checked_rpc {
($plugin:expr, $message:expr, expect $t:ident) => {
match $plugin.rpc($message.into()) {
Ok(PluginToSimulator::$t(x)) => Ok(x),
Ok(PluginToSimulator::Failure(e)) => err(e),
Ok(_) => err("Protocol error: unexpected response from plugin"),
Err(e) => Err(e),
}
};
($plugin:expr, $message:expr) => {
match $plugin.rpc($message.into()) {
Ok(PluginToSimulator::Success) => Ok(()),
Ok(PluginToSimulator::Failure(e)) => err(e),
Ok(_) => err("Protocol error: unexpected response from plugin"),
Err(e) => Err(e),
}
};
}
pub trait Plugin: Debug {
fn spawn(&mut self, logger: &LogThread) -> Result<()>;
fn plugin_type(&self) -> PluginType;
fn init_cmds(&self) -> Vec<ArbCmd>;
fn log_configuration(&self) -> PluginLogConfiguration;
fn rpc(&mut self, msg: SimulatorToPlugin) -> Result<PluginToSimulator>;
}
impl Plugin {
pub fn name(&self) -> String {
self.log_configuration().name
}
pub fn initialize(
&mut self,
logger: &LogThread,
downstream: &Option<String>,
seed: u64,
) -> Result<PluginInitializeResponse> {
checked_rpc!(
self,
PluginInitializeRequest {
downstream: downstream.clone(),
plugin_type: self.plugin_type(),
seed,
log_configuration: self.log_configuration(),
log_channel: logger.get_ipc_sender(),
},
expect Initialized
)
}
pub fn accept_upstream(&mut self) -> Result<()> {
checked_rpc!(self, PluginAcceptUpstreamRequest)
}
pub fn user_initialize(&mut self) -> Result<()> {
checked_rpc!(
self,
PluginUserInitializeRequest {
init_cmds: self.init_cmds()
}
)
}
pub fn arb(&mut self, cmd: impl Into<ArbCmd>) -> Result<ArbData> {
checked_rpc!(
self,
cmd.into(),
expect ArbResponse
)
}
}