M2: GUI thread + host window trong juce_fx_bridge (Reaper-style — editor cua CHINH instance DSP)

JuceFxGuiHost: GUI thread rieng chay juce MessageManager runDispatchLoopUntil(10) + tick
30ms inline cadence (JUCE Timer KHONG fire tren GUI thread rieng — da xac minh selftest),
PluginWindow (DocumentWindow native 'FX slot N') attach editor, reconcile dong editor+
window, teardown thu tu. runOnGui(): plugin instance phai tao tren GUI thread — JUCE plugin
gan MM vao thread tao instance, editor tao thread khac -> treo (M1 chi chay vi main thread
vua tao instance vua la message thread); prepare/shutdown bao qua runOnGui.
JuceFxLoop: guiHost.start() TRUOC engine.prepare; re-prepare sau waitEditorsClosed(1500);
teardown runOnGui(shutdown) truoc stop(). Idle ~0 CPU (khong feeder, khong instance 2).
juce_fx_gui_selftest (khong ship) PASS tren purecomp + fast-compressor: open/hide/show/
resize/close, teardown sach; window native chup duoc (PrintWindow). Regression M1 selftest OK.
This commit is contained in:
2026-09-04 10:40:46 +07:00
parent 0d22e8b4d3
commit df4a22b9b4
7 changed files with 553 additions and 18 deletions
+23 -2
View File
@@ -36,8 +36,8 @@ public:
enum class EditorAction {
Open, // tạo editor (createEditorIfNeeded) cho slot — giữ instance DSP
Close, // huỷ editor, GIỮ instance DSP + state (mở lại nhanh)
Show, // hiện editor (M2: host window) — chưa tác dụng khi chưa attach
Hide, // ẩn editor (M2: host window)
Show, // hiện editor + host window (M2)
Hide, // ẩn editor + host window, GIỮ editor+instance (mở lại nhanh)
Resize, // đổi kích thước editor (M2: host window)
Capture // đọc state processor (getStateInformation) -> captured[slot]
};
@@ -57,6 +57,27 @@ public:
// Raw bytes (chưa base64) — M3 encode khi đẩy về engine Python.
std::string takeCapturedState(uint32_t slot);
// ── GUI host support (M2): GuiHost chạy trên GUI thread dùng các API này
// để attach editor vào host window + teardown an toàn. Header giữ JUCE-free
// (editorHandle trả void* = juce::Component*).
// GUI thread: con trỏ editor Component của slot (null nếu chưa mở). Chỉ
// gọi trên message thread, cùng lúc pumpEditorQueue().
void* editorHandle(uint32_t slot);
// Thread-safe: số slot chain hiện tại (sau prepare; trước = 0).
uint32_t slotCount() const;
// Thread-safe: có editor nào đang mở không (teardown đồng bộ).
bool hasOpenEditor() const;
// Thread-safe: enqueue Close cho MỌI slot đang mở — main thread gọi trước
// engine.prepare()/shutdown() khi GUI thread đang chạy (editor là JUCE
// Component, phải đóng trên message thread; GuiHost chờ + pump).
void closeAllEditors();
// Thread-safe đọc: editor slot đang hiển thị (Show/Hide) không.
bool isEditorVisible(uint32_t slot) const;
void shutdown();
private: