Class: TuiTui::EventStream

Inherits:
Object
  • Object
show all
Defined in:
lib/tui_tui/event_stream.rb

Overview

Converts terminal input readiness and resize notifications into runtime events. Ticks are scheduled against a monotonic deadline, so TickEvent arrives at a fixed cadence even while input keeps flowing (key repeat cannot starve animations or timers).

Instance Method Summary collapse

Constructor Details

#initialize(input:, size:, clock: Clock) ⇒ EventStream

Returns a new instance of EventStream.



13
14
15
16
17
18
19
20
21
# File 'lib/tui_tui/event_stream.rb', line 13

def initialize(input:, size:, clock: Clock)
  @input = input
  @size = size
  @clock = clock
  @key_reader = KeyReader.new
  @resized = false
  @queue = []
  @deadline = nil
end

Instance Method Details

#next_event(tick: 0.1) ⇒ Object

Returns the next event: queued input first, then resize, then whichever of "tick deadline reached" or "input ready" happens first. tick is the TickEvent period — ticks land between input events, not after idle gaps.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/tui_tui/event_stream.rb', line 30

def next_event(tick: 0.1)
  return @queue.shift unless @queue.empty?

  if @resized
    @resized = false
    return ResizeEvent.new(size: @size.size)
  end

  now = @clock.monotonic
  @deadline ||= now + tick
  if now >= @deadline
    # Drain pending input into the queue before returning the tick, so a
    # zero (or tiny) period cannot starve keys: the tick goes out now, the
    # input on the very next calls.
    return EofEvent.new if IO.select([@input], nil, nil, 0) && read_input == :eof

    return advance_deadline(now, tick)
  end

  ready = IO.select([@input], nil, nil, @deadline - now)
  return advance_deadline(@clock.monotonic, tick) unless ready
  return EofEvent.new if read_input == :eof

  @queue.shift
end

#resized!Object



23
24
25
# File 'lib/tui_tui/event_stream.rb', line 23

def resized!
  @resized = true
end