icmd 0.1.1

A command-line software framework
Documentation
use std::{any::TypeId, collections::VecDeque, fmt::Debug, sync::Arc};

use crossterm::event;
use parking_lot::RwLock;

use super::ICmdWindow;

pub trait Sender {
    fn get_window(&self) -> Arc<RwLock<ICmdWindow>>;
    fn send(&self, msg: Message) {
        self.get_window().write().message_queue.push(msg);
    }
}

pub trait Participant: Sender {
    type Params;
    fn resolve(&self, msg: Message, params: Self::Params) -> bool;
    fn get_id(&self) -> TypeId
    where
        Self: Sized + 'static,
    {
        TypeId::of::<Self>()
    }
    fn update(&self, params: Self::Params) -> bool
    where
        Self: Sized + 'static,
    {
        let window = self.get_window();
        let window = window.read();
        let msgs = window.message_queue.peek().cloned();
        drop(window);
        if let Some(msg) = msgs {
            if msg.to == self.get_id() {
                let window = self.get_window();
                let mut window = window.write();
                let message = window.message_queue.pop();
                drop(window);
                if let Some(message) = message {
                    return self.resolve(message, params);
                }
                return true;
            }
            return true;
        } else {
            true
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(dead_code)]
pub enum Content {
    Ready,
    IsReady,
    Update,
    Quit,
    Event(RawEvent),
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RawEvent {
    Key(event::KeyCode, event::KeyModifiers),
    Mouse(u16, u16, event::MouseEventKind),
    Update(u64),
}

#[derive(Debug, Clone)]
pub struct Message {
    pub from: TypeId,
    pub to: TypeId,
    pub content: Content,
}

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

/// A message queue that allows for sending and receiving messages between participants.
/// It is used to facilitate communication between different components in the system.
/// The queue's length is restricted to a maximum size, and messages are processed in a first-in-first-out (FIFO) manner.
impl MessageQueue {
    /// Creates a new `MessageQueue` with the specified maximum length.
    pub fn new(max_len: usize) -> Self {
        MessageQueue {
            queue: VecDeque::new(),
            max_len,
        }
    }

    /// Pushes a message to the front of the queue.
    pub fn pop(&mut self) -> Option<Message> {
        self.queue.pop_front()
    }

    /// Pushes a message to the back of the queue.
    /// If the queue is full, the oldest message is removed to make space for the new one.
    pub fn push(&mut self, msg: Message) {
        if self.queue.len() >= self.max_len {
            self.queue.pop_back();
        }
        self.queue.push_front(msg);
    }

    /// Peeks at the front of the queue without removing it.
    pub fn peek(&self) -> Option<&Message> {
        self.queue.front()
    }
}