Class: Rubino::Interaction::EventBus
- Inherits:
-
Object
- Object
- Rubino::Interaction::EventBus
- Defined in:
- lib/rubino/interaction/event_bus.rb
Overview
Simple pub/sub event bus for decoupling core logic from UI. Core components emit events; UI adapters and other listeners subscribe.
Thread-safety: subscriptions are mutated under a mutex, and ‘emit` snapshots the listener list under the lock then invokes listeners OUTSIDE the lock. This keeps concurrent `on`/`off` (e.g. a parent run’s ‘recorder.detach!` racing a background subagent thread emitting SUBAGENT_COMPLETED onto the same bus — #136) from mutating the hash mid-iteration, while still allowing a listener to itself emit/subscribe without deadlocking.
Instance Method Summary collapse
-
#clear! ⇒ Object
Remove all listeners.
-
#emit(event_type, **payload) ⇒ Object
Emit an event to all registered listeners.
-
#initialize ⇒ EventBus
constructor
A new instance of EventBus.
-
#listener_count(event_type) ⇒ Object
Returns the count of listeners for a given event type.
-
#off(event_type) ⇒ Object
Remove all listeners for a given event type.
-
#on(event_type, &block) ⇒ Object
Subscribe to an event type with a callable or block.
Constructor Details
#initialize ⇒ EventBus
Returns a new instance of EventBus.
16 17 18 19 |
# File 'lib/rubino/interaction/event_bus.rb', line 16 def initialize @listeners = Hash.new { |h, k| h[k] = [] } @mutex = Mutex.new end |
Instance Method Details
#clear! ⇒ Object
Remove all listeners
38 39 40 |
# File 'lib/rubino/interaction/event_bus.rb', line 38 def clear! @mutex.synchronize { @listeners.clear } end |
#emit(event_type, **payload) ⇒ Object
Emit an event to all registered listeners
27 28 29 30 |
# File 'lib/rubino/interaction/event_bus.rb', line 27 def emit(event_type, **payload) listeners = @mutex.synchronize { @listeners[event_type.to_sym].dup } listeners.each { |listener| listener.call(payload) } end |
#listener_count(event_type) ⇒ Object
Returns the count of listeners for a given event type
43 44 45 |
# File 'lib/rubino/interaction/event_bus.rb', line 43 def listener_count(event_type) @mutex.synchronize { @listeners[event_type.to_sym].size } end |
#off(event_type) ⇒ Object
Remove all listeners for a given event type
33 34 35 |
# File 'lib/rubino/interaction/event_bus.rb', line 33 def off(event_type) @mutex.synchronize { @listeners.delete(event_type.to_sym) } end |
#on(event_type, &block) ⇒ Object
Subscribe to an event type with a callable or block
22 23 24 |
# File 'lib/rubino/interaction/event_bus.rb', line 22 def on(event_type, &block) @mutex.synchronize { @listeners[event_type.to_sym] << block } end |