Class: DiscordRDA::EventBus
- Inherits:
-
Object
- Object
- DiscordRDA::EventBus
- Defined in:
- lib/discord_rda/event/bus.rb
Overview
Event bus for publish-subscribe event handling. Routes events from Gateway to registered handlers.
Defined Under Namespace
Classes: Subscription
Instance Attribute Summary collapse
-
#handlers ⇒ Hash<String, Array<EventHandler>>
readonly
Registered handlers.
-
#logger ⇒ Logger
readonly
Logger instance.
-
#middleware ⇒ Array<Middleware>
readonly
Global middleware.
Instance Method Summary collapse
-
#event_types ⇒ Array<String>
Get all registered event types.
-
#has_handlers?(event_type) ⇒ Boolean
Check if event type has handlers.
-
#initialize(logger: nil) ⇒ EventBus
constructor
Initialize event bus.
-
#off(event_type, handler) ⇒ void
Unsubscribe a handler.
-
#on(event_type, handler = nil, middleware: []) { ... } ⇒ Subscription
Subscribe to an event type.
-
#once(event_type, handler = nil) { ... } ⇒ Subscription
Subscribe to an event once.
-
#publish(event_type, event) ⇒ void
Publish an event to all subscribers.
-
#unuse(middleware) ⇒ void
Remove global middleware.
-
#use(middleware) ⇒ void
Add global middleware.
-
#wait_for(event_type, timeout: nil) { ... } ⇒ Event?
Wait for an event (async).
Constructor Details
#initialize(logger: nil) ⇒ EventBus
Initialize event bus
19 20 21 22 23 24 |
# File 'lib/discord_rda/event/bus.rb', line 19 def initialize(logger: nil) @logger = logger @handlers = {} @middleware = [] @mutex = Mutex.new end |
Instance Attribute Details
#handlers ⇒ Hash<String, Array<EventHandler>> (readonly)
Returns Registered handlers.
9 10 11 |
# File 'lib/discord_rda/event/bus.rb', line 9 def handlers @handlers end |
#logger ⇒ Logger (readonly)
Returns Logger instance.
12 13 14 |
# File 'lib/discord_rda/event/bus.rb', line 12 def logger @logger end |
#middleware ⇒ Array<Middleware> (readonly)
Returns Global middleware.
15 16 17 |
# File 'lib/discord_rda/event/bus.rb', line 15 def middleware @middleware end |
Instance Method Details
#event_types ⇒ Array<String>
Get all registered event types
110 111 112 |
# File 'lib/discord_rda/event/bus.rb', line 110 def event_types @handlers.keys end |
#has_handlers?(event_type) ⇒ Boolean
Check if event type has handlers
117 118 119 120 |
# File 'lib/discord_rda/event/bus.rb', line 117 def has_handlers?(event_type) event_type = normalize_event_type(event_type) @handlers[event_type]&.any? end |
#off(event_type, handler) ⇒ void
This method returns an undefined value.
Unsubscribe a handler
84 85 86 87 88 89 90 91 92 |
# File 'lib/discord_rda/event/bus.rb', line 84 def off(event_type, handler) event_type = normalize_event_type(event_type) @mutex.synchronize do @handlers[event_type]&.reject! { |sub| sub[:handler] == handler } end @logger&.debug('Unregistered handler', event: event_type) end |
#on(event_type, handler = nil, middleware: []) { ... } ⇒ Subscription
Subscribe to an event type
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/discord_rda/event/bus.rb', line 32 def on(event_type, handler = nil, middleware: [], &block) handler = block if block_given? handler = EventHandler.new(handler) unless handler.is_a?(EventHandler) event_type = normalize_event_type(event_type) @mutex.synchronize do @handlers[event_type] ||= [] @handlers[event_type] << { handler: handler, middleware: middleware } end @logger&.debug('Registered handler', event: event_type) Subscription.new(self, event_type, handler) end |
#once(event_type, handler = nil) { ... } ⇒ Subscription
Subscribe to an event once
53 54 55 56 57 58 59 60 61 |
# File 'lib/discord_rda/event/bus.rb', line 53 def once(event_type, handler = nil, &block) handler = block if block_given? wrapped_handler = proc do |event| handler.call(event) :unsubscribe end on(event_type, wrapped_handler) end |
#publish(event_type, event) ⇒ void
This method returns an undefined value.
Publish an event to all subscribers
67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/discord_rda/event/bus.rb', line 67 def publish(event_type, event) event_type = normalize_event_type(event_type) subscriptions = @mutex.synchronize { @handlers[event_type]&.dup || [] } return if subscriptions.empty? @logger&.debug('Publishing event', type: event_type, handler_count: subscriptions.length) subscriptions.each do |sub| dispatch_with_middleware(sub[:handler], event, sub[:middleware]) end end |
#unuse(middleware) ⇒ void
This method returns an undefined value.
Remove global middleware
104 105 106 |
# File 'lib/discord_rda/event/bus.rb', line 104 def unuse(middleware) @middleware.delete(middleware) end |
#use(middleware) ⇒ void
This method returns an undefined value.
Add global middleware
97 98 99 |
# File 'lib/discord_rda/event/bus.rb', line 97 def use(middleware) @middleware << middleware end |
#wait_for(event_type, timeout: nil) { ... } ⇒ Event?
Wait for an event (async)
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/discord_rda/event/bus.rb', line 127 def wait_for(event_type, timeout: nil, &block) Async::Condition.new.tap do |condition| handler = on(event_type) do |event| if block.nil? || block.call(event) condition.signal(event) :unsubscribe end end timer = Async do sleep(timeout) if timeout condition.signal(nil) end if timeout result = condition.wait timer&.stop result end end |