Ideally there could be multiple such implementations provided which could be switched between at runtime (in the music hardware industry, such configs are often called Banks).
I learned about static and dynamic dispatch in Rust (there are very good articles and youtube videos around).
Currently I am using a static dispatch approach with an enum which also implements the Handler trait.
This works pretty well but is not very easy to extend, since every new implementation (Bank) will add a new enum variant.
I was wondering if also some dynamic dispatch approach would be possible by using trait objects. However, many of the examples (also the Rust book) are based on std:boxed::Box.
I was wondering what would be a pragmatic counterpart in the embedded no_std world?
Is the static Enum based dispatcher already the most pragmatic solution?
Thank you @tbfleming for guiding me through this journey. Its a steep learning curve (at least for me).
I was thinking about it from my understanding its save to add Send to to the Handler because they are protected with a lock on the RTIC Task. I think otherwise I would also have the issues with the static dispatched code.
But now I am heading the next puzzle: How to I create the trait objects with the lifetime required for RTIC.
Since the Handlers (at least currently) would live for the whole lifetime of the application. 'static should be ok?
But how would I create a trait object with an explicit lifetime?
PS: I hope this journey might help also other newbies that are facing similar problem with Embedded RTIC based development
I'm unfamiliar with rtic, so I looked it up to see what it needs. It looks like rtic needs to know all mutexes in advance (#[shared]). One way to do this is to pack all of the handlers into a single struct and add an instance of that struct to Shared, like you probably did with the enum. It looks like that may take care of all of the lifetime and Send/Sync requirements. Once you have a lock on that structure, you can convert its members to trait objects to pass to generic functions.
Untested; I can get qemu to work with other embedded frameworks, but something about rtic's examples seems to throw it off.
The below is a reply about Rust and not your specific scenario. Not sure if it will help at all with the latter, but perhaps it will be worth something for your mental model of Rust.
Be careful equating lifetimes to the liveness of values. Lifetimes are a property of types, not values. Local variables can have types that satisfy a 'static bound but aren't alive for the whole runtime, for example.
That said, if you need a single value to be always usable (like some sort of singleton), it's probably going to satisfy a 'static bound.
All trait objects have a lifetime. If the base type you're coercing to dyn Trait satisfies a 'static bound, then you can coerce it to dyn Trait + 'static. So if you need to create a dyn Trait + 'static, you just need to make sure the implementing types are also 'static -- don't contain any non-'static references.