class Chamomile::Program
Main event loop — wires up Model, Renderer, and InputReader.
Public Class Methods
Source
# 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
Public Instance Methods
Source
# File lib/chamomile/program.rb, line 67 def kill! @running = false @msgs.push(QuitEvent.new) rescue ClosedQueueError # Already shut down end
Kill immediately — no final message, no cleanup render
Source
# File lib/chamomile/program.rb, line 60 def quit! @msgs.push(QuitEvent.new) rescue ClosedQueueError # Already shut down end
Quit gracefully — model gets a final QuitEvent
Source
# 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
Source
# File lib/chamomile/program.rb, line 53 def send_msg(msg) @msgs.push(msg) rescue ClosedQueueError # Program has shut down end
Source
# File lib/chamomile/program.rb, line 75 def wait @done_mutex.synchronize do @done_cv.wait(@done_mutex) until @done end end
Block until the program finishes running