M4: /fx-gui redirect vao session fxrt (native-window mode, embed_url=None) + watchdog auto-restart
This commit is contained in:
@@ -711,6 +711,24 @@ async def open_fx_gui(req: FxGuiRequest, current_user: dict = Depends(get_curren
|
||||
plugin_path = (req.path or "").strip()
|
||||
if not plugin_path:
|
||||
raise HTTPException(status_code=400, detail="Thiếu đường dẫn VST plugin.")
|
||||
# ── Phase 2 (M4): plugin là slot của session FX realtime (mastering) → mở
|
||||
# editor của CHÍNH instance DSP ngay trong fxrt_bridge (juce_fx_bridge) qua
|
||||
# SHM ctrl ring ed.open — KHÔNG spawn fx_vst_bridge instance 2 + feeder
|
||||
# (nguồn CPU 100%). GUI = cửa sổ native "FX slot N" trên desktop (không
|
||||
# HTTP embed frame → embed_url=None, native=true — frontend M6 dùng mode
|
||||
# này). Vẫn spawn fx_vst_bridge khi: không shm / session không tồn tại /
|
||||
# plugin không phải slot chain (instrument, offline, fallback an toàn).
|
||||
_sess = fx_realtime.get_session((req.shm or "").strip()) if (req.shm or "").strip() else None
|
||||
if _sess is not None and _sess.alive():
|
||||
_slot = _sess.chain_slot_for_path(plugin_path)
|
||||
if _slot is not None:
|
||||
_already = fx_realtime.editor_find(plugin_path)
|
||||
_same = _already is not None and _already[0] == _sess.name
|
||||
_sess.send_editor_cmd("open", slot=_slot)
|
||||
fx_realtime.editor_register(plugin_path, _sess.name, _slot)
|
||||
return {"success": True, "started": not _same,
|
||||
"already_running": bool(_same), "native": True,
|
||||
"embed_url": None, "session_id": _sess.name, "slot": _slot}
|
||||
# Tránh mở 2 GUI cùng plugin: nếu tiến trình bridge fx-gui cho plugin này
|
||||
# đang chạy → trả started=False (frontend có thể focus window cũ).
|
||||
for proc in _FX_GUI_PROCESSES:
|
||||
@@ -808,6 +826,17 @@ async def close_fx_gui(req: FxGuiCloseRequest, current_user: dict = Depends(get_
|
||||
plugin_path = (req.path or "").strip()
|
||||
if not plugin_path:
|
||||
raise HTTPException(status_code=400, detail="Thiếu đường dẫn VST plugin.")
|
||||
# M4: plugin đang mở native (editor instance DSP trong session fxrt) →
|
||||
# gửi ed.close (đóng editor, GIỮ instance + state — mở lại nhanh).
|
||||
_entry = fx_realtime.editor_find(plugin_path)
|
||||
if _entry:
|
||||
_sid, _slot = _entry
|
||||
fx_realtime.editor_unregister(plugin_path)
|
||||
_sess = fx_realtime.get_session(_sid)
|
||||
if _sess is not None and _sess.alive():
|
||||
_sess.send_editor_cmd("close", slot=_slot)
|
||||
return {"success": True, "closed": True, "native": True}
|
||||
# session đã chết — rơi xuống spawn fallback (đóng bridge fx-gui cũ nếu có)
|
||||
for proc in _FX_GUI_PROCESSES:
|
||||
if proc is not None and proc.poll() is None and getattr(proc, "_sf_plugin_path", None) == plugin_path:
|
||||
proc.terminate()
|
||||
@@ -820,6 +849,49 @@ async def close_fx_gui(req: FxGuiCloseRequest, current_user: dict = Depends(get_
|
||||
return {"success": True, "closed": False}
|
||||
|
||||
|
||||
class FxGuiNativeRequest(BaseModel):
|
||||
"""Hide/Show GUI native (editor instance DSP trong session fxrt)."""
|
||||
path: str
|
||||
|
||||
|
||||
def _fxrt_native_editor(plugin_path):
|
||||
"""(session, slot) nếu plugin đang mở native trong session fxrt sống."""
|
||||
entry = fx_realtime.editor_find(plugin_path)
|
||||
if not entry:
|
||||
return None, None
|
||||
sess = fx_realtime.get_session(entry[0])
|
||||
if sess is None or not sess.alive():
|
||||
fx_realtime.editor_unregister(plugin_path)
|
||||
return None, None
|
||||
return sess, entry[1]
|
||||
|
||||
|
||||
@router.post("/fx-gui/hide")
|
||||
async def hide_fx_gui(req: FxGuiNativeRequest,
|
||||
current_user: dict = Depends(get_current_user)):
|
||||
"""Ẩn GUI native (ed.hide — giữ editor + instance, mở lại nhanh). Chỉ
|
||||
áp dụng editor in-process fxrt; GUI spawn mode (HTTP bridge) tự có /hide
|
||||
riêng — trả applied=False không lỗi."""
|
||||
enforce_password_changed(current_user)
|
||||
sess, slot = _fxrt_native_editor((req.path or "").strip())
|
||||
if sess is None:
|
||||
return {"success": True, "applied": False}
|
||||
sess.send_editor_cmd("hide", slot=slot)
|
||||
return {"success": True, "applied": True, "native": True}
|
||||
|
||||
|
||||
@router.post("/fx-gui/show")
|
||||
async def show_fx_gui(req: FxGuiNativeRequest,
|
||||
current_user: dict = Depends(get_current_user)):
|
||||
"""Hiện lại GUI native (ed.show)."""
|
||||
enforce_password_changed(current_user)
|
||||
sess, slot = _fxrt_native_editor((req.path or "").strip())
|
||||
if sess is None:
|
||||
return {"success": True, "applied": False}
|
||||
sess.send_editor_cmd("show", slot=slot)
|
||||
return {"success": True, "applied": True, "native": True}
|
||||
|
||||
|
||||
_FX_GUI_PROCESSES = [] # list[subprocess.Popen] — các bridge fx-gui do app spawn
|
||||
|
||||
def _register_fx_gui_process(proc):
|
||||
|
||||
Reference in New Issue
Block a user