Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
make global vs. local (module-to-module) messages less magical
Previously an ECS module could send a global message like `.tick`, `.init`, etc. to any other ECS module that was interested in listening to it. If nobody was listening for it, no problem. Whether someone is listening is determined by whether a function with that name is defined, e.g. `pub fn tick()` For module-to-module messages, the module name and message name were combined so that one module could send a message to another module. For example, a `.gfx_sprite` module may be listening for an `.init` message, by defining a `pub fn gfxSpriteInit()` function. Because module-to-module messages were defined as that _combination_ of the module name and message name (`.gfx_sprite` + `.init` -> `pub fn gfxSpriteInit`) it was easy to have a typo mean your message wouldn't get delivered. The conversion felt magical, which is not good. Additionally, because message handling was optional, you'd get no compile error for this - the message handler just would not run. After this change, a message may be sent to everyone (`send(null, .foo)`) or to a specific module (`send(.gfx_sprite, .init)`). With the latter, it is enforced that there is someone to recieve it on the other side - you'll get a comptime error otherwise. Prior to this change to handle a message `send(.gfxSpriteInit)` you would define e.g.: ``` pub fn gfxSpriteInit(...) { ... } ``` and the `gfxSprite` prefix must match your ECS module name. After this change, `send(.gfx_sprite, .init)` can be handled by defining: ``` pub const local = struct { pub fn init(...) { ... } }; ``` Since the `send(.gfx_sprite, .init)` API call is targeted at a specific ECS module (the `.gfx_sprite` module) it _must_ define the event handler inside of the `pub const local` namespace. This is to prevent collisions with global events: ``` pub const name = .gfx_sprite; pub fn init(...) { ... } // can be called only via: send(null, .init) pub const local = struct { pub fn init(...) { ... } // can be called only via: send(.gfx_sprite, .init) }; ``` This isn't perfect, having to write a namespace `local` feels a bit strange - but this is definitely an improvement over the magical "`gfxSprite` prefix must match your ECS module name" from before. Signed-off-by: Stephen Gutekanst <[email protected]>
- Loading branch information