forked from genewildish/Mainline
chore(pipeline): improve pipeline architecture
- Add capability-based dependency resolution with prefix matching - Add EffectPluginStage with sensor binding support - Add CameraStage adapter for camera integration - Add DisplayStage adapter for display integration - Add Pipeline metrics collection - Add deprecation notices to legacy modules - Update app.py with pipeline integration
This commit is contained in:
@@ -26,8 +26,20 @@ class Display(Protocol):
|
||||
- clear(): Clear the display
|
||||
- cleanup(): Shutdown the display
|
||||
|
||||
Optional methods for keyboard input:
|
||||
- is_quit_requested(): Returns True if user pressed Ctrl+C/Q or Escape
|
||||
- clear_quit_request(): Clears the quit request flag
|
||||
|
||||
The reuse flag allows attaching to an existing display instance
|
||||
rather than creating a new window/connection.
|
||||
|
||||
Keyboard input support by backend:
|
||||
- terminal: No native input (relies on signal handler for Ctrl+C)
|
||||
- pygame: Supports Ctrl+C, Ctrl+Q, Escape for graceful shutdown
|
||||
- websocket: No native input (relies on signal handler for Ctrl+C)
|
||||
- sixel: No native input (relies on signal handler for Ctrl+C)
|
||||
- null: No native input
|
||||
- kitty: Supports Ctrl+C, Ctrl+Q, Escape (via pygame-like handling)
|
||||
"""
|
||||
|
||||
width: int
|
||||
|
||||
@@ -37,6 +37,7 @@ class PygameDisplay:
|
||||
self._screen = None
|
||||
self._font = None
|
||||
self._resized = False
|
||||
self._quit_requested = False
|
||||
|
||||
def _get_font_path(self) -> str | None:
|
||||
"""Get font path for rendering."""
|
||||
@@ -130,8 +131,6 @@ class PygameDisplay:
|
||||
self._initialized = True
|
||||
|
||||
def show(self, buffer: list[str]) -> None:
|
||||
import sys
|
||||
|
||||
if not self._initialized or not self._pygame:
|
||||
return
|
||||
|
||||
@@ -139,7 +138,15 @@ class PygameDisplay:
|
||||
|
||||
for event in self._pygame.event.get():
|
||||
if event.type == self._pygame.QUIT:
|
||||
sys.exit(0)
|
||||
self._quit_requested = True
|
||||
elif event.type == self._pygame.KEYDOWN:
|
||||
if event.key in (self._pygame.K_ESCAPE, self._pygame.K_c):
|
||||
if event.key == self._pygame.K_c and not (
|
||||
event.mod & self._pygame.KMOD_LCTRL
|
||||
or event.mod & self._pygame.KMOD_RCTRL
|
||||
):
|
||||
continue
|
||||
self._quit_requested = True
|
||||
elif event.type == self._pygame.VIDEORESIZE:
|
||||
self.window_width = event.w
|
||||
self.window_height = event.h
|
||||
@@ -210,3 +217,20 @@ class PygameDisplay:
|
||||
def reset_state(cls) -> None:
|
||||
"""Reset pygame state - useful for testing."""
|
||||
cls._pygame_initialized = False
|
||||
|
||||
def is_quit_requested(self) -> bool:
|
||||
"""Check if user requested quit (Ctrl+C, Ctrl+Q, or Escape).
|
||||
|
||||
Returns True if the user pressed Ctrl+C, Ctrl+Q, or Escape.
|
||||
The main loop should check this and raise KeyboardInterrupt.
|
||||
"""
|
||||
return self._quit_requested
|
||||
|
||||
def clear_quit_request(self) -> bool:
|
||||
"""Clear the quit request flag after handling.
|
||||
|
||||
Returns the previous quit request state.
|
||||
"""
|
||||
was_requested = self._quit_requested
|
||||
self._quit_requested = False
|
||||
return was_requested
|
||||
|
||||
Reference in New Issue
Block a user