replay: delay per complete frame instead of per chunk

ReplayPacer (MsgListener+MsgTalker) sits between packetizer output and
downstream listeners; sleeps after each complete NMEA/UBX frame before
forwarding. FileBackend no longer owns the delay — it reads as fast as
possible and the pacer provides back-pressure on the same thread.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-25 13:11:40 +02:00
co-authored by Claude Sonnet 4.6
parent ff686b64f7
commit dce570460e
4 changed files with 58 additions and 26 deletions
+13 -3
View File
@@ -153,6 +153,7 @@ class ReceiverManager(QObject):
from listeners import NavSatQtListener, GsaQtListener
from backend.serial_backend import SerialBackend
from backend.file_backend import FileBackend
from msg.replay_pacer import ReplayPacer
config = self._configs.get(rid)
state = self._states.get(rid)
@@ -168,7 +169,7 @@ class ReceiverManager(QObject):
elif config.conn_type == 'serial':
backend = SerialBackend(config.serial_port, config.baud_rate)
else:
backend = FileBackend([config.file_path], delay=config.delay)
backend = FileBackend([config.file_path])
backend.register_xcvr(xcvr)
@@ -177,10 +178,19 @@ class ReceiverManager(QObject):
xcvr.register_listener(nmea_pkt)
xcvr.register_listener(ubx_pkt)
ubx_pkt.register_listener(
if config.conn_type == 'file' and config.delay > 0:
nmea_sink = ReplayPacer(config.delay)
ubx_sink = ReplayPacer(config.delay)
nmea_pkt.register_listener(nmea_sink)
ubx_pkt.register_listener(ubx_sink)
else:
nmea_sink = nmea_pkt
ubx_sink = ubx_pkt
ubx_sink.register_listener(
NavSatQtListener(lambda sats, r=rid: self._on_sat(r, sats))
)
nmea_pkt.register_listener(
nmea_sink.register_listener(
GsaQtListener(rid, lambda p, t, r=rid: self._on_pdop(r, p, t))
)