1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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 dyn 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
)
}
}