-
Notifications
You must be signed in to change notification settings - Fork 4
Description
First of all, thank you for putting together a truly pleasant, and performant (the real P in APECS) entity-component-system implementation.
Has there been any thought as to how to support resources which do not implement the Send trait, and the systems which use them (that, by implication, must be run on the main thread)?
Some context: I'm coming from the Bevy ecosystem, but looking for a roll-my-own solution to state management in a non-game setting where Bevy's opinionated design makes less sense. In Bevy's ECS you can add a resource which does not implement Send (or Sync) using the World::insert_non_send_resource method, and then access it as a system parameter using the NonSend<R> or NonSendMut<R> traits. Any system which accesses non-Send resources has to run on the application's main thread, and this is of course enforced by the compiler.
Why is this useful? Well there are in fact some commonly used types which do not implement Send. Most notably, the event loop of a winit program must be created and run from the main thread, as must also some calls to the operating system / display manager on macOS and Windows. Allowing non-Send resources means you can just write a system that uses these resources, and the schedule runner automatically makes sure these run on the main thread only.
As I need to implement a winit program that needs to access non-Send resources from its input event and window management systems, I've been looking into how to do this with apecs. As near as I can tell apecs does not support this. It's easy enough to add a separate non-Send TypeMap (I used the anymap crate) to store these resources, but I wasn't sure how to handle the scheduling to run these systems on the main thread. I admit that moongraph is still a bit of a mystery to me at this point.
I'm happy to continue hacking along, but I'm wondering if anyone has considered this use case and how it might best be implemented in apecs. Maybe there's a better, easier solution that was just not obvious to me?