Class: Chamomile::Renderer
- Inherits:
-
Object
- Object
- Chamomile::Renderer
- Defined in:
- lib/chamomile/renderer.rb
Overview
FPS-throttled terminal renderer with alt-screen diff, inline, and full modes.
Constant Summary collapse
- HIDE_CURSOR =
"\e[?25l"- SHOW_CURSOR =
"\e[?25h"- ALT_SCREEN_ON =
"\e[?1049h"- ALT_SCREEN_OFF =
"\e[?1049l"- CLEAR_SCREEN =
"\e[H\e[2J"- CURSOR_HOME =
"\e[H"- SYNC_START =
"\e[?2026h"- SYNC_END =
"\e[?2026l"
Instance Attribute Summary collapse
-
#height ⇒ Object
readonly
Returns the value of attribute height.
-
#width ⇒ Object
readonly
Returns the value of attribute width.
Instance Method Summary collapse
- #apply_cursor_shape(shape) ⇒ Object
- #clear ⇒ Object
- #enter_alt_screen ⇒ Object
- #enter_inline_mode ⇒ Object
- #exit_alt_screen ⇒ Object
-
#force_render(view_output) ⇒ Object
Force an immediate render, bypassing FPS throttle.
- #hide_cursor ⇒ Object
-
#initialize(output: $stdout, fps: 60) ⇒ Renderer
constructor
A new instance of Renderer.
- #move_cursor(row, col) ⇒ Object
- #println(str) ⇒ Object
-
#println_above(str) ⇒ Object
Print a line above the rendered area (for inline mode logging, etc.).
- #render(view_output) ⇒ Object
- #resize(width, height) ⇒ Object
- #show_cursor ⇒ Object
- #stop ⇒ Object
- #write_window_title(title) ⇒ Object
Constructor Details
#initialize(output: $stdout, fps: 60) ⇒ Renderer
Returns a new instance of Renderer.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/chamomile/renderer.rb', line 17 def initialize(output: $stdout, fps: 60) @output = output @alt_screen = false @inline = false @width = 80 @height = 24 @prev_lines = [] @inline_lines = 0 @mutex = Mutex.new @fps = fps @min_interval = fps.positive? ? 1.0 / fps : 0 @last_render = 0.0 @pending_view = nil @timer_thread = nil end |
Instance Attribute Details
#height ⇒ Object (readonly)
Returns the value of attribute height.
15 16 17 |
# File 'lib/chamomile/renderer.rb', line 15 def height @height end |
#width ⇒ Object (readonly)
Returns the value of attribute width.
15 16 17 |
# File 'lib/chamomile/renderer.rb', line 15 def width @width end |
Instance Method Details
#apply_cursor_shape(shape) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/chamomile/renderer.rb', line 111 def apply_cursor_shape(shape) code = case shape when :block then 2 when :underline then 4 when :bar then 6 when :blinking_block then 1 when :blinking_underline then 3 when :blinking_bar then 5 else 0 # default end @output.write("\e[#{code} q") end |
#clear ⇒ Object
80 81 82 83 |
# File 'lib/chamomile/renderer.rb', line 80 def clear @output.write(CLEAR_SCREEN) @output.flush end |
#enter_alt_screen ⇒ Object
33 34 35 36 37 |
# File 'lib/chamomile/renderer.rb', line 33 def enter_alt_screen @output.write(ALT_SCREEN_ON) @alt_screen = true @inline = false end |
#enter_inline_mode ⇒ Object
44 45 46 47 |
# File 'lib/chamomile/renderer.rb', line 44 def enter_inline_mode @inline = true @inline_lines = 0 end |
#exit_alt_screen ⇒ Object
39 40 41 42 |
# File 'lib/chamomile/renderer.rb', line 39 def exit_alt_screen @output.write(ALT_SCREEN_OFF) @alt_screen = false end |
#force_render(view_output) ⇒ Object
Force an immediate render, bypassing FPS throttle
129 130 131 132 133 134 135 136 137 |
# File 'lib/chamomile/renderer.rb', line 129 def force_render(view_output) view_string = resolve_view(view_output) @mutex.synchronize do flush_render(view_string) @last_render = Process.clock_gettime(Process::CLOCK_MONOTONIC) @pending_view = nil cancel_timer end end |
#hide_cursor ⇒ Object
49 50 51 |
# File 'lib/chamomile/renderer.rb', line 49 def hide_cursor @output.write(HIDE_CURSOR) end |
#move_cursor(row, col) ⇒ Object
107 108 109 |
# File 'lib/chamomile/renderer.rb', line 107 def move_cursor(row, col) @output.write("\e[#{row};#{col}H") end |
#println(str) ⇒ Object
85 86 87 |
# File 'lib/chamomile/renderer.rb', line 85 def println(str) @output.puts(str) end |
#println_above(str) ⇒ Object
Print a line above the rendered area (for inline mode logging, etc.)
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/chamomile/renderer.rb', line 90 def println_above(str) @mutex.synchronize do if @inline && @inline_lines.positive? buf = +"" buf << "\e[#{@inline_lines}A" # Move up buf << "\e[L" # Insert line buf << str buf << "\n" buf << "\e[#{@inline_lines}B" # Move back down @output.write(buf) @output.flush else @output.puts(str) end end end |
#render(view_output) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/chamomile/renderer.rb', line 62 def render(view_output) view_string = resolve_view(view_output) @mutex.synchronize do now = Process.clock_gettime(Process::CLOCK_MONOTONIC) elapsed = now - @last_render if elapsed >= @min_interval flush_render(view_string) @last_render = now @pending_view = nil cancel_timer else @pending_view = view_string schedule_timer(@min_interval - elapsed) end end end |
#resize(width, height) ⇒ Object
57 58 59 60 |
# File 'lib/chamomile/renderer.rb', line 57 def resize(width, height) @width = width @height = height end |
#show_cursor ⇒ Object
53 54 55 |
# File 'lib/chamomile/renderer.rb', line 53 def show_cursor @output.write(SHOW_CURSOR) end |
#stop ⇒ Object
139 140 141 142 143 |
# File 'lib/chamomile/renderer.rb', line 139 def stop @mutex.synchronize do cancel_timer end end |
#write_window_title(title) ⇒ Object
124 125 126 |
# File 'lib/chamomile/renderer.rb', line 124 def write_window_title(title) @output.write("\e]2;#{title}\a") end |