feature/capability-based-deps #53
@@ -51,6 +51,7 @@ def run_pipeline_mode(preset_name: str = "demo"):
|
|||||||
from engine.fetch import fetch_all, fetch_poetry, load_cache
|
from engine.fetch import fetch_all, fetch_poetry, load_cache
|
||||||
from engine.pipeline.adapters import (
|
from engine.pipeline.adapters import (
|
||||||
RenderStage,
|
RenderStage,
|
||||||
|
SourceItemsToBufferStage,
|
||||||
create_items_stage,
|
create_items_stage,
|
||||||
create_stage_from_display,
|
create_stage_from_display,
|
||||||
create_stage_from_effect,
|
create_stage_from_effect,
|
||||||
@@ -85,19 +86,29 @@ def run_pipeline_mode(preset_name: str = "demo"):
|
|||||||
)
|
)
|
||||||
|
|
||||||
print(" \033[38;5;245mFetching content...\033[0m")
|
print(" \033[38;5;245mFetching content...\033[0m")
|
||||||
cached = load_cache()
|
|
||||||
if cached:
|
# Handle special sources that don't need traditional fetching
|
||||||
items = cached
|
introspection_source = None
|
||||||
elif preset.source == "poetry":
|
if preset.source == "pipeline-inspect":
|
||||||
items, _, _ = fetch_poetry()
|
items = []
|
||||||
|
print(" \033[38;5;245mUsing pipeline introspection source\033[0m")
|
||||||
|
elif preset.source == "empty":
|
||||||
|
items = []
|
||||||
|
print(" \033[38;5;245mUsing empty source (no content)\033[0m")
|
||||||
else:
|
else:
|
||||||
items, _, _ = fetch_all()
|
cached = load_cache()
|
||||||
|
if cached:
|
||||||
|
items = cached
|
||||||
|
elif preset.source == "poetry":
|
||||||
|
items, _, _ = fetch_poetry()
|
||||||
|
else:
|
||||||
|
items, _, _ = fetch_all()
|
||||||
|
|
||||||
if not items:
|
if not items:
|
||||||
print(" \033[38;5;196mNo content available\033[0m")
|
print(" \033[38;5;196mNo content available\033[0m")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print(f" \033[38;5;82mLoaded {len(items)} items\033[0m")
|
print(f" \033[38;5;82mLoaded {len(items)} items\033[0m")
|
||||||
|
|
||||||
display = DisplayRegistry.create(preset.display)
|
display = DisplayRegistry.create(preset.display)
|
||||||
if not display:
|
if not display:
|
||||||
@@ -108,18 +119,45 @@ def run_pipeline_mode(preset_name: str = "demo"):
|
|||||||
|
|
||||||
effect_registry = get_registry()
|
effect_registry = get_registry()
|
||||||
|
|
||||||
pipeline.add_stage("source", create_items_stage(items, preset.source))
|
# Create source stage based on preset source type
|
||||||
pipeline.add_stage(
|
if preset.source == "pipeline-inspect":
|
||||||
"render",
|
from engine.data_sources.pipeline_introspection import (
|
||||||
RenderStage(
|
PipelineIntrospectionSource,
|
||||||
items,
|
)
|
||||||
width=80,
|
from engine.pipeline.adapters import DataSourceStage
|
||||||
height=24,
|
|
||||||
camera_speed=params.camera_speed,
|
introspection_source = PipelineIntrospectionSource(
|
||||||
camera_mode=preset.camera,
|
pipeline=None, # Will be set after pipeline.build()
|
||||||
firehose_enabled=params.firehose_enabled,
|
viewport_width=80,
|
||||||
),
|
viewport_height=24,
|
||||||
)
|
)
|
||||||
|
pipeline.add_stage(
|
||||||
|
"source", DataSourceStage(introspection_source, name="pipeline-inspect")
|
||||||
|
)
|
||||||
|
elif preset.source == "empty":
|
||||||
|
from engine.data_sources.sources import EmptyDataSource
|
||||||
|
from engine.pipeline.adapters import DataSourceStage
|
||||||
|
|
||||||
|
empty_source = EmptyDataSource(width=80, height=24)
|
||||||
|
pipeline.add_stage("source", DataSourceStage(empty_source, name="empty"))
|
||||||
|
else:
|
||||||
|
pipeline.add_stage("source", create_items_stage(items, preset.source))
|
||||||
|
|
||||||
|
# Add appropriate render stage
|
||||||
|
if preset.source in ("pipeline-inspect", "empty"):
|
||||||
|
pipeline.add_stage("render", SourceItemsToBufferStage(name="items-to-buffer"))
|
||||||
|
else:
|
||||||
|
pipeline.add_stage(
|
||||||
|
"render",
|
||||||
|
RenderStage(
|
||||||
|
items,
|
||||||
|
width=80,
|
||||||
|
height=24,
|
||||||
|
camera_speed=params.camera_speed,
|
||||||
|
camera_mode=preset.camera,
|
||||||
|
firehose_enabled=params.firehose_enabled,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
for effect_name in preset.effects:
|
for effect_name in preset.effects:
|
||||||
effect = effect_registry.get(effect_name)
|
effect = effect_registry.get(effect_name)
|
||||||
@@ -132,6 +170,10 @@ def run_pipeline_mode(preset_name: str = "demo"):
|
|||||||
|
|
||||||
pipeline.build()
|
pipeline.build()
|
||||||
|
|
||||||
|
# For pipeline-inspect, set the pipeline after build to avoid circular dependency
|
||||||
|
if introspection_source is not None:
|
||||||
|
introspection_source.set_pipeline(pipeline)
|
||||||
|
|
||||||
if not pipeline.initialize():
|
if not pipeline.initialize():
|
||||||
print(" \033[38;5;196mFailed to initialize pipeline\033[0m")
|
print(" \033[38;5;196mFailed to initialize pipeline\033[0m")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -162,7 +204,7 @@ def run_pipeline_mode(preset_name: str = "demo"):
|
|||||||
|
|
||||||
result = pipeline.execute(items)
|
result = pipeline.execute(items)
|
||||||
if result.success:
|
if result.success:
|
||||||
display.show(result.data)
|
display.show(result.data, border=params.border)
|
||||||
|
|
||||||
if hasattr(display, "is_quit_requested") and display.is_quit_requested():
|
if hasattr(display, "is_quit_requested") and display.is_quit_requested():
|
||||||
if hasattr(display, "clear_quit_request"):
|
if hasattr(display, "clear_quit_request"):
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ class MultiDisplay:
|
|||||||
for d in self.displays:
|
for d in self.displays:
|
||||||
d.init(width, height, reuse=reuse)
|
d.init(width, height, reuse=reuse)
|
||||||
|
|
||||||
def show(self, buffer: list[str]) -> None:
|
def show(self, buffer: list[str], border: bool = False) -> None:
|
||||||
for d in self.displays:
|
for d in self.displays:
|
||||||
d.show(buffer)
|
d.show(buffer, border=border)
|
||||||
|
|
||||||
def clear(self) -> None:
|
def clear(self) -> None:
|
||||||
for d in self.displays:
|
for d in self.displays:
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class Display(Protocol):
|
|||||||
"""Initialize display with dimensions."""
|
"""Initialize display with dimensions."""
|
||||||
...
|
...
|
||||||
|
|
||||||
def show(self, buffer: list[str]) -> None:
|
def show(self, buffer: list[str], border: bool = False) -> None:
|
||||||
"""Show buffer on display."""
|
"""Show buffer on display."""
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|||||||
@@ -165,10 +165,10 @@ class TestMultiDisplay:
|
|||||||
multi = MultiDisplay([mock_display1, mock_display2])
|
multi = MultiDisplay([mock_display1, mock_display2])
|
||||||
|
|
||||||
buffer = ["line1", "line2"]
|
buffer = ["line1", "line2"]
|
||||||
multi.show(buffer)
|
multi.show(buffer, border=False)
|
||||||
|
|
||||||
mock_display1.show.assert_called_once_with(buffer)
|
mock_display1.show.assert_called_once_with(buffer, border=False)
|
||||||
mock_display2.show.assert_called_once_with(buffer)
|
mock_display2.show.assert_called_once_with(buffer, border=False)
|
||||||
|
|
||||||
def test_clear_forwards_to_all_displays(self):
|
def test_clear_forwards_to_all_displays(self):
|
||||||
"""clear forwards to all displays."""
|
"""clear forwards to all displays."""
|
||||||
|
|||||||
Reference in New Issue
Block a user