mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-31 14:12:06 +08:00
Big UI: More optimization
This commit is contained in:
@@ -381,14 +381,30 @@ def point_hits(mouse_pos: MousePos, rect: rl.Rectangle, parent_rect: rl.Rectangl
|
||||
return hit.width > 0 and hit.height > 0 and rl.check_collision_point_rec(mouse_pos, hit)
|
||||
|
||||
|
||||
_WRAP_TEXT_CACHE: dict[tuple[int, str, int, int, int], tuple[str, ...]] = {}
|
||||
_MAX_WRAP_CACHE_SIZE = 512
|
||||
|
||||
|
||||
def wrap_text(font: rl.Font, text: str, max_width: float, font_size: float, max_lines: int = 2) -> list[str]:
|
||||
if not text or max_width <= 0:
|
||||
return []
|
||||
|
||||
font_id = getattr(getattr(font, "texture", None), "id", id(font))
|
||||
w_key = int(round(max_width))
|
||||
s_key = int(round(font_size))
|
||||
key = (font_id, text, w_key, s_key, max_lines)
|
||||
|
||||
cached = _WRAP_TEXT_CACHE.get(key)
|
||||
if cached is not None:
|
||||
return list(cached)
|
||||
|
||||
spacing = font_size * 0.15
|
||||
words = text.split()
|
||||
lines: list[str] = []
|
||||
current = ""
|
||||
for word in words:
|
||||
candidate = f"{current} {word}".strip() if current else word
|
||||
if measure_text_cached(font, candidate, int(font_size), spacing=spacing).x <= max_width:
|
||||
if measure_text_cached(font, candidate, s_key, spacing=spacing).x <= max_width:
|
||||
current = candidate
|
||||
else:
|
||||
if current:
|
||||
@@ -398,7 +414,12 @@ def wrap_text(font: rl.Font, text: str, max_width: float, font_size: float, max_
|
||||
break
|
||||
if current and len(lines) < max_lines:
|
||||
lines.append(current)
|
||||
return lines if lines else [text]
|
||||
|
||||
result = tuple(lines if lines else [text])
|
||||
if len(_WRAP_TEXT_CACHE) >= _MAX_WRAP_CACHE_SIZE:
|
||||
_WRAP_TEXT_CACHE.clear()
|
||||
_WRAP_TEXT_CACHE[key] = result
|
||||
return list(result)
|
||||
|
||||
|
||||
def build_list_panel_frame(rect: rl.Rectangle, metrics: AetherListMetrics = AETHER_LIST_METRICS) -> AetherListFrame:
|
||||
|
||||
@@ -107,7 +107,7 @@ class StarPilotPanelInfo:
|
||||
class StarPilotPanel(Widget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._params_memory = Params(memory=True)
|
||||
self._params_memory = ui_state.params_memory
|
||||
self._params = FrameCachedParams()
|
||||
self._navigate_callback: Callable | None = None
|
||||
self._back_callback: Callable | None = None
|
||||
|
||||
@@ -111,13 +111,24 @@ def _speed_limit_pulse_color(base: rl.Color, alpha: int) -> rl.Color:
|
||||
)
|
||||
|
||||
|
||||
# ── State ─────────────────────────────────────────────────────────────
|
||||
# ── State Cache ──────────────────────────────────────────────────────
|
||||
_cached_key = None
|
||||
_cached_slc_state = None
|
||||
|
||||
|
||||
def _get_slc_state():
|
||||
"""Extract SLC state from SubMaster. Returns dict or None if stale/hidden."""
|
||||
global _cached_key, _cached_slc_state
|
||||
sm = ui_state.sm
|
||||
key = (sm.frame, sm.recv_frame.get("starpilotPlan", 0), ui_state.started_frame)
|
||||
if key == _cached_key:
|
||||
return _cached_slc_state
|
||||
|
||||
_cached_key = key
|
||||
|
||||
if sm.recv_frame["starpilotPlan"] < ui_state.started_frame:
|
||||
_reset_pulse()
|
||||
_cached_slc_state = None
|
||||
return None
|
||||
|
||||
plan = sm["starpilotPlan"]
|
||||
@@ -131,6 +142,7 @@ def _get_slc_state():
|
||||
|
||||
if not show_slc and not speed_limit_changed:
|
||||
_reset_pulse()
|
||||
_cached_slc_state = None
|
||||
return None
|
||||
|
||||
speed_conversion = CV.MS_TO_KPH if ui_state.is_metric else CV.MS_TO_MPH
|
||||
@@ -161,7 +173,7 @@ def _get_slc_state():
|
||||
# and before any sign colors are computed downstream.
|
||||
_tick_pulse(plan.slcSpeedLimitSource, resolved_ms)
|
||||
|
||||
return {
|
||||
_cached_slc_state = {
|
||||
'speed_limit': speed_limit,
|
||||
'speed_limit_str': "\u2013" if speed_limit <= 1 else str(int(round(speed_limit))),
|
||||
'slc_overridden_speed': slc_overridden_speed,
|
||||
@@ -182,6 +194,7 @@ def _get_slc_state():
|
||||
'mapbox_sl': max(0.0, plan.slcMapboxSpeedLimit * speed_conversion),
|
||||
'next_sl': max(0.0, plan.slcNextSpeedLimit * speed_conversion),
|
||||
}
|
||||
return _cached_slc_state
|
||||
|
||||
|
||||
# ── Fonts ─────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -10,14 +10,28 @@ class WidgetLayoutManager:
|
||||
"right": []
|
||||
}
|
||||
self.spacing = 15 # Spacing between widgets
|
||||
self._prev_key = None
|
||||
|
||||
def register_widget(self, zone: str, widget: LayoutWidget):
|
||||
"""Register a widget in a specific zone."""
|
||||
self.zones[zone].append(widget)
|
||||
self.zones[zone].sort(key=lambda w: w.priority)
|
||||
self._prev_key = None
|
||||
|
||||
def update_layout(self, content_rect: rl.Rectangle, is_rhd: bool = False):
|
||||
"""Calculate and apply positions of all active widgets in all zones."""
|
||||
key = (
|
||||
content_rect.x, content_rect.y, content_rect.width, content_rect.height,
|
||||
is_rhd,
|
||||
tuple(
|
||||
(zone, tuple((w, w.is_visible, w.get_size() if w.is_visible else None) for w in widgets))
|
||||
for zone, widgets in self.zones.items()
|
||||
)
|
||||
)
|
||||
if key == self._prev_key:
|
||||
return
|
||||
self._prev_key = key
|
||||
|
||||
self.content_rect = content_rect
|
||||
self._layout_left()
|
||||
self._layout_bottom(is_rhd)
|
||||
|
||||
@@ -16,8 +16,6 @@ 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:
|
||||
def __init__(self, ttl: float = 1.0):
|
||||
self._params = Params()
|
||||
@@ -64,7 +62,6 @@ class CachedParams:
|
||||
|
||||
return attr
|
||||
|
||||
|
||||
class UIStatus(Enum):
|
||||
DISENGAGED = "disengaged"
|
||||
ENGAGED = "engaged"
|
||||
|
||||
Reference in New Issue
Block a user