Class: Rubino::Interaction::EventBus

Inherits:
Object
  • Object
show all
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

Constructor Details

#initializeEventBus

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