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
//! This module provides a way for a [crate::processor::Cpu] to communicate with the "exterior world".
//!
//! This means it can put messages in an output queue, and these messages can be transmitted by any "supervisor" of the Cpus to the right recipient.

use std::collections::VecDeque;
use osiris_data::data::composite::{Array, ProduceConsume};

/// Helps a supervisor track an identified [crate::processor::Cpu].
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct CpuId(u16);

impl CpuId {
    pub const fn new(raw: u16) -> Self { Self(raw) }
    pub const fn to_u16(&self) -> u16 { self.0 }
}

#[derive(Clone, Debug)]
pub struct Message {
    recipient: CpuId,
    data: Array,
}

impl Message {
    pub fn new(recipient: CpuId, data: Array) -> Self {
        Message { recipient, data }
    }

    pub fn is_recipient(&self, cpu_id: CpuId) -> bool { self.recipient == cpu_id }
    pub fn recipient(&self) -> CpuId { self.recipient }
    pub fn get_data(&self) -> Array { self.data.clone() }

}

#[derive(Clone, Debug, Default)]
pub struct MessageQueue {
    queue: VecDeque<Message>
}

impl ProduceConsume<Message> for MessageQueue {
    fn produce(&mut self, data: Message) {
        self.queue.push_back(data);
    }

    fn consume(&mut self) -> Option<Message> { self.queue.pop_front() }

    fn len(&self) -> usize { self.queue.len() }

    fn is_empty(&self) -> bool { self.queue.is_empty() }
}