use std::{cell::RefCell, collections::HashMap, fmt, rc::Rc};
use crate::prelude::*;
pub struct BaseController<Body>
where
Body: fmt::Debug + 'static,
{
command_map: RefCell<HashMap<Interest, Rc<dyn Command<Body>>>>,
notify_context: Rc<BaseNotifyContext>,
}
unsafe impl<Body> std::marker::Send for BaseController<Body> where Body: fmt::Debug + 'static {}
unsafe impl<Body> std::marker::Sync for BaseController<Body> where Body: fmt::Debug + 'static {}
impl<Body> BaseController<Body>
where
Body: fmt::Debug + 'static,
{
pub fn new() -> Self {
Self {
command_map: RefCell::new(HashMap::new()),
notify_context: Rc::new(BaseNotifyContext {}),
}
}
pub fn as_context(&self) -> Rc<dyn NotifyContext> {
self.notify_context.clone()
}
}
impl<Body> Singleton for BaseController<Body>
where
Body: fmt::Debug + 'static,
{
fn global() -> &'static Self {
todo!("you have to reimplement the controller for your purposes")
}
}
impl<Body> Controller<Body> for BaseController<Body>
where
Body: fmt::Debug + 'static,
{
fn execute_command(&self, notification: Rc<dyn Notification<Body>>) {
let command_map = self.command_map.borrow();
log::info!("Execute Command [BaseController] {:?}", notification);
if let Some(command) = command_map.get(¬ification.interest()) {
log::info!("Command [BaseController] {:?} for {:?}", command, notification);
command.execute(notification)
}
}
fn has_command(&self, interest: &Interest) -> bool {
let command_map = self.command_map.borrow();
command_map.contains_key(interest)
}
fn register_command(&self, interest: Interest, command: Rc<dyn Command<Body>>) {
log::info!("Register Command [BaseController] {:?}", interest);
{
}
self.command_map.borrow_mut().insert(interest, command);
}
fn remove_command(&self, interest: &Interest) {
if self.has_command(interest) {
{
}
self.command_map.borrow_mut().remove(interest);
}
}
}
impl<Body> fmt::Debug for BaseController<Body>
where
Body: fmt::Debug + 'static,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Controller")
.finish()
}
}
#[derive(Clone, Copy)]
struct BaseNotifyContext;
impl NotifyContext for BaseNotifyContext {
fn id(&self) -> u64 {
0x01
}
}
impl NotifyContext for Rc<BaseNotifyContext> {
fn id(&self) -> u64 {
0x01
}
}
impl fmt::Debug for BaseNotifyContext {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BaseNotifyContext").field("id", &self.id()).finish()
}
}