use rand::rngs::StdRng;
use rand::SeedableRng;
use rustsim_core::{
collect::collect_step,
prelude::{Agent, AgentStore, Fastest, HashMapStore, StandardModel, Time},
standard::HasAgentIds,
types::AgentId,
};
mod support;
use support::NothingSpace;
#[derive(Debug, Clone)]
struct CounterAgent {
id: AgentId,
value: i32,
}
impl Agent for CounterAgent {
fn id(&self) -> AgentId {
self.id
}
}
type CounterModel =
StandardModel<NothingSpace, CounterAgent, HashMapStore<CounterAgent>, (), StdRng, Fastest>;
fn counter_step(
agent: &mut CounterAgent,
_ctx: &mut rustsim_core::step_context::StepContext<
'_,
NothingSpace,
CounterAgent,
(),
StdRng,
Fastest,
>,
) {
agent.value += 1;
}
#[derive(Debug, Clone, PartialEq)]
struct AgentSnapshot {
time: Time,
id: AgentId,
value: i32,
}
#[derive(Debug, Clone, PartialEq)]
struct ModelSnapshot {
time: Time,
agent_count: usize,
}
#[test]
fn collect_agent_and_model_data_across_steps() {
let mut store = HashMapStore::new();
store.insert(CounterAgent { id: 1, value: 0 });
store.insert(CounterAgent { id: 2, value: 10 });
let mut model = CounterModel::new(
store,
NothingSpace,
Fastest::new(),
(),
StdRng::seed_from_u64(0),
Some(Box::new(counter_step)),
None,
true,
);
let agent_report = |agent: &CounterAgent, model: &CounterModel| AgentSnapshot {
time: model.time(),
id: agent.id(),
value: agent.value,
};
let model_report = |model: &CounterModel| ModelSnapshot {
time: model.time(),
agent_count: model.agent_ids().len(),
};
let mut agent_data: Vec<AgentSnapshot> = Vec::new();
let mut model_data: Vec<ModelSnapshot> = Vec::new();
let ids: Vec<AgentId> = model.agent_ids();
collect_step(
&model,
&ids,
Some(&agent_report),
Some(&model_report),
&mut agent_data,
&mut model_data,
);
assert_eq!(agent_data.len(), 2);
assert_eq!(model_data.len(), 1);
assert_eq!(model_data[0].agent_count, 2);
assert_eq!(model_data[0].time, Time::Discrete(0));
model.step();
let ids: Vec<AgentId> = model.agent_ids();
collect_step(
&model,
&ids,
Some(&agent_report),
Some(&model_report),
&mut agent_data,
&mut model_data,
);
assert_eq!(agent_data.len(), 4);
assert_eq!(model_data.len(), 2);
assert_eq!(model_data[1].time, Time::Discrete(1));
let post_step: Vec<_> = agent_data[2..].to_vec();
for snap in &post_step {
assert_eq!(snap.time, Time::Discrete(1));
assert!(snap.value > 0);
}
}