feat: implement 6-stage render pipeline #317

Merged
freemo merged 2 commits from feature/m2-render-pipeline into master 2026-03-16 19:53:40 +00:00
Owner

Summary

  • Implements a modular 6-stage render pipeline that processes RenderOps into terminal output
  • Each stage (Router, Formatter, Layout, Dirty Check, Ncurses, Composite) is a separate class for testability
  • Includes comprehensive unit and integration tests

Changes

New Files

  • lib/aethyr/core/render/render_pipeline.rb - Main orchestrator
  • lib/aethyr/core/render/pipeline_stages/router_stage.rb - Routes ops to target windows
  • lib/aethyr/core/render/pipeline_stages/formatter_stage.rb - Applies ANSI colors, word wrapping
  • lib/aethyr/core/render/pipeline_stages/layout_stage.rb - Solves layout constraints
  • lib/aethyr/core/render/pipeline_stages/dirty_check_stage.rb - Compares frames, marks clean windows
  • lib/aethyr/core/render/pipeline_stages/ncurses_stage.rb - Writes to ncurses buffers
  • lib/aethyr/core/render/pipeline_stages/composite_stage.rb - Calls doupdate per frame

Tests

  • tests/unit/render_pipeline.feature - 30 unit test scenarios
  • tests/integration/render_pipeline_integration.feature - 10 integration scenarios

Testing

  • All 40 new test scenarios pass
  • Rubocop passes with no offenses

Closes #307

## Summary - Implements a modular 6-stage render pipeline that processes RenderOps into terminal output - Each stage (Router, Formatter, Layout, Dirty Check, Ncurses, Composite) is a separate class for testability - Includes comprehensive unit and integration tests ## Changes ### New Files - `lib/aethyr/core/render/render_pipeline.rb` - Main orchestrator - `lib/aethyr/core/render/pipeline_stages/router_stage.rb` - Routes ops to target windows - `lib/aethyr/core/render/pipeline_stages/formatter_stage.rb` - Applies ANSI colors, word wrapping - `lib/aethyr/core/render/pipeline_stages/layout_stage.rb` - Solves layout constraints - `lib/aethyr/core/render/pipeline_stages/dirty_check_stage.rb` - Compares frames, marks clean windows - `lib/aethyr/core/render/pipeline_stages/ncurses_stage.rb` - Writes to ncurses buffers - `lib/aethyr/core/render/pipeline_stages/composite_stage.rb` - Calls doupdate per frame ### Tests - `tests/unit/render_pipeline.feature` - 30 unit test scenarios - `tests/integration/render_pipeline_integration.feature` - 10 integration scenarios ## Testing - All 40 new test scenarios pass - Rubocop passes with no offenses Closes #307
Implements the RenderOp value object class for the UI render pipeline as
specified in issue #304. RenderOps are immutable value objects that describe
rendering instructions without specifying how they should be rendered.

Key features:
- Immutable value objects (frozen after creation) with type, window, and data
- Seven core RenderOp types: text_append, map_refresh, bar_update,
  prompt_update, window_clear, overlay_show, overlay_hide
- Factory methods for convenient construction: RenderOp.text_append(),
  RenderOp.bar_update(), etc.
- Data validation per type (required fields are enforced)
- Equality comparison support (== and hash for use as hash keys)
- to_h serialization for logging and debugging
- Comprehensive YARD documentation

Testing:
- 36 Cucumber scenarios covering all factory methods, immutability,
  validation, equality, and type constants
- 3 integration scenarios for realistic usage patterns

ISSUES CLOSED: #304
Implement a modular 6-stage render pipeline that processes RenderOps
into terminal output:

1. Router - Routes ops to target windows, groups by window
2. Formatter - Applies ANSI colors, word wrapping to window width
3. Layout - Solves layout constraints for window positions/sizes
4. Dirty Check - Compares against previous frame, marks clean windows
5. Ncurses - Writes dirty windows to ncurses buffers (wnoutrefresh)
6. Composite - Calls doupdate once per frame

Each stage is a separate class for testability. The pipeline handles
empty op batches gracefully (no-op frame) and supports terminal resize.

Includes unit tests covering all 6 stages and integration tests for
the full pipeline flow.
freemo force-pushed feature/m2-render-pipeline from 8660214653 to c2a16006b0 2026-03-16 16:55:42 +00:00 Compare
freemo force-pushed feature/m2-render-pipeline from c2a16006b0 to 3d6e996458 2026-03-16 17:30:51 +00:00 Compare
freemo force-pushed feature/m2-render-pipeline from 3d6e996458 to e6ed5d65f6 2026-03-16 19:53:25 +00:00 Compare
freemo merged commit e6ed5d65f6 into master 2026-03-16 19:53:40 +00:00
freemo deleted branch feature/m2-render-pipeline 2026-03-16 19:53:40 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: aethyr/Aethyr#317
No description provided.