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,
}
impl MessageQueue {
pub fn new(max_len: usize) -> Self {
MessageQueue {
queue: VecDeque::new(),
max_len,
}
}
pub fn pop(&mut self) -> Option<Message> {
self.queue.pop_front()
}
pub fn push(&mut self, msg: Message) {
if self.queue.len() >= self.max_len {
self.queue.pop_back();
}
self.queue.push_front(msg);
}
pub fn peek(&self) -> Option<&Message> {
self.queue.front()
}
}