fix(presets): phase-lock blink and one tick on re-select

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-25 21:55:46 +12:00
parent 39a84696c3
commit c9895df512

View File

@@ -201,16 +201,13 @@ class Presets:
self.fill((0, 0, 0)) self.fill((0, 0, 0))
self.selected = preset_name self.selected = preset_name
return True return True
# Manual single-shot patterns: if this select arrives before the main loop has # If re-selecting the same preset before the main loop has tick()'d the
# tick()'d the previous frame, completing it first keeps step in sync with beats. # previous frame, run one pending tick so step stays in sync.
if ( if (
preset_name == self.selected preset_name == self.selected
and not preset.a
and preset.p in ("chase", "pulse")
and self.generator is not None and self.generator is not None
): ):
while self.generator is not None: self.tick()
self.tick()
# Set step value if explicitly provided # Set step value if explicitly provided
if step is not None: if step is not None:
self.step = step self.step = step
@@ -274,11 +271,22 @@ class Presets:
colors = preset.c if preset.c else [(255, 255, 255)] colors = preset.c if preset.c else [(255, 255, 255)]
bg_color = self.apply_brightness(preset.background_or(colors), preset.b) bg_color = self.apply_brightness(preset.background_or(colors), preset.b)
color_index = 0 color_index = 0
state = True delay_ms = max(1, int(preset.d))
last_update = utime.ticks_ms() period = delay_ms * 2
now = utime.ticks_ms()
# Phase-lock to wall time so group identify (broadcast select) stays in sync even
# when devices process the packet on different main-loop iterations.
phase = now % period if period else 0
state = phase < delay_ms
last_update = utime.ticks_add(now, -phase)
if state:
base = colors[color_index % len(colors)]
self.fill(self.apply_brightness(base, preset.b))
color_index += 1
else:
self.fill(bg_color)
while True: while True:
now = utime.ticks_ms() now = utime.ticks_ms()
delay_ms = max(1, int(preset.d))
if utime.ticks_diff(now, last_update) >= delay_ms: if utime.ticks_diff(now, last_update) >= delay_ms:
if state: if state:
base = colors[color_index % len(colors)] base = colors[color_index % len(colors)]