72 lines
2.4 KiB
Python
72 lines
2.4 KiB
Python
import time
|
|
|
|
from engine.effects.performance import PerformanceMonitor, get_monitor
|
|
from engine.effects.registry import EffectRegistry
|
|
from engine.effects.types import EffectContext
|
|
|
|
|
|
class EffectChain:
|
|
def __init__(
|
|
self, registry: EffectRegistry, monitor: PerformanceMonitor | None = None
|
|
):
|
|
self._registry = registry
|
|
self._order: list[str] = []
|
|
self._monitor = monitor
|
|
|
|
def _get_monitor(self) -> PerformanceMonitor:
|
|
if self._monitor is not None:
|
|
return self._monitor
|
|
return get_monitor()
|
|
|
|
def set_order(self, names: list[str]) -> None:
|
|
self._order = list(names)
|
|
|
|
def get_order(self) -> list[str]:
|
|
return self._order.copy()
|
|
|
|
def add_effect(self, name: str, position: int | None = None) -> bool:
|
|
if name not in self._registry.list_all():
|
|
return False
|
|
if position is None:
|
|
self._order.append(name)
|
|
else:
|
|
self._order.insert(position, name)
|
|
return True
|
|
|
|
def remove_effect(self, name: str) -> bool:
|
|
if name in self._order:
|
|
self._order.remove(name)
|
|
return True
|
|
return False
|
|
|
|
def reorder(self, new_order: list[str]) -> bool:
|
|
all_plugins = set(self._registry.list_all().keys())
|
|
if not all(name in all_plugins for name in new_order):
|
|
return False
|
|
self._order = list(new_order)
|
|
return True
|
|
|
|
def process(self, buf: list[str], ctx: EffectContext) -> list[str]:
|
|
monitor = self._get_monitor()
|
|
frame_number = ctx.frame_number
|
|
monitor.start_frame(frame_number)
|
|
|
|
frame_start = time.perf_counter()
|
|
result = list(buf)
|
|
for name in self._order:
|
|
plugin = self._registry.get(name)
|
|
if plugin and plugin.config.enabled:
|
|
chars_in = sum(len(line) for line in result)
|
|
effect_start = time.perf_counter()
|
|
try:
|
|
result = plugin.process(result, ctx)
|
|
except Exception:
|
|
plugin.config.enabled = False
|
|
elapsed = time.perf_counter() - effect_start
|
|
chars_out = sum(len(line) for line in result)
|
|
monitor.record_effect(name, elapsed * 1000, chars_in, chars_out)
|
|
|
|
total_elapsed = time.perf_counter() - frame_start
|
|
monitor.end_frame(frame_number, total_elapsed * 1000)
|
|
return result
|