Class: Tina4::Events

Inherits:
Object
  • Object
show all
Defined in:
lib/tina4/events.rb

Class Method Summary collapse

Class Method Details

.clearObject

Remove all listeners for all events.



104
105
106
# File 'lib/tina4/events.rb', line 104

def clear
  @listeners.clear
end

.emit(event, *args) ⇒ Object

Fire an event synchronously. Returns array of listener results.

results = Tina4::Events.emit("user.created", user_data)


63
64
65
66
67
68
69
70
71
72
# File 'lib/tina4/events.rb', line 63

def emit(event, *args)
  entries = @listeners[event].dup
  results = []
  entries.each do |entry|
    # Remove one-time listeners before calling so re-entrant emits are safe
    @listeners[event].delete(entry) if entry[:once]
    results << entry[:callback].call(*args)
  end
  results
end

.emit_async(event, *args) ⇒ Object

Fire an event asynchronously. Each listener runs in its own thread. Errors in listeners are silently caught.

Tina4::Events.emit_async("user.created", user_data)


89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/tina4/events.rb', line 89

def emit_async(event, *args)
  return unless @listeners&.key?(event)

  @listeners[event].sort_by { |l| -(l[:priority] || 0) }.each do |listener|
    Thread.new do
      begin
        listener[:callback].call(*args)
      rescue => e
        # Async emit silently catches errors
      end
    end
  end
end

.eventsObject

List all registered event names.



80
81
82
# File 'lib/tina4/events.rb', line 80

def events
  @listeners.keys
end

.listeners(event) ⇒ Object

Get all listener callbacks for an event (in priority order).



75
76
77
# File 'lib/tina4/events.rb', line 75

def listeners(event)
  @listeners[event].map { |entry| entry[:callback] }
end

.off(event, callback = nil) ⇒ Object

Remove a specific listener, or all listeners for an event.

Tina4::Events.off("user.created", handler)  # remove specific
Tina4::Events.off("user.created")            # remove all for event


51
52
53
54
55
56
57
# File 'lib/tina4/events.rb', line 51

def off(event, callback = nil)
  if callback.nil?
    @listeners.delete(event)
  else
    @listeners[event].reject! { |entry| entry[:callback] == callback }
  end
end

.on(event, priority: 0, &block) ⇒ Object

Register a listener for an event.

Tina4::Events.on("user.created") { |user| ... }
Tina4::Events.on("user.created", priority: 10) { |user| ... }

Higher priority runs first.

Raises:

  • (ArgumentError)


26
27
28
29
30
31
32
# File 'lib/tina4/events.rb', line 26

def on(event, priority: 0, &block)
  raise ArgumentError, "block required" unless block_given?

  @listeners[event] << { priority: priority, callback: block, once: false }
  @listeners[event].sort_by! { |entry| -entry[:priority] }
  block
end

.once(event, priority: 0, &block) ⇒ Object

Register a listener that fires only once then auto-removes.

Tina4::Events.once("app.ready") { puts "App started!" }

Raises:

  • (ArgumentError)


38
39
40
41
42
43
44
# File 'lib/tina4/events.rb', line 38

def once(event, priority: 0, &block)
  raise ArgumentError, "block required" unless block_given?

  @listeners[event] << { priority: priority, callback: block, once: true }
  @listeners[event].sort_by! { |entry| -entry[:priority] }
  block
end