-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathjs_py.rs
106 lines (94 loc) · 3.44 KB
/
js_py.rs
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
//! Generates the initial state from a provided JavaScript or Python script.
mod message;
mod task;
use async_trait::async_trait;
use stateful::{agent::Agent, field::FieldSpecMapAccessor};
pub use self::{
message::{FailedMessage, JsPyInitTaskMessage, StartMessage, SuccessMessage},
task::{TsInitTask, JsInitTask, PyInitTask},
};
use crate::{
package::simulation::{
init::{
InitPackage, InitPackageCreator, InitTask, InitTaskMessage, InitialState,
InitialStateName,
},
MaybeCpuBound, Package, PackageComms, PackageCreator, PackageCreatorConfig,
PackageInitConfig, PackageTask,
},
task::{TaskMessage, TaskSharedStore},
Error, Result,
};
pub struct JsPyInit {
initial_state: InitialState,
comms: PackageComms,
}
impl MaybeCpuBound for JsPyInit {
fn cpu_bound(&self) -> bool {
false
}
}
impl Package for JsPyInit {}
#[async_trait]
impl InitPackage for JsPyInit {
async fn run(&mut self) -> Result<Vec<Agent>> {
let task = match &self.initial_state.name {
InitialStateName::InitPy => InitTask::PyInitTask(PyInitTask {
initial_state_source: self.initial_state.src.clone(),
}),
InitialStateName::InitJs => InitTask::JsInitTask(JsInitTask {
initial_state_source: self.initial_state.src.clone(),
}),
InitialStateName::InitTs => InitTask::TsInitTask(TsInitTask {
initial_state_source: self.initial_state.src.clone(),
}),
name => {
// should be unreachable
return Err(Error::from(format!(
"Trying to run an init package for JS/Py but the init source wasn't .js or \
.py but instead was: {:?}",
name
)));
}
};
let shared_store = TaskSharedStore::default();
let active_task = self
.comms
.new_task(PackageTask::Init(task), shared_store)
.await?;
let task_message = match active_task.drive_to_completion().await? {
TaskMessage::Init(InitTaskMessage::JsPyInitTaskMessage(message)) => message,
_ => return Err(Error::from("Not a JsPyInitTaskMessage")),
};
match task_message {
JsPyInitTaskMessage::Success(SuccessMessage { agents }) => Ok(agents),
_ => Err(Error::from("Init Task failed")),
}
}
}
pub struct JsPyInitCreator;
impl PackageCreator for JsPyInitCreator {
// TODO: Since the init.js/py file is the same for the whole experiment consider sending it out
// here instead of inside `PyInitTask` and `JsInitTask`
}
impl InitPackageCreator for JsPyInitCreator {
fn create(
&self,
_config: &PackageCreatorConfig,
init_config: &PackageInitConfig,
comms: PackageComms,
_accessor: FieldSpecMapAccessor,
) -> Result<Box<dyn InitPackage>> {
match &init_config.initial_state.name {
InitialStateName::InitPy | InitialStateName::InitJs | InitialStateName::InitTs => Ok(Box::new(JsPyInit {
initial_state: init_config.initial_state.clone(),
comms,
})),
name => Err(Error::from(format!(
"Trying to create a JS/Python init package but the initial state source didn't \
end in '.js' or '.py': {:?}",
name
))),
}
}
}