54 lines
1.6 KiB
Python
54 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
from pygui.backend.models.frame import Frame
|
|
from pygui.backend.wafer.zwafer_models import ZWaferData
|
|
|
|
|
|
def frames_from_wafer_data(data: ZWaferData, records) -> list[Frame]:
|
|
"""Build Frames from parsed DataRecords (records = list[DataRecord].)"""
|
|
return [Frame(seq=i, time=r.time, values=list(r.values)) for i, r in enumerate(records)]
|
|
|
|
class FramePlayer:
|
|
def __init__(self) -> None:
|
|
self._frames: list[Frame] =[]
|
|
self._i =0
|
|
|
|
def load(self, frames: list[Frame]) -> "FramePlayer":
|
|
self._frames = frames
|
|
self._i = 0
|
|
return self
|
|
|
|
@property
|
|
def total(self) -> int:
|
|
return len(self._frames)
|
|
|
|
@property
|
|
def index(self) -> int:
|
|
return self._i
|
|
|
|
@property
|
|
def at_end(self) -> bool:
|
|
return self._i >= len(self._frames) -1
|
|
|
|
def current(self) -> Frame | None:
|
|
if not self._frames:
|
|
return None
|
|
return self._frames[self._i]
|
|
|
|
def _clamp(self, i:int):
|
|
return max(0, min(i, len(self._frames) - 1)) if self._frames else 0
|
|
|
|
def step(self, delta: int) -> "FramePlayer":
|
|
self._i = self._clamp(self._i + delta)
|
|
return self
|
|
|
|
def seek(self, i: int) -> "FramePlayer":
|
|
self._i = self._clamp(i)
|
|
return self
|
|
|
|
def next_frame_ms(self) -> float:
|
|
"""Wall-clock ms until the next frame based on recorded timestamps; 0 if at end."""
|
|
if self._i + 1 >= len(self._frames):
|
|
return 0.0
|
|
return (self._frames[self._i + 1].time - self._frames[self._i].time) * 1000.0
|