76 lines
1.6 KiB
Python
76 lines
1.6 KiB
Python
import bisect
|
|
|
|
|
|
class ReplayController:
|
|
|
|
def __init__(self, journal):
|
|
|
|
self.journal = journal
|
|
self.index = 0
|
|
self.playing = False
|
|
|
|
# pre-sorted events for deterministic replay
|
|
self.timeline = sorted(
|
|
journal.events,
|
|
key=lambda e: e["ts"]
|
|
)
|
|
|
|
# -------------------------
|
|
# CURRENT EVENT
|
|
# -------------------------
|
|
def current(self):
|
|
|
|
if 0 <= self.index < len(self.timeline):
|
|
return self.timeline[self.index]
|
|
|
|
return None
|
|
|
|
# -------------------------
|
|
# STEP FORWARD
|
|
# -------------------------
|
|
def step(self):
|
|
|
|
if self.index < len(self.timeline) - 1:
|
|
self.index += 1
|
|
|
|
return self.current()
|
|
|
|
# -------------------------
|
|
# STEP BACKWARD
|
|
# -------------------------
|
|
def back(self):
|
|
|
|
if self.index > 0:
|
|
self.index -= 1
|
|
|
|
return self.current()
|
|
|
|
# -------------------------
|
|
# SEEK BY TIMESTAMP
|
|
# -------------------------
|
|
def seek(self, timestamp):
|
|
|
|
times = [e["ts"] for e in self.timeline]
|
|
|
|
self.index = bisect.bisect_left(times, timestamp)
|
|
|
|
return self.current()
|
|
|
|
# -------------------------
|
|
# RESET
|
|
# -------------------------
|
|
def reset(self):
|
|
|
|
self.index = 0
|
|
|
|
return self.current()
|
|
|
|
# -------------------------
|
|
# PLAY (ITERATOR MODE)
|
|
# -------------------------
|
|
def play(self):
|
|
|
|
for i in range(self.index, len(self.timeline)):
|
|
self.index = i
|
|
yield self.timeline[i]
|