""" Frame timing utilities — FPS control and precise timing. """ import time class FrameTimer: """Frame timer for consistent render loop timing.""" def __init__(self, target_frame_dt: float = 0.05): self.target_frame_dt = target_frame_dt self._frame_count = 0 self._start_time = time.monotonic() self._last_frame_time = self._start_time @property def fps(self) -> float: """Current FPS based on elapsed frames.""" elapsed = time.monotonic() - self._start_time if elapsed > 0: return self._frame_count / elapsed return 0.0 def sleep_until_next_frame(self) -> float: """Sleep to maintain target frame rate. Returns actual elapsed time.""" now = time.monotonic() elapsed = now - self._last_frame_time self._last_frame_time = now self._frame_count += 1 sleep_time = max(0, self.target_frame_dt - elapsed) if sleep_time > 0: time.sleep(sleep_time) return elapsed def reset(self) -> None: """Reset frame counter and start time.""" self._frame_count = 0 self._start_time = time.monotonic() self._last_frame_time = self._start_time def calculate_scroll_step( scroll_dur: float, view_height: int, padding: int = 15 ) -> float: """Calculate scroll step interval for smooth scrolling. Args: scroll_dur: Duration in seconds for one headline to scroll through view view_height: Terminal height in rows padding: Extra rows for off-screen content Returns: Time in seconds between scroll steps """ return scroll_dur / (view_height + padding) * 2