So first, I think I misread your description, thinking on_some_event()
is the already implemented external event you have to handle, but I think the advice still applies so long as you're careful to avoid confusing the external events (like, say, "user connected") with internal events, replacing global mutation (like, say, "add user to room", "send message to user") - perhaps use Command for the latter.
If you did have a context (in the sense of a thing you pass to everything), it would only have a sender, while the processor (which could just be a loop in main) only has a receiver. The point here is to avoid having to have a context though, and give out senders (ideally wrapped up so the actual mechanism is hidden) to whoever needs to send events/commands (instead of mutating state directly), and your receiver can stay in the processor at the top of your app and mutate anything it likes.
It's not the only way to build this, but it's a pretty natural way to avoid having to handle mutation from anywhere, which solves a lot of headaches.
The only real trick is to avoid having any long lived references, though: doing that essentially requires interior mutation (RefCell
and the like), this is just a good way to avoid that by decoupling detecting events and applying responses - which is why having an event loop is so common.
You can instead do things like have a context (or several) with a bunch of mut references you pass around and (potentially) throw away when you're done, but that tends to be more specialized (renderers, for example). You need to be careful with that, as you can quickly trap yourself if you don't get the things you have references to split up correctly, as while you have that context, nothing can otherwise be able to reference any of those objects or anything in them (without interior mutability, which you should try to avoid)
The short version of the general advice is event driven applications are just hard to write ad-hoc logic for correctly without some careful design (largely because they have to keep state around between events), and Rust makes things that are hard to write correctly much harder to write in general. Try to avoid fighting the language, and you're going to be doing that if you try to pass something that can mutate any part of your application to any part of your application.