use std::marker::PhantomData;
use crate::{Receiver, Sender};
#[derive(Clone)]
pub struct Node<TEvent, TEntity>
where
TEntity: Receiver<TEvent>,
{
children: Vec<Node<TEvent, TEntity>>,
entity: TEntity,
phantom: PhantomData<TEvent>,
}
impl<TEvent, TEntity> Node<TEvent, TEntity>
where
TEntity: Receiver<TEvent>,
{
pub fn new(entity: TEntity, children: Vec<Node<TEvent, TEntity>>) -> Self {
Self {
entity,
children,
phantom: PhantomData::default(),
}
}
}
impl<TEvent, TEntity> Sender<TEvent> for Node<TEvent, TEntity>
where
TEntity: Receiver<TEvent>,
{
fn emit(&self, event: TEvent, target: &mut dyn Receiver<TEvent>) -> bool {
target.handle(&event)
}
}
impl<TEvent, TEntity> Receiver<TEvent> for Node<TEvent, TEntity>
where
TEntity: Receiver<TEvent>,
{
fn handle(&mut self, event: &TEvent) -> bool {
if !self.entity.handle(event) {
let mut handeled = false;
for child in &mut self.children {
handeled |= child.handle(event);
}
handeled
} else {
true
}
}
}
#[cfg(test)]
mod tests {
use super::*;
enum Event {
HandleInParent,
HandleInChild,
}
enum Entities {
Parent(ParentEntity),
Child(ChildEntity),
}
impl Receiver<Event> for Entities {
fn handle(&mut self, event: &Event) -> bool {
match self {
Self::Parent(e) => e.handle(event),
Self::Child(e) => e.handle(event),
}
}
}
struct ParentEntity;
impl Receiver<Event> for ParentEntity {
fn handle(&mut self, event: &Event) -> bool {
match event {
Event::HandleInParent => true,
_ => false,
}
}
}
struct ChildEntity;
impl Receiver<Event> for ChildEntity {
fn handle(&mut self, event: &Event) -> bool {
match event {
Event::HandleInChild => true,
_ => false,
}
}
}
#[test]
fn it_trigger_event_in_parent() {
let mut r = Node::new(Entities::Parent(ParentEntity), vec![]);
let s = Node::new(Entities::Parent(ParentEntity), vec![]);
assert!(s.emit(Event::HandleInParent, &mut r));
assert!(!s.emit(Event::HandleInChild, &mut r));
}
#[test]
fn it_trigger_event_in_child() {
let mut r = Node::new(Entities::Child(ChildEntity), vec![]);
let s = Node::new(Entities::Parent(ParentEntity), vec![]);
assert!(!s.emit(Event::HandleInParent, &mut r));
assert!(s.emit(Event::HandleInChild, &mut r));
}
#[test]
fn it_trigger_event_in_tree() {
let mut r = Node::new(
Entities::Parent(ParentEntity),
vec![Node::new(Entities::Child(ChildEntity), vec![])],
);
let s = Node::new(Entities::Parent(ParentEntity), vec![]);
assert!(s.emit(Event::HandleInParent, &mut r));
assert!(s.emit(Event::HandleInChild, &mut r));
}
}