use crate::messages::*;
use crate::utilities::*;
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
pub enum Invalid<MessageId: IndexLike> {
Configuration(&'static str),
Agent(usize, &'static str),
Message(MessageId, &'static str),
}
impl<MessageId: IndexLike> Default for Invalid<MessageId> {
fn default() -> Self {
Invalid::Configuration("you should not be seeing this")
}
}
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
pub struct Configuration<
StateId: IndexLike,
MessageId: IndexLike,
InvalidId: IndexLike,
const MAX_AGENTS: usize,
const MAX_MESSAGES: usize,
> {
pub state_ids: [StateId; MAX_AGENTS],
pub message_counts: [MessageIndex; MAX_AGENTS],
pub message_ids: [MessageId; MAX_MESSAGES],
pub invalid_id: InvalidId,
}
impl<
StateId: IndexLike,
MessageId: IndexLike,
InvalidId: IndexLike,
const MAX_AGENTS: usize,
const MAX_MESSAGES: usize,
> Default for Configuration<StateId, MessageId, InvalidId, MAX_AGENTS, MAX_MESSAGES>
{
fn default() -> Self {
Configuration {
state_ids: [StateId::invalid(); MAX_AGENTS],
message_counts: [MessageIndex::invalid(); MAX_AGENTS],
message_ids: [MessageId::invalid(); MAX_MESSAGES],
invalid_id: InvalidId::invalid(),
}
}
}
impl<
StateId: IndexLike,
MessageId: IndexLike,
InvalidId: IndexLike,
const MAX_AGENTS: usize,
const MAX_MESSAGES: usize,
> Configuration<StateId, MessageId, InvalidId, MAX_AGENTS, MAX_MESSAGES>
{
pub(crate) fn remove_message(&mut self, source: usize, mut message_index: usize) {
debug_assert!(self.message_counts[source].to_usize() > 0);
debug_assert!(self.message_ids[message_index].is_valid());
self.message_counts[source].decr();
loop {
let next_message_index = message_index + 1;
let next_message_id = if next_message_index < MAX_MESSAGES {
self.message_ids[next_message_index]
} else {
MessageId::invalid() };
self.message_ids[message_index] = next_message_id;
if !next_message_id.is_valid() {
return;
}
message_index = next_message_index;
}
}
pub(crate) fn add_message(&mut self, source_index: usize, message_id: MessageId) {
debug_assert!(source_index != usize::max_value());
debug_assert!(self.message_counts[source_index] < MessageIndex::invalid());
assert!(
!self.message_ids[MAX_MESSAGES - 1].is_valid(),
"too many in-flight messages, must be at most {}",
MAX_MESSAGES
);
self.message_counts[source_index].incr();
self.message_ids[MAX_MESSAGES - 1] = message_id;
self.message_ids.sort();
}
pub(crate) fn change_state(&mut self, agent_index: usize, state_id: StateId) {
self.state_ids[agent_index] = state_id;
}
}