start/live.py

91 lines
2.8 KiB
Python

import sys
import time
import importlib
import os
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from threading import Timer
# --- KONFIGURACJA ---
VIEWER_PORT = 3939
DELAY_SECONDS = 0.1 # Czeka na ciszę przez 0.5s zanim przeładuje
# --------------------
if len(sys.argv) < 2:
print("❌ Błąd: Nie podałeś nazwy pliku!")
sys.exit(1)
RAW_PATH = sys.argv[1]
ABS_PATH = os.path.abspath(RAW_PATH)
DIR_NAME = os.path.dirname(ABS_PATH)
FILE_NAME = os.path.basename(ABS_PATH)
MODULE_NAME = os.path.splitext(FILE_NAME)[0]
print(f"📂 Katalog roboczy: {DIR_NAME}")
os.chdir(DIR_NAME)
if "." not in sys.path:
sys.path.insert(0, ".")
# --- IMPORTY CAD ---
print(f"🔥 Ładuję biblioteki CAD...")
import build123d
from ocp_vscode import show, set_port
# Konfigurujemy klienta, żeby gadał z portem 3939
set_port(VIEWER_PORT)
print(f"🚀 GOTOWE! Nasłuchuję zmian w: {FILE_NAME}")
# --- OBSŁUGA ZMIAN PLIKU ---
class RebuildHandler(FileSystemEventHandler):
def __init__(self):
self.timer = None
def on_modified(self, event):
# Reagujemy tylko na zmianę TEGO konkretnego pliku
if os.path.abspath(event.src_path) == ABS_PATH:
# Jeśli zegar już tyka, anulujemy go (bo przyszło nowe zdarzenie = Vim jeszcze pisze)
if self.timer:
self.timer.cancel()
# Ustawiamy nowy timer. Odpali się tylko jeśli przez 0.5s nic nowego nie przyjdzie.
self.timer = Timer(DELAY_SECONDS, self.process_reload)
self.timer.start()
def process_reload(self):
print(f"♻️ Przeliczam {MODULE_NAME}... ", end="", flush=True)
start_time = time.time()
try:
# Magia przeładowania modułu bez restartu procesu
if MODULE_NAME in sys.modules:
importlib.reload(sys.modules[MODULE_NAME])
else:
importlib.import_module(MODULE_NAME)
print(f"Gotowe ({time.time() - start_time:.2f}s)")
except Exception as e:
# Łapiemy błędy składni/CAD, żeby runner się nie wywalił
print(f"\n❌ BŁĄD KODU:\n{e}")
if __name__ == "__main__":
# 1. Pierwsze uruchomienie przy starcie
try:
importlib.import_module(MODULE_NAME)
except Exception as e:
print(f"⚠️ Startowy błąd w kodzie: {e}")
# 2. Uruchomienie obserwatora (Watchdog)
event_handler = RebuildHandler()
observer = Observer()
# Obserwujemy katalog, ale w handlerze filtrujemy tylko nasz plik
observer.schedule(event_handler, path='.', recursive=False)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
print("\n🛑 Koniec pracy.")
observer.join()