index_alloc 0.1.1

A toy static allocator wich can serve as a global_allocator.
Documentation
use index_alloc::boxed::Box;
use index_alloc::IndexAllocator;

const MEMORY_SIZE: usize = 1024;
const INDEX_SIZE: usize = 32;

static ALLOCATOR: IndexAllocator<MEMORY_SIZE, INDEX_SIZE> = 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<MEMORY_SIZE, INDEX_SIZE>,
    listeners: [Option<BoxedListener<'a>>; N],
    counter: usize,
}

impl<'a, const N: usize> EventDispatcher<'a, N> {
    pub fn empty(allocator: &'a IndexAllocator<MEMORY_SIZE, INDEX_SIZE>) -> Self {
        const NONE: Option<BoxedListener> = None;
        Self {
            allocator,
            listeners: [NONE; N],
            counter: 0,
        }
    }

    pub fn register<T>(&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");
}