Class: Rufio::Renderer
- Inherits:
-
Object
- Object
- Rufio::Renderer
- Defined in:
- lib/rufio/renderer.rb
Overview
Renderer class - Front buffer for double buffering
Manages the front buffer (what’s currently displayed on screen) and performs differential rendering by comparing with the back buffer (Screen).
Features:
-
Diff rendering: Only updates changed lines
-
Cursor positioning: Uses ANSI escape codes
-
Flush control: Ensures all output is displayed
Instance Method Summary collapse
-
#clear ⇒ Object
Clear the front buffer and screen.
-
#initialize(width, height, output: STDOUT) ⇒ Renderer
constructor
A new instance of Renderer.
-
#render(screen) ⇒ Boolean
Render the screen with differential updates.
-
#resize(width, height) ⇒ Object
Resize the front buffer.
Constructor Details
#initialize(width, height, output: STDOUT) ⇒ Renderer
Returns a new instance of Renderer.
15 16 17 18 19 20 |
# File 'lib/rufio/renderer.rb', line 15 def initialize(width, height, output: STDOUT) @width = width @height = height @front = Array.new(height) { " " * width } @output = output end |
Instance Method Details
#clear ⇒ Object
Clear the front buffer and screen
76 77 78 79 80 81 82 |
# File 'lib/rufio/renderer.rb', line 76 def clear @front = Array.new(@height) { " " * @width } # Clear screen and move cursor to home @output.print "\e[2J\e[H" @output.flush end |
#render(screen) ⇒ Boolean
Render the screen with differential updates
26 27 28 29 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 55 56 57 58 59 |
# File 'lib/rufio/renderer.rb', line 26 def render(screen) # CPU最適化: Dirty rowsが空の場合は完全にスキップ dirty = screen.dirty_rows if dirty.empty? return false end # Phase1: Only process dirty rows (rows that have changed) # 全dirty rowsの出力を1つのバッファに積んでから単一の write() で書き出す。 # STDOUT sync=true 環境で print を行ごとに呼ぶと各行で即座にフラッシュされ # 中間状態が表示されてちらつきが発生するため、アトミックな更新を保証する。 buf = String.new("") rendered_count = 0 dirty.each do |y| line = screen.row(y) next if line == @front[y] # Skip if content is actually the same # Move cursor to line y (1-indexed) and buffer the line buf << "\e[#{y + 1};1H#{line}" @front[y] = line rendered_count += 1 end # Phase1: Clear dirty tracking after rendering screen.clear_dirty # 単一の write() でアトミックに出力し、その後 flush する if rendered_count > 0 @output.write(buf) @output.flush end true end |
#resize(width, height) ⇒ Object
Resize the front buffer
65 66 67 68 69 70 71 72 73 |
# File 'lib/rufio/renderer.rb', line 65 def resize(width, height) @width = width @height = height @front = Array.new(height) { " " * width } # Clear entire screen @output.print "\e[2J\e[H" @output.flush end |