Skip to content

Commit d7bf98b

Browse files
committed
Fix recording start flag and add worker test
Set `_processor_recording_started_notified` immediately after a successful recording-start hook callback so the UI tracks notification state correctly and avoids repeated notifications. Also add a unit test that verifies `ProcessorSpec` processors are instantiated on the `DLCLiveWorker` thread, wired into `DLCLive`, and properly stopped/cleared when resetting the processor.
1 parent 2181580 commit d7bf98b

2 files changed

Lines changed: 101 additions & 0 deletions

File tree

‎dlclivegui/gui/main_window.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,6 +1966,7 @@ def _notify_processor_recording_started(self, context: dict) -> bool:
19661966

19671967
try:
19681968
hook(context)
1969+
self._processor_recording_started_notified = True
19691970
logger.info("Notified processor recording started: %s", context)
19701971
return True
19711972
except Exception:

‎tests/services/test_dlc_processor.py‎

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
from __future__ import annotations
22

33
import queue
4+
import threading
45

56
import numpy as np
67
import pytest
78

89
from dlclivegui.config import DLCProcessorSettings
910

1011
# from dlclivegui.config import DLCProcessorSettings
12+
from dlclivegui.processors.processor_utils import ProcessorSpec
1113
from dlclivegui.services.dlc_processor import (
1214
DLCLiveProcessor,
1315
ProcessorStats,
@@ -55,6 +57,104 @@ def test_worker_initializes_on_first_frame(qtbot, monkeypatch_dlclive, settings_
5557
proc.reset() # Ensure thread cleanup
5658

5759

60+
@pytest.mark.unit
61+
def test_processor_spec_builds_in_worker_and_is_cleaned(
62+
qtbot,
63+
monkeypatch,
64+
settings_model,
65+
):
66+
"""Build a ProcessorSpec in DLCLiveWorker and clean it on reset."""
67+
from dlclivegui.services import dlc_processor as dlc_processor_module
68+
69+
built_processors = []
70+
dlclive_instances = []
71+
72+
class WorkerBuiltProcessor:
73+
PROCESSOR_NAME = "Worker-built test processor"
74+
75+
def __init__(self):
76+
self.build_thread_name = threading.current_thread().name
77+
self.stop_calls = 0
78+
built_processors.append(self)
79+
80+
def process(self, pose, **kwargs):
81+
return pose
82+
83+
def stop(self):
84+
self.stop_calls += 1
85+
86+
class FakeRunner:
87+
def get_pose(self, _processed_frame):
88+
return np.array(
89+
[[1.0, 2.0, 0.9]],
90+
dtype=np.float32,
91+
)
92+
93+
class FakeDLCLive:
94+
def __init__(self, **options):
95+
self.processor = options["processor"]
96+
self.runner = FakeRunner()
97+
self.pose = None
98+
self.cfg = {}
99+
self.init_called = False
100+
dlclive_instances.append(self)
101+
102+
def init_inference(self, _frame):
103+
self.init_called = True
104+
105+
def process_frame(self, frame):
106+
return frame
107+
108+
monkeypatch.setattr(
109+
dlc_processor_module,
110+
"DLCLive",
111+
FakeDLCLive,
112+
)
113+
114+
proc = DLCLiveProcessor()
115+
proc.configure(
116+
settings_model,
117+
processor_spec=ProcessorSpec(
118+
cls=WorkerBuiltProcessor,
119+
),
120+
)
121+
122+
frame = np.zeros(
123+
(32, 32, 3),
124+
dtype=np.uint8,
125+
)
126+
127+
try:
128+
with qtbot.waitSignal(
129+
proc.initialized,
130+
timeout=1500,
131+
) as blocker:
132+
proc.enqueue_frame(frame, timestamp=1.0)
133+
134+
assert blocker.args == [True]
135+
assert len(built_processors) == 1
136+
assert len(dlclive_instances) == 1
137+
138+
built_processor = built_processors[0]
139+
dlclive_instance = dlclive_instances[0]
140+
141+
assert built_processor.build_thread_name == "DLCLiveWorker"
142+
assert proc._processor is built_processor
143+
assert proc._processor_built_from_spec is True
144+
assert dlclive_instance.processor is built_processor
145+
assert dlclive_instance.init_called is True
146+
147+
proc.reset(reset_processor_plugin=True)
148+
149+
assert built_processor.stop_calls == 1
150+
assert proc._processor is None
151+
assert proc._processor_built_from_spec is False
152+
assert proc._state == WorkerState.STOPPED
153+
154+
finally:
155+
proc.shutdown()
156+
157+
58158
@pytest.mark.unit
59159
def test_worker_processes_frames(qtbot, monkeypatch_dlclive, settings_model):
60160
proc = DLCLiveProcessor()

0 commit comments

Comments
 (0)