Zeichnungsmanager Master-Controls + Scheren + Startup-Perf + Oeffnung-Preview
UI: - GeschossManager: Master-Eye + Master-Lock im Header (analog EbenenManager). Scheren-Button pro Geschoss togglet hasClipping. Auge ganz links wie bei Ebenen. Eye-Logik klar 4-Wege: aktive Z immer hell+on, in 'active'/'all_force' fuer non-active gedimmt, sonst spiegelt Flag direkt. Schrift wird NIE gegrayt. Neuer Mode 'all_force' = "Alle anzeigen" (ignoriert Eye), 'all' jetzt mit Label "Ausgewaehlte" (respektiert Eye). Klick aufs Auge in 'active'/'all_force' wechselt automatisch in "Ausgewaehlte" damit Aktion sofort wirkt. - layer_builder.apply_visibility: neuer z_mode 'all_force' vor visible-Check — zeigt jede Z auch wenn Eye=false war. - elemente._cmd_create_oeffnung: gruene Live-Preview (vertikales Oeffnungs- Rechteck + Breiten-Marker + Diagonale) waehrend Fenster/Tuer-Platzierung entlang der Wand-Achse. Brueest-Offset aus Geschoss-UK korrekt im Z. Performance Cold-Start: - panel_base: Inlined-HTML als Modul-Cache (1x build, n-mal mount). Pro Panel-Mount nur noch str.replace + LoadHtml. Spart bei 10 Panels 9x ~395 KB Disk-Read + Regex-Pass. Cache-Key = mtime von dist/index.html. - Timing-Instrumentierung: _t_mark + print_startup_summary. Hook in startup.py feuert 3s nach Plugin-Load + listet Wall-time, Top-10, Aggregat pro Phase. - OberleisteBridge: Command-Enumeration (~1000 Commands) jetzt lazy via Rhino.RhinoApp.Idle statt synchron im __init__. Cold-Start nicht blockiert, Autocomplete kommt ~1 Frame spaeter. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+38
-9
@@ -772,12 +772,36 @@ class OberleisteBridge(panel_base.BaseBridge):
|
||||
self._last_state_sig = None # Fingerprint des letzten Push — dedupe
|
||||
self._cached_overrides = None # (enabled, count) — invalidiert bei Toggle/Update
|
||||
self._cached_combinations = None # (names, active) — invalidiert bei jeder Comb-Aenderung
|
||||
# Command-Liste einmalig laden (kann teuer sein -> cachen)
|
||||
try:
|
||||
self._all_commands = _list_all_command_names()
|
||||
# Command-Liste LAZY laden — die Enumeration durchlaeuft alle Plugins
|
||||
# und ist teuer (~hundert ms). Wird erst beim ersten _send_state, oder
|
||||
# explizit bei Command-Input-Fokus, gebaut.
|
||||
self._all_commands = None
|
||||
|
||||
def _ensure_commands_loaded_async(self):
|
||||
"""Schedult die teure Command-Enum auf den naechsten Idle-Tick statt
|
||||
sie synchron beim ersten _send_state zu laden. Cold-Start-Pfad wird
|
||||
nicht geblockt; Autocomplete-Liste ist ~1 Frame spaeter da."""
|
||||
if self._all_commands is not None: return
|
||||
if getattr(self, "_commands_loading", False): return
|
||||
self._commands_loading = True
|
||||
def _load_once(s, e):
|
||||
try: Rhino.RhinoApp.Idle -= _load_once
|
||||
except Exception: pass
|
||||
try:
|
||||
self._all_commands = _list_all_command_names()
|
||||
except Exception as ex:
|
||||
print("[OBERLEISTE] command-enum:", ex)
|
||||
self._all_commands = []
|
||||
# Sofort an UI pushen (Autocomplete wird live)
|
||||
try:
|
||||
if not getattr(self, "_commands_sent", False):
|
||||
self.send("STATE", {"allCommands": self._all_commands})
|
||||
self._commands_sent = True
|
||||
except Exception: pass
|
||||
try: Rhino.RhinoApp.Idle += _load_once
|
||||
except Exception as ex:
|
||||
print("[OBERLEISTE] command-enum:", ex)
|
||||
self._all_commands = []
|
||||
print("[OBERLEISTE] schedule command-load:", ex)
|
||||
self._commands_loading = False
|
||||
|
||||
def _on_ready(self):
|
||||
# Bootstrap DPI (gemeinsam mit massstab.py)
|
||||
@@ -1081,11 +1105,16 @@ class OberleisteBridge(panel_base.BaseBridge):
|
||||
prompt = _get_command_prompt()
|
||||
info["cmdPrompt"] = prompt
|
||||
info["cmdOptions"] = _parse_command_options(prompt)
|
||||
# Command-Autocomplete-Liste — nur einmal initial schicken (gross)
|
||||
# Command-Autocomplete-Liste — Lazy via Idle-Tick (statt im Bridge-
|
||||
# Init blockierend). Wenn sie noch nicht da ist: einplanen. Wenn da:
|
||||
# einmalig mitsenden.
|
||||
if not getattr(self, "_commands_sent", False):
|
||||
info["allCommands"] = self._all_commands
|
||||
self._commands_sent = True
|
||||
force = True # Erste Push immer feuern
|
||||
if self._all_commands is None:
|
||||
self._ensure_commands_loaded_async()
|
||||
else:
|
||||
info["allCommands"] = self._all_commands
|
||||
self._commands_sent = True
|
||||
force = True
|
||||
# Diff-Check: wenn weder Daten noch force, gar nichts schicken
|
||||
# (dedupe Idle-Ticks ohne Aenderung — spart WebView-ExecuteScript Roundtrip)
|
||||
sig = (
|
||||
|
||||
Reference in New Issue
Block a user