use std::{fmt::Debug, rc::Rc};
use crate::{
foundation::patterns::{
default::{BaseController, BaseModel, BaseView},
observer::{BaseNotification, BaseObserver},
},
prelude::*,
};
pub struct BaseFacade<Body>
where
Body: Debug + 'static,
{
controller: BaseController<Body>,
view: BaseView<Body>,
}
impl<Body> BaseFacade<Body>
where
Body: Debug + 'static,
{
pub fn new() -> Self {
Self {
controller: BaseController::new(),
view: BaseView::new(),
}
}
}
impl<Body> Singleton for BaseFacade<Body>
where
Body: Debug + 'static,
{
fn global() -> &'static Self {
todo!("you have to reimplement the facade for your purposes")
}
}
impl<Body> Facade<Body> for BaseFacade<Body>
where
Body: Debug + 'static,
{
fn has_command(&self, interest: &Interest) -> bool {
self.controller.has_command(interest)
}
fn register_command(&self, interest: Interest, command: Rc<dyn Command<Body>>) {
{
if !self.has_command(&interest) {
self.view.register_observer(
interest,
Rc::new(BaseObserver::new(
Box::new(|notification| {
log::error!("You should implement yourself Facade");
BaseFacade::<Body>::global()
.controller
.execute_command(notification);
}),
self.controller.as_context(),
)),
);
}
}
self.controller.register_command(interest, command);
}
fn remove_command(&self, interest: &Interest) {
if self.has_command(interest) {
{
self.view
.remove_observer(interest, &self.controller.as_context());
}
self.controller.remove_command(interest);
}
}
fn send(&self, interest: Interest, body: Option<Body>) {
self.notify(Rc::new(BaseNotification::new(interest, body)));
}
}
impl<Body> Model for BaseFacade<Body>
where
Body: Debug + 'static,
{
fn has_proxy<P: Proxy>(&self) -> bool {
BaseModel::global().has_proxy::<P>()
}
fn register_proxy<P: Proxy>(&self, proxy: Rc<P>) {
BaseModel::global().register_proxy(proxy);
}
fn remove_proxy<P: Proxy>(&self) -> Option<Rc<P>> {
BaseModel::global().remove_proxy::<P>()
}
fn retrieve_proxy<P: Proxy>(&self) -> Option<Rc<P>> {
BaseModel::global().retrieve_proxy::<P>()
}
}
impl<Body> View<Body> for BaseFacade<Body>
where
Body: Debug + 'static,
{
fn register_observer(&self, interest: Interest, observer: Rc<dyn Observer<Body>>) {
self.view.register_observer(interest, observer);
}
fn remove_observer(&self, interest: &Interest, notify_context: &Rc<dyn NotifyContext>) {
self.view.remove_observer(interest, notify_context);
}
fn notify(&self, note: Rc<dyn Notification<Body>>) {
self.view.notify(note);
}
}
impl<Body> MediatorRegistry<Body> for BaseFacade<Body>
where
Body: Debug + 'static,
{
fn register_mediator<M: Mediator<Body>>(&self, mediator: Rc<M>) {
self.view.register_mediator(mediator);
}
fn retrieve_mediator<M: Mediator<Body>>(&self) -> Option<Rc<M>> {
self.view.retrieve_mediator::<M>()
}
fn remove_mediator<M: Mediator<Body>>(&self) -> Option<Rc<M>> {
self.view.remove_mediator::<M>()
}
fn has_mediator<M: Mediator<Body>>(&self) -> bool {
self.view.has_mediator::<M>()
}
}