diff --git a/moonwalk.py b/moonwalk.py index e9c9366..2866a07 100644 --- a/moonwalk.py +++ b/moonwalk.py @@ -35,6 +35,38 @@ class Params: object_velocity: float = 40 # pixels/second velocity_decay: float = 1 # make system a bit springy + def add_listener(self, attr: str, callback: callable): + """ + Add a listener for a change, callback gets + called with (attribute_name, old_value, new_value) + """ + if not attr in self.get_listeners(): + self._listeners[attr] = [] + self._listeners[attr].append(callback) + + def get_listeners(self) -> dict[str, callable]: + if not hasattr(self, "_listeners"): + self._listeners = {} + return self._listeners + + def __setattr__(self, attr, val): + if attr == '_listeners': + super().__setattr__(attr, val) + return + + if attr == 'tracker_fps' and val < .1: + # limit tracker fps + val = .1 + + if attr == 'emitter_speed' and val < .1: + # limit tracker fps + val = .1 + + old_val = getattr(self, attr) + super().__setattr__(attr, val) + if attr in self.get_listeners(): + for listener in self._listeners[attr]: + listener(attr, old_val, val) class DetectedObject: @@ -129,6 +161,7 @@ class Canvas: for i, field in enumerate(dataclasses.fields(self.params)): self.labels[field.name] = pyglet.text.Label(f"{field.name}: {field.default}", x=20, y=30 + 15*(i+1), color=(255,255,255,255), batch=self.batch_info) + # TODO: Add a number next to the box using pyglet.graphics.Group() self.track_shapes = defaultdict(lambda: pyglet.shapes.Box(0,0,0,0,color=(0,255,0),thickness=2, batch=self.batch_bounding_boxes)) self.tracker = Sort(max_age=5, min_hits=2, iou_threshold=0) #DeepSort(max_age=5) @@ -136,7 +169,15 @@ class Canvas: pyglet.clock.schedule_interval(self.on_track, 1/self.params.tracker_fps) self.interval_items: list[pyglet.clock._ScheduledIntervalItem] = [i for i in pyglet.clock._default._schedule_interval_items if i.func == self.on_track] + self.params.add_listener('tracker_fps', self.on_tracker_fps_change) + def on_tracker_fps_change(self, field, old_value, new_value): + """ + Param dataclass listener for changes to tracker_fps + """ + for ii in self.interval_items: + ii.interval = 1/new_value + logger.debug(f"Set tracker interval to {ii.interval}") def run(self): @@ -162,7 +203,7 @@ class Canvas: def on_key_press(self, symbol, modifiers): - if symbol == pyglet.window.key.Q: + if symbol == pyglet.window.key.Q or symbol == pyglet.window.key.ESCAPE: self.window.close() exit() @@ -185,7 +226,11 @@ class Canvas: x <= (self.labels[param_name].x + self.labels[param_name].content_width) and \ y >= self.labels[param_name].y and \ y <= (self.labels[param_name].y + self.labels[param_name].content_height): - setattr(self.params, param_name, param_value+scroll_y) + if scroll_y < 0: + param_value /= (-scroll_y * 1.25) + else: + param_value *= (scroll_y * 1.25) + setattr(self.params, param_name, param_value) def on_track(self, dt):