forked from genewildish/Mainline
feat(pipeline): improve new pipeline architecture
- Add TransformDataSource for filtering/mapping source items - Add MetricsDataSource for rendering live pipeline metrics as ASCII art - Fix display stage registration in StageRegistry - Register sources with both class name and simple name aliases - Fix DisplayStage.init() to pass reuse parameter - Simplify create_default_pipeline to use DataSourceStage wrapper - Set pygame as default display - Remove old pipeline tasks from mise.toml - Add tests for new pipeline architecture
This commit is contained in:
@@ -183,7 +183,7 @@ class DisplayStage(Stage):
|
||||
def init(self, ctx: PipelineContext) -> bool:
|
||||
w = ctx.params.viewport_width if ctx.params else 80
|
||||
h = ctx.params.viewport_height if ctx.params else 24
|
||||
result = self._display.init(w, h)
|
||||
result = self._display.init(w, h, reuse=False)
|
||||
return result is not False
|
||||
|
||||
def process(self, data: Any, ctx: PipelineContext) -> Any:
|
||||
|
||||
@@ -303,18 +303,14 @@ def create_pipeline_from_params(params: PipelineParams) -> Pipeline:
|
||||
|
||||
def create_default_pipeline() -> Pipeline:
|
||||
"""Create a default pipeline with all standard components."""
|
||||
from engine.pipeline.adapters import DataSourceStage
|
||||
from engine.sources_v2 import HeadlinesDataSource
|
||||
|
||||
pipeline = Pipeline()
|
||||
|
||||
# Add source stage
|
||||
source = StageRegistry.create("source", "headlines")
|
||||
if source:
|
||||
pipeline.add_stage("source", source)
|
||||
|
||||
# Add effect stages
|
||||
for effect_name in ["noise", "fade", "glitch", "firehose", "hud"]:
|
||||
effect = StageRegistry.create("effect", effect_name)
|
||||
if effect:
|
||||
pipeline.add_stage(f"effect_{effect_name}", effect)
|
||||
# Add source stage (wrapped as Stage)
|
||||
source = HeadlinesDataSource()
|
||||
pipeline.add_stage("source", DataSourceStage(source, name="headlines"))
|
||||
|
||||
# Add display stage
|
||||
display = StageRegistry.create("display", "terminal")
|
||||
|
||||
@@ -28,7 +28,7 @@ class StageRegistry:
|
||||
cls._categories[category] = {}
|
||||
|
||||
# Use class name as key
|
||||
key = stage_class.__name__
|
||||
key = getattr(stage_class, "__name__", stage_class.__class__.__name__)
|
||||
cls._categories[category][key] = stage_class
|
||||
|
||||
@classmethod
|
||||
@@ -90,6 +90,10 @@ def discover_stages() -> None:
|
||||
StageRegistry.register("source", HeadlinesDataSource)
|
||||
StageRegistry.register("source", PoetryDataSource)
|
||||
StageRegistry.register("source", PipelineDataSource)
|
||||
|
||||
StageRegistry._categories["source"]["headlines"] = HeadlinesDataSource
|
||||
StageRegistry._categories["source"]["poetry"] = PoetryDataSource
|
||||
StageRegistry._categories["source"]["pipeline"] = PipelineDataSource
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
@@ -98,14 +102,48 @@ def discover_stages() -> None:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
from engine.display import Display # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
# Register display stages
|
||||
_register_display_stages()
|
||||
|
||||
StageRegistry._discovered = True
|
||||
|
||||
|
||||
def _register_display_stages() -> None:
|
||||
"""Register display backends as stages."""
|
||||
try:
|
||||
from engine.display import DisplayRegistry
|
||||
except ImportError:
|
||||
return
|
||||
|
||||
DisplayRegistry.initialize()
|
||||
|
||||
for backend_name in DisplayRegistry.list_backends():
|
||||
factory = _DisplayStageFactory(backend_name)
|
||||
StageRegistry._categories.setdefault("display", {})[backend_name] = factory
|
||||
|
||||
|
||||
class _DisplayStageFactory:
|
||||
"""Factory that creates DisplayStage instances for a specific backend."""
|
||||
|
||||
def __init__(self, backend_name: str):
|
||||
self._backend_name = backend_name
|
||||
|
||||
def __call__(self):
|
||||
from engine.display import DisplayRegistry
|
||||
from engine.pipeline.adapters import DisplayStage
|
||||
|
||||
display = DisplayRegistry.create(self._backend_name)
|
||||
if display is None:
|
||||
raise RuntimeError(
|
||||
f"Failed to create display backend: {self._backend_name}"
|
||||
)
|
||||
return DisplayStage(display, name=self._backend_name)
|
||||
|
||||
@property
|
||||
def __name__(self) -> str:
|
||||
return self._backend_name.capitalize() + "Stage"
|
||||
|
||||
|
||||
# Convenience functions
|
||||
def register_source(stage_class: type[Stage]) -> None:
|
||||
"""Register a source stage."""
|
||||
|
||||
Reference in New Issue
Block a user