feat(examples): Add default visualization script

Add script that renders the standard Mainline visualization using the
graph-based DSL. This demonstrates the default behavior with:

- Headlines source data
- Scroll camera mode
- Terminal display
- Classic effects: noise, fade, glitch, firehose

Files added:
- examples/default_visualization.py - Main script
- examples/default_visualization.toml - TOML configuration
- examples/README.md - Documentation for all examples

Usage:
  python examples/default_visualization.py
This commit is contained in:
2026-03-21 19:43:52 -07:00
parent 613752ee20
commit 38bc9a2c13
3 changed files with 212 additions and 0 deletions

87
examples/README.md Normal file
View File

@@ -0,0 +1,87 @@
# Examples
This directory contains example scripts demonstrating how to use Mainline's features.
## Default Visualization
**`default_visualization.py`** - Renders the standard Mainline visualization using the graph-based DSL.
```bash
python examples/default_visualization.py
```
This script demonstrates:
- Graph-based pipeline configuration using TOML
- Default Mainline behavior: headlines source, scroll camera, terminal display
- Classic effects: noise, fade, glitch, firehose
- One-shot rendering (prints to stdout)
### Configuration
The visualization is defined in `default_visualization.toml`:
```toml
[nodes.source]
type = "source"
source = "headlines"
[nodes.camera]
type = "camera"
mode = "scroll"
speed = 1.0
[nodes.noise]
type = "effect"
effect = "noise"
intensity = 0.3
[nodes.fade]
type = "effect"
effect = "fade"
intensity = 0.5
[nodes.display]
type = "display"
backend = "terminal"
[connections]
list = ["source -> camera -> noise -> fade -> display"]
```
## Graph DSL Demonstration
**`graph_dsl_demo.py`** - Demonstrates the graph-based DSL in multiple ways:
```bash
python examples/graph_dsl_demo.py
```
Shows:
- Imperative Python API for building graphs
- Dictionary-based API
- Graph validation (cycles, disconnected nodes)
- Different node types and configurations
## Integration Test
**`test_graph_integration.py`** - Tests the graph system with actual pipeline execution:
```bash
python examples/test_graph_integration.py
```
Verifies:
- Graph loading from TOML
- Pipeline execution
- Output rendering
- Comparison with preset-based pipelines
## Other Demos
- **`demo-lfo-effects.py`** - LFO modulation of effect intensities (Pygame display)
- **`demo_oscilloscope.py`** - Oscilloscope visualization
- **`demo_image_oscilloscope.py`** - Image-based oscilloscope
## Graph DSL Reference
See `docs/graph-dsl.md` for complete documentation on the graph-based DSL syntax.

View File

@@ -0,0 +1,86 @@
#!/usr/bin/env python3
"""
Default Mainline Visualization
Renders the standard Mainline visualization using the graph-based DSL.
This demonstrates the default behavior: headlines source, scroll camera,
terminal display, with classic effects (noise, fade, glitch, firehose).
Usage:
python examples/default_visualization.py
The visualization will be rendered once and printed to stdout.
"""
import sys
from pathlib import Path
# Add the project root to Python path
sys.path.insert(0, str(Path(__file__).parent.parent))
from engine.effects.plugins import discover_plugins
from engine.pipeline.graph_toml import load_pipeline_from_toml
from engine.pipeline.params import PipelineParams
def main():
"""Render the default Mainline visualization."""
print("Loading default Mainline visualization...")
print("=" * 70)
# Discover effect plugins
discover_plugins()
# Path to the TOML configuration
toml_path = Path(__file__).parent / "default_visualization.toml"
if not toml_path.exists():
print(f"Error: Configuration file not found: {toml_path}", file=sys.stderr)
sys.exit(1)
# Load pipeline from TOML configuration
try:
pipeline = load_pipeline_from_toml(
toml_path, viewport_width=80, viewport_height=24
)
print(f"✓ Pipeline loaded from {toml_path.name}")
print(f" Stages: {list(pipeline._stages.keys())}")
except Exception as e:
print(f"Error loading pipeline: {e}", file=sys.stderr)
sys.exit(1)
# Initialize the pipeline
if not pipeline.initialize():
print("Error: Failed to initialize pipeline", file=sys.stderr)
sys.exit(1)
print("✓ Pipeline initialized")
# Set up execution context
ctx = pipeline.context
ctx.terminal_width = 80
ctx.terminal_height = 24
# Create params for the execution
params = PipelineParams(viewport_width=80, viewport_height=24)
ctx.params = params
# Execute the pipeline (empty items list - source will provide content)
print("Executing pipeline...")
result = pipeline.execute([])
# Render output
if result.success:
print("=" * 70)
print("Visualization Output:")
print("=" * 70)
for i, line in enumerate(result.data):
print(line)
print("=" * 70)
print(f"✓ Successfully rendered {len(result.data)} lines")
else:
print(f"Error: Pipeline execution failed: {result.error}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,39 @@
# Default Mainline Visualization
# This configuration renders the standard Mainline visualization using the
# graph-based DSL. It matches the upstream-default preset behavior.
[nodes.source]
type = "source"
source = "headlines"
[nodes.camera]
type = "camera"
mode = "scroll"
speed = 1.0
[nodes.noise]
type = "effect"
effect = "noise"
intensity = 0.3
[nodes.fade]
type = "effect"
effect = "fade"
intensity = 0.5
[nodes.glitch]
type = "effect"
effect = "glitch"
intensity = 0.2
[nodes.firehose]
type = "effect"
effect = "firehose"
intensity = 0.4
[nodes.display]
type = "display"
backend = "terminal"
[connections]
list = ["source -> camera -> noise -> fade -> glitch -> firehose -> display"]