Files
RFP_Infinity-Vis/app/output/base.py

71 lines
1.8 KiB
Python

from __future__ import annotations
from abc import ABC, abstractmethod
from dataclasses import dataclass
from app.config.models import InfinityMirrorConfig
from app.core.types import PreviewFrame
@dataclass
class OutputResult:
ok: bool
message: str = ""
packets_sent: int = 0
device_count: int = 0
@dataclass(frozen=True)
class ControllerMetrics:
fps: float | None = None
live_devices: int = 0
sampled_devices: int = 0
total_devices: int = 0
source: str = ""
@dataclass(frozen=True)
class OutputDiagnostics:
backend_id: str
backend_name: str
output_enabled: bool
worker_running: bool
target_fps: float
send_fps: float = 0.0
last_send_time_ms: float = 0.0
frames_submitted: int = 0
frames_sent: int = 0
stale_frame_drops: int = 0
send_failures: int = 0
packets_last_frame: int = 0
devices_last_frame: int = 0
packets_sent_total: int = 0
last_message: str = ""
send_budget_misses: int = 0
last_schedule_slip_ms: float = 0.0
controller_fps: float | None = None
controller_live_devices: int = 0
controller_sampled_devices: int = 0
controller_total_devices: int = 0
controller_source: str = ""
class OutputBackend(ABC):
backend_id: str
display_name: str
supports_live_output: bool = False
def start(self) -> None:
"""Hook for backends that need to allocate resources."""
def stop(self) -> None:
"""Hook for backends that need to release resources."""
def controller_metrics(self, config: InfinityMirrorConfig) -> ControllerMetrics | None:
"""Optional hook for backends that can report controller-side receive metrics."""
return None
@abstractmethod
def send_frame(self, config: InfinityMirrorConfig, frame: PreviewFrame) -> OutputResult:
raise NotImplementedError