use index_alloc::boxed::Box; use index_alloc::IndexAllocator; const MEMORY_SIZE: usize = 1024; const INDEX_SIZE: usize = 32; static ALLOCATOR: IndexAllocator = IndexAllocator::empty(); pub type BoxedListener<'a> = Box<'a, dyn Listener + 'static, MEMORY_SIZE, INDEX_SIZE>; pub struct EventDispatcher<'a, const N: usize> { allocator: &'a IndexAllocator, listeners: [Option>; N], counter: usize, } impl<'a, const N: usize> EventDispatcher<'a, N> { pub fn empty(allocator: &'a IndexAllocator) -> Self { const NONE: Option = None; Self { allocator, listeners: [NONE; N], counter: 0, } } pub fn register(&mut self, listener: T) where T: Listener + 'static, &'a mut (dyn Listener + 'static): From<&'a mut T>, { if self.counter >= N { panic!("Out of listeners"); } self.listeners[self.counter] = Some( self.allocator .try_boxed::<'a, dyn Listener + 'static, T>(listener) .unwrap(), ); self.counter += 1; } pub fn send(&mut self, name: &str) { for listener in self.listeners.iter_mut() { if let Some(l) = listener { l.on_event(name); } } } } pub trait Listener { fn on_event(&mut self, name: &str); } impl<'a, T: Listener> From<&'a mut T> for &'a mut dyn Listener { fn from(value: &'a mut T) -> Self { value as _ } } pub struct DummyListener; impl Listener for DummyListener { fn on_event(&mut self, name: &str) { println!("Received : {name}"); } } pub struct CounterListener { counter: u8, } impl Listener for CounterListener { fn on_event(&mut self, name: &str) { println!("Received : {name} : {}", self.counter); self.counter += 1; } } fn main() { let mut dispatcher: EventDispatcher<16> = EventDispatcher::empty(&ALLOCATOR); let dummy = DummyListener; let counter = CounterListener { counter: 0 }; dispatcher.register(dummy); dispatcher.register(counter); dispatcher.send("It's a test"); dispatcher.send("Second test"); }