diff --git a/main.py b/main.py index b654579180d932ea6dd8c221132b9c79d60895b2..b5919fd21c06c22eaed6817c59c21475fc82b02f 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,4 @@ +import hashlib import json import os import threading @@ -293,6 +294,8 @@ def wr_get_config(): # Loading functions # ##################### +widgetcache = {} + def load_widget(widget_name: str, config_override: dict=None): # Get the widget properties from the config file widget_props = module_config.get(widget_name, {}).copy() @@ -305,11 +308,24 @@ def load_widget(widget_name: str, config_override: dict=None): if (isinstance(v, int) or isinstance(v, float)) and k.startswith("scalable_"): widget_props[k.removeprefix("scalable_")] = v * PROP_WINDOW_SCALE + # Generate hash to store the widget in the cache + m = hashlib.md5() + m.update(widget_name.encode("utf8")) + m.update(encode_dict(widget_props).encode("utf8")) + widget_hash = m.hexdigest() + + if widget_hash in widgetcache: + # If the widget is already in the cache, return it + widget = widgetcache[widget_hash] + else: + # Load the widget + widget = getattr(screenwidgets, widget_name)(widget_props, pygame) + # Add to cache + widgetcache[widget_hash] = widget + # Add the pygame module to the widget properties widget_props["pygame"] = pygame - - # Load the widget - return getattr(screenwidgets, widget_name)(widget_props) + return widget def load_pattern(pattern_name: str, leds: ILedString, config_override: dict=None): pattern_props = module_config.get(pattern_name, {}).copy() diff --git a/module_defaults.json b/module_defaults.json index 1e2c43471de2611374e8f1ed14a93e78b7e0ce00..ce60520674ca4c1a92265312c32d3c982df87c88 100644 --- a/module_defaults.json +++ b/module_defaults.json @@ -385,7 +385,7 @@ "RainbowPattern": { "tick_rate": { "name": "Tick rate", - "description": "The delay between ticks (in ms). If negative, will only run once.", + "description": "The delay between ticks (in ms). Adjusting this will speed up or slow down the effect. If negative, will only run once.", "default": 10, "type": "integer" } diff --git a/screenwidgets.py b/screenwidgets.py index 284074faf591cda9f637ddbc0dc6267673cd7d5a..d586b0349d82d18f8b681d7f135c4d2a56d19875 100644 --- a/screenwidgets.py +++ b/screenwidgets.py @@ -23,7 +23,7 @@ class IWidget(metaclass=IWidgetMeta): """ Interface for a widget which can be drawn on the screen """ - def __init__(self, config: dict): + def __init__(self, config: dict, pygame): pass def draw(self, screen): pass @@ -32,12 +32,12 @@ class DigitalClockWidget(IWidget): """ A simple clock widget which displays the current time """ - def __init__(self, config: dict): + def __init__(self, config: dict, pygame): # Call the parent constructor - super().__init__(config) + super().__init__(config, pygame) # Get the pygame module from the config - self.pygame = config['pygame'] + self.pygame = pygame # Get the font path self.font_path = get_font_path_or_default(self.pygame, config.get("font_name", None), config.get("font_bold", False), config.get("font_italic", False)) @@ -83,9 +83,9 @@ class DigitalClockWidget(IWidget): screen.blit(text_surface, text_rect) class TestWidget(IWidget): - def __init__(self, config: dict): - super().__init__(config) - self.pygame = config['pygame'] + def __init__(self, config: dict, pygame): + super().__init__(config, pygame) + self.pygame = pygame self.color = config.get("color", "white") self.bg_color = config.get("background_color", "black") self.text = config.get("text", "Hello, world!") @@ -98,9 +98,9 @@ class TestWidget(IWidget): screen.blit(text_surface, text_rect) class AnalogClockWidget(IWidget): - def __init__(self, config: dict): - super().__init__(config) - self.pygame = config['pygame'] + def __init__(self, config: dict, pygame): + super().__init__(config, pygame) + self.pygame = pygame # Set the colours self.background_color = config.get("background_color", "black") @@ -200,9 +200,9 @@ class AnalogClockWidget(IWidget): self.clock_hand(screen, get_screen_centre(), self.hour_hand_length, hour * 30, self.hour_hand_thickness, self.hour_hand_color) class IPShowWidget(IWidget): - def __init__(self, config: dict): - super().__init__(config) - self.pygame = config['pygame'] + def __init__(self, config: dict, pygame): + super().__init__(config, pygame) + self.pygame = pygame # Backgrounds self.background_color = config.get("background_color", "black") @@ -244,9 +244,9 @@ class IPShowWidget(IWidget): screen.blit(text_surface_2, text_rect_2) class WeatherWidget(IWidget): - def __init__(self, config: dict): - super().__init__(config) - self.pygame = config['pygame'] + def __init__(self, config: dict, pygame): + super().__init__(config, pygame) + self.pygame = pygame # Get the font path self.title_font_path = get_font_path_or_default(self.pygame, config.get("title_font_name", None),