diff --git a/selfdrive/ui/layouts/settings/starpilot/panel.py b/selfdrive/ui/layouts/settings/starpilot/panel.py index 4804b4b6e..ecfbdf970 100644 --- a/selfdrive/ui/layouts/settings/starpilot/panel.py +++ b/selfdrive/ui/layouts/settings/starpilot/panel.py @@ -17,9 +17,14 @@ import time class SettingsParamsWrapper: + """ + Proxy for ui_state.params. Relies on CachedParams for global TTL caching. + Intercepts UI writes (put/remove) to trigger system migrations automatically. + """ def __init__(self): self._params = ui_state.params + # --- Read Operations (Forwarded directly to global TTL cache) --- def get(self, key, **kwargs): return self._params.get(key, **kwargs) @@ -33,8 +38,10 @@ class SettingsParamsWrapper: return self._params.get_float(key, **kwargs) def _notify_changed(self): + # Triggers backend state sync when UI settings are modified update_starpilot_toggles() + # --- Write Operations (Triggers side-effects) --- def put(self, key, val, **kwargs): self._params.put(key, val, **kwargs) self._notify_changed() @@ -55,6 +62,7 @@ class SettingsParamsWrapper: self._params.remove(key) self._notify_changed() + # Safety net for any newly added parameter methods def __getattr__(self, name): return getattr(self._params, name) diff --git a/selfdrive/ui/ui_state.py b/selfdrive/ui/ui_state.py index e7098c67c..08d45b9c9 100644 --- a/selfdrive/ui/ui_state.py +++ b/selfdrive/ui/ui_state.py @@ -17,6 +17,10 @@ from openpilot.system.hardware import HARDWARE, PC BACKLIGHT_OFFROAD = 65 if HARDWARE.get_device_type() == "mici" else 50 USBGPU_POLL_INTERVAL = 1.0 class CachedParams: + """ + Global TTL-based cache for Params() to prevent excessive disk/IPC reads. + Dynamically wraps read methods (get*) to cache values and write methods (put*) to invalidate stale cache. + """ def __init__(self, ttl: float = 1.0): self._params = Params() self._cache = {} @@ -24,6 +28,7 @@ class CachedParams: self._ttl = ttl def _invalidate(self, key=None): + # Clears specific key or entire cache to guarantee fresh reads after writes if key is None: self._cache.clear() else: @@ -39,6 +44,7 @@ class CachedParams: return attr if name.startswith("get"): + # Intercept reads to serve from RAM if TTL is valid def get_wrapper(key, *args, **kwargs): now = time.monotonic() k_str = key.decode("utf-8") if isinstance(key, bytes) else str(key) @@ -53,6 +59,7 @@ class CachedParams: return get_wrapper if name.startswith("put") or name.startswith("remove") or name.startswith("clear"): + # Intercept writes to immediately invalidate stale data def put_wrapper(key=None, *args, **kwargs): res = attr(key, *args, **kwargs) if key is not None else attr(*args, **kwargs) self._invalidate(key)