simvx.core.event_bus¶
Typed event bus keyed on dataclass event types.
Handlers subscribe against a dataclass event type. Calling
- meth:
EventBus.publishwith an instance of that dataclass synchronously fans the event out to every live handler subscribed for the exact class. There is no MRO walk: a handler forParentdoes NOT receive publishes ofChild(Parent); subclasses must subscribe themselves. This keeps dispatch predictable and O(1) per event class.
Vocabulary (subscribe/publish/unsubscribe) is intentionally distinct from
- class:
Signal’s connect/emit/disconnect: anEventBusis a typed pub/sub hub, while a Signal is a per-instance callback list. Different shapes, so different verbs.
Each event class has its own :class:Signal, so a handler’s lifetime follows
the signal rule:
A bound method of a :class:
Nodeis held weakly, and its subscription ends when the node is destroyed (:meth:Node.destroy, orchange_scene, which destroys the scene it replaces) or garbage-collected. Leaving the tree without being destroyed (remove_child) does not end it.Every other callable (a lambda, a closure, a :class:
functools.partial, a free function, a method of a plain object) is held strongly and fires until it is unsubscribed, even when it captures a node that was destroyed.
Two dispatch modes:
- meth:
publish: synchronous. Handlers run in subscription order on the calling thread beforepublishreturns.
- meth:
publish_deferred: queues the event. The queue is drained when- meth:
flush_deferredis called (typically once per frame).
Threading: the bus assumes a single-threaded engine. There are no locks.
Calling publish from a non-main thread is undefined behaviour.
Module Contents¶
Classes¶
Typed publish/subscribe bus keyed on dataclass event types. |
Data¶
API¶
- simvx.core.event_bus.EventCls¶
None
- simvx.core.event_bus.Handler¶
None
- class simvx.core.event_bus.EventBus[source]¶
Typed publish/subscribe bus keyed on dataclass event types.
Initialization
- __slots__¶
(‘_subs’, ‘_deferred’)
- subscribe(event_cls: simvx.core.event_bus.EventCls, handler: simvx.core.event_bus.Handler) None[source]¶
Register
handlerfor events of exactlyevent_cls.A bound method of a :class:
Nodeis held weakly and dropped when the node is destroyed or collected; any other callable is held until- Meth:
unsubscribe. Subscribing a handler that is already subscribed does nothing.
- unsubscribe(event_cls: simvx.core.event_bus.EventCls, handler: simvx.core.event_bus.Handler) None[source]¶
Remove
handlerfromevent_cls. Idempotent.handlermatches by equality, so a freshly bound method finds the subscription made with an earlier binding of the same method.
- disconnect_from_module(module_name: str) int[source]¶
Drop every handler defined in
module_name; return how many.Hot reload calls this before reloading a module, so the old version of a handler stops firing and the old module can be collected.
- publish(event: Any) None[source]¶
Synchronously fan
eventout to handlers of its exact type.Raises :class:
TypeErrorifeventis not a dataclass instance. Handlers run in subscription order. Subscriptions of collected nodes are pruned during dispatch.Unsubscribing takes effect immediately, as it does for a
- Class:
Signal: a handler removed by an earlier handler in this same dispatch is not called. Unsubscribing mid-dispatch nearly always means the subscriber is being torn down, so calling it anyway is wrong.