From 8884cd42ae6e02be88f1732ac3ceb5a340a7a084 Mon Sep 17 00:00:00 2001 From: MoonJam Date: Sun, 13 Oct 2024 14:58:23 +0800 Subject: [PATCH] python: Fix threading in GUI Stopping and starting threads didn't really work before. --- python/inputmodule/gui/gui_threading.py | 22 +++++++++++------ python/inputmodule/gui/ledmatrix.py | 26 ++++++++++++++------- python/inputmodule/inputmodule/ledmatrix.py | 12 +++++++--- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/python/inputmodule/gui/gui_threading.py b/python/inputmodule/gui/gui_threading.py index daff889..0f7fec2 100644 --- a/python/inputmodule/gui/gui_threading.py +++ b/python/inputmodule/gui/gui_threading.py @@ -1,21 +1,29 @@ # Global GUI variables -STOP_THREAD = False DISCONNECTED_DEVS = [] +STATUS = '' +def set_status(status): + global STATUS + STATUS = status + +def get_status(): + global STATUS + return STATUS def stop_thread(): - global STOP_THREAD - STOP_THREAD = True + global STATUS + STATUS = 'STOP_THREAD' def reset_thread(): - global STOP_THREAD - STOP_THREAD = False + global STATUS + if STATUS == 'STOP_THREAD': + STATUS = '' def is_thread_stopped(): - global STOP_THREAD - return STOP_THREAD + global STATUS + return STATUS == 'STOP_THREAD' def is_dev_disconnected(dev): diff --git a/python/inputmodule/gui/ledmatrix.py b/python/inputmodule/gui/ledmatrix.py index 9a369e7..dddd165 100644 --- a/python/inputmodule/gui/ledmatrix.py +++ b/python/inputmodule/gui/ledmatrix.py @@ -6,22 +6,26 @@ reset_thread, is_thread_stopped, is_dev_disconnected, + set_status, + get_status, ) from inputmodule.inputmodule.ledmatrix import ( light_leds, show_string, eq, breathing, + animate, ) from inputmodule.inputmodule import brightness - def countdown(dev, seconds): """Run a countdown timer. Lighting more LEDs every 100th of a seconds. Until the timer runs out and every LED is lit""" + animate(dev, False) + set_status('countdown') start = datetime.now() target = seconds * 1_000_000 - while True: + while get_status() == 'countdown': if is_thread_stopped() or is_dev_disconnected(dev.device): reset_thread() return @@ -37,15 +41,17 @@ def countdown(dev, seconds): time.sleep(0.01) - light_leds(dev, 306) - breathing(dev) - # blinking(dev) + if get_status() == 'countdown': + light_leds(dev, 306) + breathing(dev) + # blinking(dev) def blinking(dev): """Blink brightness high/off every second. Keeps currently displayed grid""" - while True: + set_status('blinking') + while get_status() == 'blinking': if is_thread_stopped() or is_dev_disconnected(dev.device): reset_thread() return @@ -57,7 +63,9 @@ def blinking(dev): def random_eq(dev): """Display an equlizer looking animation with random values.""" - while True: + animate(dev, False) + set_status('random_eq') + while get_status() == 'random_eq': if is_thread_stopped() or is_dev_disconnected(dev.device): reset_thread() return @@ -72,7 +80,9 @@ def random_eq(dev): def clock(dev): """Render the current time and display. Loops forever, updating every second""" - while True: + animate(dev, False) + set_status('clock') + while get_status() == 'clock': if is_thread_stopped() or is_dev_disconnected(dev.device): reset_thread() return diff --git a/python/inputmodule/inputmodule/ledmatrix.py b/python/inputmodule/inputmodule/ledmatrix.py index f1ead13..7b351bd 100644 --- a/python/inputmodule/inputmodule/ledmatrix.py +++ b/python/inputmodule/inputmodule/ledmatrix.py @@ -11,6 +11,7 @@ send_serial, brightness, ) +from inputmodule.gui.gui_threading import get_status, set_status WIDTH = 9 HEIGHT = 34 @@ -69,6 +70,8 @@ def percentage(dev, p): def animate(dev, b: bool): """Tell the firmware to start/stop animation. Scrolls the currently saved grid vertically down.""" + if b: + set_status('animate') send_command(dev, CommandVals.Animate, [b]) @@ -104,6 +107,7 @@ def image_bl(dev, image_file): def camera(dev): """Play a live view from the webcam, for fun""" + set_status('camera') with serial.Serial(dev.device, 115200) as s: import cv2 @@ -120,7 +124,7 @@ def camera(dev): end_x = min(dim[1], start_x + WIDTH) # Pre-process the video into resized, cropped, grayscale frames - while True: + while get_status() == 'camera': ret, frame = capture.read() if not ret: print("Failed to capture video frames") @@ -142,6 +146,7 @@ def camera(dev): def video(dev, video_file): + set_status('video') """Resize and play back a video""" with serial.Serial(dev.device, 115200) as s: import cv2 @@ -161,7 +166,7 @@ def video(dev, video_file): processed = [] # Pre-process the video into resized, cropped, grayscale frames - while True: + while get_status() == 'video': ret, frame = capture.read() if not ret: print("Failed to read video frames") @@ -294,8 +299,9 @@ def all_brightnesses(dev): def breathing(dev): """Animate breathing brightness. Keeps currently displayed grid""" + set_status('breathing') # Bright ranges appear similar, so we have to go through those faster - while True: + while get_status() == 'breathing': # Go quickly from 250 to 50 for i in range(10): time.sleep(0.03)