Class: Charming::Internal::EventLoop

Inherits:
Object
  • Object
show all
Defined in:
lib/charming/internal/event_loop.rb

Overview

EventLoop pumps events for a Charming runtime: it delivers the next due event — completed background tasks first, then due timers, then terminal input (with optional held-key coalescing) — to the block passed to #run, until the block returns :quit, the interrupt check trips, or a test backend runs out of events. It knows nothing about controllers, routes, or rendering; deciding what an event means belongs to its caller.

Constant Summary collapse

DEFAULT_READ_TIMEOUT =
0.05

Instance Method Summary collapse

Constructor Details

#initialize(backend:, clock:, task_queue:, timer_bindings: [], coalesce_input: false, interrupted: -> { false }) ⇒ EventLoop

timer_bindings is the list of controller timer bindings (each responding to name and interval) to schedule. interrupted is a callable checked every iteration so a signal handler can stop the loop.



17
18
19
20
21
22
23
24
25
# File 'lib/charming/internal/event_loop.rb', line 17

def initialize(backend:, clock:, task_queue:, timer_bindings: [], coalesce_input: false, interrupted: -> { false })
  @backend = backend
  @clock = clock
  @task_queue = task_queue
  @coalesce_input = coalesce_input
  @interrupted = interrupted
  @timers = build_timers(timer_bindings)
  @pending_event = nil
end

Instance Method Details

#reset_timers(timer_bindings) ⇒ Object

Replaces the scheduled timers — called when navigation lands on a controller with different timer bindings.



50
51
52
# File 'lib/charming/internal/event_loop.rb', line 50

def reset_timers(timer_bindings)
  @timers = build_timers(timer_bindings)
end

#runObject

Pumps events, yielding each to the caller together with a flag saying whether another event is already due (letting the caller coalesce a burst into one repaint). Stops when the block returns :quit, when the interrupt check returns true, or when a test backend is exhausted. Closes the task queue on the way out so producer threads can't block on a loop that is no longer draining them.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/charming/internal/event_loop.rb', line 33

def run
  loop do
    break if @interrupted.call

    event = next_event
    unless event
      break if backend_exhausted?
      next
    end
    break if yield(event, more_ready?) == :quit
  end
ensure
  @task_queue.close
end