use crate::memoize::*;
use crate::reactions::*;
use crate::utilities::*;
use std::cell::RefCell;
use std::marker::PhantomData;
use std::rc::Rc;
pub enum Instances {
Singleton,
Count(usize),
}
pub trait AgentInstances<StateId: IndexLike, Payload: DataLike>: Name {
fn prev_agent_type(&self) -> Option<Rc<dyn AgentType<StateId, Payload>>>;
fn first_index(&self) -> usize;
fn next_index(&self) -> usize;
fn is_singleton(&self) -> bool;
fn instances_count(&self) -> usize;
fn instance_order(&self, instance: usize) -> usize;
fn display_state(&self, state_id: StateId) -> Rc<String>;
fn terse_id(&self, state_id: StateId) -> StateId;
fn display_terse(&self, name_id: StateId) -> String;
}
pub trait AgentType<StateId: IndexLike, Payload: DataLike>:
AgentInstances<StateId, Payload>
{
fn reaction(
&self,
instance: usize,
state_ids: &[StateId],
payload: &Payload,
) -> Reaction<StateId, Payload>;
fn activity(&self, instance: usize, state_ids: &[StateId]) -> Activity<Payload>;
fn state_is_deferring(&self, instance: usize, state_ids: &[StateId]) -> bool;
fn state_invalid_because(&self, instance: usize, state_ids: &[StateId])
-> Option<&'static str>;
fn state_max_in_flight_messages(&self, instance: usize, state_ids: &[StateId])
-> Option<usize>;
fn states_count(&self) -> usize;
fn compute_terse(&self);
}
pub trait PartType<State: DataLike, StateId: IndexLike> {
fn part_state_by_id(&self, state_id: StateId) -> State;
fn part_first_index(&self) -> usize;
fn parts_count(&self) -> usize;
}
pub struct AgentTypeData<State: DataLike, StateId: IndexLike, Payload: DataLike> {
states: RefCell<Memoize<State, StateId>>,
first_index: usize,
name: &'static str,
is_singleton: bool,
label_of_state: RefCell<Vec<Rc<String>>>,
terse_of_state: RefCell<Vec<StateId>>,
name_of_terse: RefCell<Vec<String>>,
order_of_instances: Vec<usize>,
prev_agent_type: Option<Rc<dyn AgentType<StateId, Payload>>>,
_payload: PhantomData<Payload>,
}
pub struct ContainerOf1TypeData<
State: DataLike,
Part: DataLike,
StateId: IndexLike,
Payload: DataLike,
const MAX_PARTS: usize,
> {
agent_type_data: AgentTypeData<State, StateId, Payload>,
part_type: Rc<dyn PartType<Part, StateId>>,
}
pub struct ContainerOf2TypeData<
State: DataLike,
Part1: DataLike,
Part2: DataLike,
StateId: IndexLike,
Payload: DataLike,
const MAX_PARTS: usize,
> {
agent_type_data: AgentTypeData<State, StateId, Payload>,
part1_type: Rc<dyn PartType<Part1, StateId>>,
part2_type: Rc<dyn PartType<Part2, StateId>>,
}
impl<State: DataLike, StateId: IndexLike, Payload: DataLike>
AgentTypeData<State, StateId, Payload>
{
pub fn new(
name: &'static str,
instances: Instances,
prev_agent_type: Option<Rc<dyn AgentType<StateId, Payload>>>,
) -> Self {
let (is_singleton, count) = match instances {
Instances::Singleton => (true, 1),
Instances::Count(amount) => {
assert!(
amount > 0,
"zero instances specified for agent type {}",
name
);
(false, amount)
}
};
let default_state: State = Default::default();
let mut states = Memoize::new(StateId::invalid().to_usize());
states.store(default_state);
let label_of_state = RefCell::new(vec![]);
label_of_state
.borrow_mut()
.push(Rc::new(format!("{}", default_state)));
let order_of_instances = vec![0; count];
Self {
name,
order_of_instances,
is_singleton,
label_of_state,
terse_of_state: RefCell::new(vec![]),
name_of_terse: RefCell::new(vec![]),
states: RefCell::new(states),
first_index: prev_agent_type
.clone()
.map_or(0, |agent_type| agent_type.next_index()),
prev_agent_type,
_payload: PhantomData,
}
}
pub fn set_order(&mut self, instance: usize, order: usize) {
assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count()
);
self.order_of_instances[instance] = order;
}
fn impl_compute_terse(&self) {
let mut terse_of_state = self.terse_of_state.borrow_mut();
let mut name_of_terse = self.name_of_terse.borrow_mut();
assert!(terse_of_state.is_empty());
assert!(name_of_terse.is_empty());
let states = self.states.borrow();
terse_of_state.reserve(states.len());
name_of_terse.reserve(states.len());
for state_id in 0..states.len() {
let state = states.get(StateId::from_usize(state_id));
let state_name = state.name();
if let Some(terse_id) = name_of_terse
.iter()
.position(|terse_name| terse_name == &state_name)
{
terse_of_state.push(StateId::from_usize(terse_id));
} else {
terse_of_state.push(StateId::from_usize(name_of_terse.len()));
name_of_terse.push(state_name);
}
}
name_of_terse.shrink_to_fit();
}
pub fn get_state(&self, state_id: StateId) -> State {
self.states.borrow().get(state_id)
}
}
impl<
State: DataLike,
Part: DataLike,
StateId: IndexLike,
Payload: DataLike,
const MAX_PARTS: usize,
> ContainerOf1TypeData<State, Part, StateId, Payload, MAX_PARTS>
{
pub fn new(
name: &'static str,
instances: Instances,
part_type: Rc<dyn PartType<Part, StateId>>,
prev_type: Rc<dyn AgentType<StateId, Payload>>,
) -> Self {
Self {
agent_type_data: AgentTypeData::new(name, instances, Some(prev_type)),
part_type,
}
}
}
impl<
State: DataLike,
Part1: DataLike,
Part2: DataLike,
StateId: IndexLike,
Payload: DataLike,
const MAX_PARTS: usize,
> ContainerOf2TypeData<State, Part1, Part2, StateId, Payload, MAX_PARTS>
{
pub fn new(
name: &'static str,
instances: Instances,
part1_type: Rc<dyn PartType<Part1, StateId>>,
part2_type: Rc<dyn PartType<Part2, StateId>>,
prev_type: Rc<dyn AgentType<StateId, Payload>>,
) -> Self {
Self {
agent_type_data: AgentTypeData::new(name, instances, Some(prev_type)),
part1_type,
part2_type,
}
}
}
impl<State: DataLike, StateId: IndexLike, Payload: DataLike> PartType<State, StateId>
for AgentTypeData<State, StateId, Payload>
{
fn part_state_by_id(&self, state_id: StateId) -> State {
self.states.borrow().get(state_id)
}
fn part_first_index(&self) -> usize {
self.first_index
}
fn parts_count(&self) -> usize {
self.instances_count()
}
}
pub trait AgentState<State: DataLike, Payload: DataLike> {
fn reaction(&self, instance: usize, payload: &Payload) -> Reaction<State, Payload>;
fn activity(&self, _instance: usize) -> Activity<Payload> {
Activity::Passive
}
fn is_deferring(&self, _instance: usize) -> bool {
false
}
fn invalid_because(&self, _instance: usize) -> Option<&'static str> {
None
}
fn max_in_flight_messages(&self, _instance: usize) -> Option<usize> {
None
}
}
pub trait ContainerOf1State<State: DataLike, Part: DataLike, Payload: DataLike> {
fn reaction(
&self,
instance: usize,
payload: &Payload,
parts: &[Part],
) -> Reaction<State, Payload>;
fn activity(&self, _instance: usize, _parts: &[Part]) -> Activity<Payload> {
Activity::Passive
}
fn is_deferring(&self, _instance: usize, _parts: &[Part]) -> bool {
false
}
fn invalid_because(&self, _instance: usize, _parts: &[Part]) -> Option<&'static str> {
None
}
fn max_in_flight_messages(&self, _instance: usize, _parts: &[Part]) -> Option<usize> {
None
}
}
pub trait ContainerOf2State<State: DataLike, Part1: DataLike, Part2: DataLike, Payload: DataLike> {
fn reaction(
&self,
instance: usize,
payload: &Payload,
parts1: &[Part1],
parts2: &[Part2],
) -> Reaction<State, Payload>;
fn activity(
&self,
_instance: usize,
_parts1: &[Part1],
_parts2: &[Part2],
) -> Activity<Payload> {
Activity::Passive
}
fn is_deferring(&self, _instance: usize, _parts1: &[Part1], _parts2: &[Part2]) -> bool {
false
}
fn invalid_because(
&self,
_instance: usize,
_parts1: &[Part1],
_parts2: &[Part2],
) -> Option<&'static str> {
None
}
fn max_in_flight_messages(
&self,
_instance: usize,
_parts1: &[Part1],
_parts2: &[Part2],
) -> Option<usize> {
None
}
}
impl<State: DataLike, StateId: IndexLike, Payload: DataLike>
AgentTypeData<State, StateId, Payload>
{
fn translate_reaction(
&self,
reaction: &Reaction<State, Payload>,
) -> Reaction<StateId, Payload> {
match reaction {
Reaction::Unexpected => Reaction::Unexpected,
Reaction::Ignore => Reaction::Ignore,
Reaction::Defer => Reaction::Defer,
Reaction::Do1(action) => Reaction::Do1(self.translate_action(action)),
Reaction::Do1Of(actions) => Reaction::Do1Of(self.translate_actions(&actions)), }
}
fn translate_action(&self, action: &Action<State, Payload>) -> Action<StateId, Payload> {
match *action {
Action::Defer => Action::Defer,
Action::Ignore => Action::Ignore, Action::Change(state) => Action::Change(self.translate_state(state)),
Action::Send1(emit) => Action::Send1(emit),
Action::ChangeAndSend1(state, emit) => {
Action::ChangeAndSend1(self.translate_state(state), emit)
}
Action::Sends(emits) => Action::Sends(emits), Action::ChangeAndSends(state, emits) => {
Action::ChangeAndSends(self.translate_state(state), emits)
}
}
}
fn translate_actions(
&self,
actions: &[Option<Action<State, Payload>>; MAX_COUNT],
) -> [Option<Action<StateId, Payload>>; MAX_COUNT] {
let mut translated_actions: [Option<Action<StateId, Payload>>; MAX_COUNT] =
[None; MAX_COUNT];
for (maybe_action, maybe_translated) in actions.iter().zip(translated_actions.iter_mut()) {
*maybe_translated = maybe_action
.as_ref()
.map(|action| self.translate_action(action));
}
translated_actions
}
fn translate_state(&self, state: State) -> StateId {
let stored = self.states.borrow_mut().store(state);
if stored.is_new {
debug_assert!(self.label_of_state.borrow().len() == stored.id.to_usize());
self.label_of_state
.borrow_mut()
.push(Rc::new(format!("{}", state)));
}
stored.id
}
}
impl<State: DataLike, StateId: IndexLike, Payload: DataLike> Name
for AgentTypeData<State, StateId, Payload>
{
fn name(&self) -> String {
self.name.to_string()
}
}
impl<
State: DataLike,
Part: DataLike,
StateId: IndexLike,
Payload: DataLike,
const MAX_PARTS: usize,
> Name for ContainerOf1TypeData<State, Part, StateId, Payload, MAX_PARTS>
{
fn name(&self) -> String {
self.agent_type_data.name()
}
}
impl<
State: DataLike,
Part1: DataLike,
Part2: DataLike,
StateId: IndexLike,
Payload: DataLike,
const MAX_PARTS: usize,
> Name for ContainerOf2TypeData<State, Part1, Part2, StateId, Payload, MAX_PARTS>
{
fn name(&self) -> String {
self.agent_type_data.name()
}
}
impl<State: DataLike, StateId: IndexLike, Payload: DataLike> AgentInstances<StateId, Payload>
for AgentTypeData<State, StateId, Payload>
{
fn prev_agent_type(&self) -> Option<Rc<dyn AgentType<StateId, Payload>>> {
self.prev_agent_type.clone()
}
fn first_index(&self) -> usize {
self.first_index
}
fn next_index(&self) -> usize {
self.first_index + self.instances_count()
}
fn is_singleton(&self) -> bool {
self.is_singleton
}
fn instances_count(&self) -> usize {
self.order_of_instances.len()
}
fn instance_order(&self, instance: usize) -> usize {
self.order_of_instances[instance]
}
fn display_state(&self, state_id: StateId) -> Rc<String> {
self.label_of_state.borrow()[state_id.to_usize()].clone()
}
fn terse_id(&self, state_id: StateId) -> StateId {
self.terse_of_state.borrow()[state_id.to_usize()]
}
fn display_terse(&self, terse_id: StateId) -> String {
self.name_of_terse.borrow()[terse_id.to_usize()].clone()
}
}
impl<
State: DataLike + ContainerOf1State<State, Part, Payload>,
Part: DataLike + AgentState<Part, Payload>,
StateId: IndexLike,
Payload: DataLike,
const MAX_PARTS: usize,
> AgentInstances<StateId, Payload>
for ContainerOf1TypeData<State, Part, StateId, Payload, MAX_PARTS>
{
fn prev_agent_type(&self) -> Option<Rc<dyn AgentType<StateId, Payload>>> {
self.agent_type_data.prev_agent_type.clone()
}
fn first_index(&self) -> usize {
self.agent_type_data.first_index()
}
fn next_index(&self) -> usize {
self.agent_type_data.next_index()
}
fn is_singleton(&self) -> bool {
self.agent_type_data.is_singleton()
}
fn instances_count(&self) -> usize {
self.agent_type_data.instances_count()
}
fn instance_order(&self, instance: usize) -> usize {
self.agent_type_data.instance_order(instance)
}
fn display_state(&self, state_id: StateId) -> Rc<String> {
self.agent_type_data.display_state(state_id)
}
fn terse_id(&self, state_id: StateId) -> StateId {
self.agent_type_data.terse_id(state_id)
}
fn display_terse(&self, terse_id: StateId) -> String {
self.agent_type_data.display_terse(terse_id)
}
}
impl<
State: DataLike + ContainerOf2State<State, Part1, Part2, Payload>,
Part1: DataLike + AgentState<Part1, Payload>,
Part2: DataLike + AgentState<Part2, Payload>,
StateId: IndexLike,
Payload: DataLike,
const MAX_PARTS: usize,
> AgentInstances<StateId, Payload>
for ContainerOf2TypeData<State, Part1, Part2, StateId, Payload, MAX_PARTS>
{
fn prev_agent_type(&self) -> Option<Rc<dyn AgentType<StateId, Payload>>> {
self.agent_type_data.prev_agent_type.clone()
}
fn first_index(&self) -> usize {
self.agent_type_data.first_index()
}
fn next_index(&self) -> usize {
self.agent_type_data.next_index()
}
fn is_singleton(&self) -> bool {
self.agent_type_data.is_singleton()
}
fn instances_count(&self) -> usize {
self.agent_type_data.instances_count()
}
fn instance_order(&self, instance: usize) -> usize {
self.agent_type_data.instance_order(instance)
}
fn display_state(&self, state_id: StateId) -> Rc<String> {
self.agent_type_data.display_state(state_id)
}
fn terse_id(&self, state_id: StateId) -> StateId {
self.agent_type_data.terse_id(state_id)
}
fn display_terse(&self, terse_id: StateId) -> String {
self.agent_type_data.display_terse(terse_id)
}
}
impl<State: DataLike + AgentState<State, Payload>, StateId: IndexLike, Payload: DataLike>
AgentType<StateId, Payload> for AgentTypeData<State, StateId, Payload>
{
fn reaction(
&self,
instance: usize,
state_ids: &[StateId],
payload: &Payload,
) -> Reaction<StateId, Payload> {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count() );
let state = self
.states
.borrow()
.get(state_ids[self.first_index + instance]);
let reaction = state.reaction(instance, payload);
self.translate_reaction(&reaction)
}
fn activity(&self, instance: usize, state_ids: &[StateId]) -> Activity<Payload> {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count() );
self.states
.borrow()
.get(state_ids[self.first_index + instance])
.activity(instance)
}
fn state_is_deferring(&self, instance: usize, state_ids: &[StateId]) -> bool {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count() );
self.states
.borrow()
.get(state_ids[self.first_index + instance])
.is_deferring(instance)
}
fn state_invalid_because(
&self,
instance: usize,
state_ids: &[StateId],
) -> Option<&'static str> {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count() );
self.states
.borrow()
.get(state_ids[self.first_index + instance])
.invalid_because(instance)
}
fn state_max_in_flight_messages(
&self,
instance: usize,
state_ids: &[StateId],
) -> Option<usize> {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count() );
self.states
.borrow()
.get(state_ids[self.first_index + instance])
.max_in_flight_messages(instance)
}
fn states_count(&self) -> usize {
self.states.borrow().len()
}
fn compute_terse(&self) {
self.impl_compute_terse();
}
}
impl<
State: DataLike + ContainerOf1State<State, Part, Payload>,
Part: DataLike + AgentState<Part, Payload>,
StateId: IndexLike,
Payload: DataLike,
const MAX_PARTS: usize,
> ContainerOf1TypeData<State, Part, StateId, Payload, MAX_PARTS>
{
fn collect_parts(&self, state_ids: &[StateId]) -> [Part; MAX_PARTS] {
let mut parts = [Part::default(); MAX_PARTS];
let part_first_index = self.part_type.part_first_index();
(0..self.part_type.parts_count()).for_each(|part_instance| {
let state_id = state_ids[part_first_index + part_instance];
parts[part_instance] = self.part_type.part_state_by_id(state_id);
});
parts
}
pub fn set_order(&mut self, instance: usize, order: usize) {
self.agent_type_data.set_order(instance, order);
}
}
impl<
State: DataLike + ContainerOf2State<State, Part1, Part2, Payload>,
Part1: DataLike + AgentState<Part1, Payload>,
Part2: DataLike + AgentState<Part2, Payload>,
StateId: IndexLike,
Payload: DataLike,
const MAX_PARTS: usize,
> ContainerOf2TypeData<State, Part1, Part2, StateId, Payload, MAX_PARTS>
{
fn collect_parts(&self, state_ids: &[StateId]) -> ([Part1; MAX_PARTS], [Part2; MAX_PARTS]) {
let mut parts1 = [Part1::default(); MAX_PARTS];
let part1_first_index = self.part1_type.part_first_index();
(0..self.part1_type.parts_count()).for_each(|part1_instance| {
let state_id = state_ids[part1_first_index + part1_instance];
parts1[part1_instance] = self.part1_type.part_state_by_id(state_id);
});
let mut parts2 = [Part2::default(); MAX_PARTS];
let part2_first_index = self.part2_type.part_first_index();
(0..self.part2_type.parts_count()).for_each(|part2_instance| {
let state_id = state_ids[part2_first_index + part2_instance];
parts2[part2_instance] = self.part2_type.part_state_by_id(state_id);
});
(parts1, parts2)
}
pub fn set_order(&mut self, instance: usize, order: usize) {
self.agent_type_data.set_order(instance, order);
}
}
impl<
State: DataLike + ContainerOf1State<State, Part, Payload>,
Part: DataLike + AgentState<Part, Payload>,
StateId: IndexLike,
Payload: DataLike,
const MAX_PARTS: usize,
> AgentType<StateId, Payload>
for ContainerOf1TypeData<State, Part, StateId, Payload, MAX_PARTS>
{
fn reaction(
&self,
instance: usize,
state_ids: &[StateId],
payload: &Payload,
) -> Reaction<StateId, Payload> {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count() );
let all_parts = self.collect_parts(state_ids);
let parts = &all_parts[..self.part_type.parts_count()];
let reaction = self
.agent_type_data
.states
.borrow()
.get(state_ids[self.agent_type_data.first_index + instance])
.reaction(instance, payload, parts);
self.agent_type_data.translate_reaction(&reaction)
}
fn activity(&self, instance: usize, state_ids: &[StateId]) -> Activity<Payload> {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count() );
let all_parts = self.collect_parts(state_ids);
let parts = &all_parts[..self.part_type.parts_count()];
self.agent_type_data
.states
.borrow()
.get(state_ids[self.agent_type_data.first_index + instance])
.activity(instance, parts)
}
fn state_is_deferring(&self, instance: usize, state_ids: &[StateId]) -> bool {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count() );
let all_parts = self.collect_parts(state_ids);
let parts = &all_parts[..self.part_type.parts_count()];
self.agent_type_data
.states
.borrow()
.get(state_ids[self.agent_type_data.first_index + instance])
.is_deferring(instance, parts)
}
fn state_invalid_because(
&self,
instance: usize,
state_ids: &[StateId],
) -> Option<&'static str> {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count()
);
let all_parts = self.collect_parts(state_ids);
let parts = &all_parts[..self.part_type.parts_count()];
self.agent_type_data
.states
.borrow()
.get(state_ids[self.agent_type_data.first_index + instance])
.invalid_because(instance, parts)
}
fn state_max_in_flight_messages(
&self,
instance: usize,
state_ids: &[StateId],
) -> Option<usize> {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count() );
let all_parts = self.collect_parts(state_ids);
let parts = &all_parts[..self.part_type.parts_count()];
self.agent_type_data
.states
.borrow()
.get(state_ids[self.agent_type_data.first_index + instance])
.max_in_flight_messages(instance, parts)
}
fn states_count(&self) -> usize {
self.agent_type_data.states.borrow().len()
}
fn compute_terse(&self) {
self.agent_type_data.impl_compute_terse();
}
}
impl<
State: DataLike + ContainerOf2State<State, Part1, Part2, Payload>,
Part1: DataLike + AgentState<Part1, Payload>,
Part2: DataLike + AgentState<Part2, Payload>,
StateId: IndexLike,
Payload: DataLike,
const MAX_PARTS: usize,
> AgentType<StateId, Payload>
for ContainerOf2TypeData<State, Part1, Part2, StateId, Payload, MAX_PARTS>
{
fn reaction(
&self,
instance: usize,
state_ids: &[StateId],
payload: &Payload,
) -> Reaction<StateId, Payload> {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count()
);
let (all_parts1, all_parts2) = self.collect_parts(state_ids);
let parts1 = &all_parts1[..self.part1_type.parts_count()];
let parts2 = &all_parts2[..self.part2_type.parts_count()];
let reaction = self
.agent_type_data
.states
.borrow()
.get(state_ids[self.agent_type_data.first_index + instance])
.reaction(instance, payload, parts1, parts2);
self.agent_type_data.translate_reaction(&reaction)
}
fn activity(&self, instance: usize, state_ids: &[StateId]) -> Activity<Payload> {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count()
);
let (all_parts1, all_parts2) = self.collect_parts(state_ids);
let parts1 = &all_parts1[..self.part1_type.parts_count()];
let parts2 = &all_parts2[..self.part2_type.parts_count()];
self.agent_type_data
.states
.borrow()
.get(state_ids[self.agent_type_data.first_index + instance])
.activity(instance, parts1, parts2)
}
fn state_is_deferring(&self, instance: usize, state_ids: &[StateId]) -> bool {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count()
);
let (all_parts1, all_parts2) = self.collect_parts(state_ids);
let parts1 = &all_parts1[..self.part1_type.parts_count()];
let parts2 = &all_parts2[..self.part2_type.parts_count()];
self.agent_type_data
.states
.borrow()
.get(state_ids[self.agent_type_data.first_index + instance])
.is_deferring(instance, parts1, parts2)
}
fn state_invalid_because(
&self,
instance: usize,
state_ids: &[StateId],
) -> Option<&'static str> {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count()
);
let (all_parts1, all_parts2) = self.collect_parts(state_ids);
let parts1 = &all_parts1[..self.part1_type.parts_count()];
let parts2 = &all_parts2[..self.part2_type.parts_count()];
self.agent_type_data
.states
.borrow()
.get(state_ids[self.agent_type_data.first_index + instance])
.invalid_because(instance, parts1, parts2)
}
fn state_max_in_flight_messages(
&self,
instance: usize,
state_ids: &[StateId],
) -> Option<usize> {
debug_assert!(
instance < self.instances_count(),
"instance: {} count: {}",
instance,
self.instances_count()
);
let (all_parts1, all_parts2) = self.collect_parts(state_ids);
let parts1 = &all_parts1[..self.part1_type.parts_count()];
let parts2 = &all_parts2[..self.part2_type.parts_count()];
self.agent_type_data
.states
.borrow()
.get(state_ids[self.agent_type_data.first_index + instance])
.max_in_flight_messages(instance, parts1, parts2)
}
fn states_count(&self) -> usize {
self.agent_type_data.states.borrow().len()
}
fn compute_terse(&self) {
self.agent_type_data.impl_compute_terse();
}
}
#[macro_export]
macro_rules! index_type {
($name:ident, $type:ident) => {
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Debug)]
pub struct $name($type);
impl total_space::IndexLike for $name {
fn from_usize(value: usize) -> Self {
$name($type::from_usize(value).unwrap())
}
fn to_usize(&self) -> usize {
let $name(value) = self;
$type::to_usize(value).unwrap()
}
fn invalid() -> Self {
$name($type::max_value())
}
}
impl Display for $name {
fn fmt(&self, formatter: &mut Formatter<'_>) -> FormatterResult {
write!(formatter, "{}", self.to_usize())
}
}
};
}