Class: Chamomile::Program

Inherits:
Object
  • Object
show all
Defined in:
lib/chamomile/program.rb

Overview

Main event loop — wires up Model, Renderer, and InputReader.

Instance Method Summary collapse

Constructor Details

#initialize(model, options: nil, **kwargs) ⇒ Program

Returns a new instance of Program.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/chamomile/program.rb', line 8

def initialize(model, options: nil, **kwargs)
  @options = options || Options.default(**kwargs.compact)

  @model        = model
  @output       = @options.output
  @input        = resolve_input
  @msgs         = Queue.new
  @renderer     = if @options.without_renderer
                    NullRenderer.new
                  else
                    Renderer.new(output: @output, fps: @options.fps)
                  end
  @input_reader = InputReader.new(@msgs, input: @input)
  @executor     = Concurrent::ThreadPoolExecutor.new(
    min_threads: 2,
    max_threads: 8,
    max_queue: 64,
    fallback_policy: :caller_runs
  )
  @running      = false
  @torn_down    = false
  @done_mutex   = Mutex.new
  @done_cv      = ConditionVariable.new
  @done         = false
  @stty_state   = nil
end

Instance Method Details

#kill!Object

Kill immediately — no final message, no cleanup render



67
68
69
70
71
72
# File 'lib/chamomile/program.rb', line 67

def kill!
  @running = false
  @msgs.push(QuitEvent.new)
rescue ClosedQueueError
  # Already shut down
end

#quit!Object

Quit gracefully — model gets a final QuitEvent



60
61
62
63
64
# File 'lib/chamomile/program.rb', line 60

def quit!
  @msgs.push(QuitEvent.new)
rescue ClosedQueueError
  # Already shut down
end

#runObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/chamomile/program.rb', line 35

def run
  @running = true

  if @options.catch_panics
    begin
      run_inner
    rescue StandardError => e
      teardown_terminal
      Chamomile.log("Panic: #{e.class}: #{e.message}\n#{e.backtrace&.first(10)&.join("\n")}", level: :error)
      raise
    end
  else
    run_inner
  end
ensure
  signal_done
end

#send_msg(msg) ⇒ Object



53
54
55
56
57
# File 'lib/chamomile/program.rb', line 53

def send_msg(msg)
  @msgs.push(msg)
rescue ClosedQueueError
  # Program has shut down
end

#waitObject

Block until the program finishes running



75
76
77
78
79
# File 'lib/chamomile/program.rb', line 75

def wait
  @done_mutex.synchronize do
    @done_cv.wait(@done_mutex) until @done
  end
end