Files

72 lines
3.2 KiB
Plaintext

115| bool stop = false;
116| };
117|
118| int main(int argc, char* argv[]) {
119| if (argc < 2) {
120| printf("usage: gui_probe <plugin.vst3> [variant] [secs] [hwnd]\n"
121| "variants: main_own | worker_own_nopump | worker_own_pump | worker_foreign_nopump | worker_foreign_pump | bridge_like | same_thread | two_instances | two_instances_close | close_reopen | bridge_two | shared_worker | ui_thread | two_workers_close\n");
122| return 2;
123| }
124| std::string path = argv[1];
125| std::string variant = argc > 2 ? argv[2] : "main_own";
126| int secs = argc > 3 ? atoi(argv[3]) : 20;
127|
128| CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
129|
130| // Watchdog: never let a stuck plugin hang this probe forever.
131| std::thread([secs]() {
132| Sleep((DWORD)(secs + 10) * 1000);
133| printf("WATCHDOG-KILL\n");
134| fflush(stdout);
135| TerminateProcess(GetCurrentProcess(), 0);
136| }).detach();
137|
138| HWND ownHwnd = 0;
139| {
140| WNDCLASSEX wc = {};
141| wc.cbSize = sizeof(wc);
142| wc.lpfnWndProc = DefWindowProc;
143| wc.hInstance = GetModuleHandle(nullptr);
144| wc.lpszClassName = "GuiProbeClass";
145| RegisterClassEx(&wc);
146| ownHwnd = CreateWindowEx(0, "GuiProbeClass", "GuiProbe", WS_OVERLAPPEDWINDOW,
147| 0, 0, 800, 600, nullptr, nullptr, wc.hInstance, nullptr);
148| printf("ownHwnd=%p\n", (void*)ownHwnd);
149| }
150|
151| void* targetHwnd = (void*)ownHwnd;
152| if (argc > 4) targetHwnd = (void*)(uintptr_t)strtoull(argv[4], nullptr, 0);
153|
154| printf("loading %s\n", path.c_str());
155| fflush(stdout);
156| Vst3Instrument inst;
157| Vst3Instrument inst2;
158| bool isDeferred = (variant == "bridge_like" || variant == "same_thread" ||
159| variant == "two_instances" || variant == "two_instances_close" ||
160| variant == "close_reopen" || variant == "bridge_two" ||
161| variant == "shared_worker" || variant == "ui_thread");
162| bool ok = true;
163| if (!isDeferred) {
164| ok = inst.loadPlugin(path, 44100.0);
165| printf("load=%d\n", ok ? 1 : 0);
166| fflush(stdout);
167| if (!ok) return 1;
168| }
169|
170| std::atomic<bool> done{false};
171| std::atomic<bool> result{false};
172|
173| auto attach_job = [&]() {
174| CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
175| printf("[%s] openGUI start hwnd=%p\n", variant.c_str(), targetHwnd);
176| fflush(stdout);
177| bool r = inst.openGUI(targetHwnd);
178| printf("[%s] openGUI returned=%d\n", variant.c_str(), r ? 1 : 0);
179| fflush(stdout);
180| result = r;
181| done = true;
182| };
183|
184| if (variant == "main_own") {
185| attach_job(); // editorhost pattern: attached on main thread, pump after
186| pump_for(secs);