Hot-Reloading
This is not an actual "issue", but an alternative idea about hot-reloading. I do it this way, so I thought I'd share it 🙂
Unlike CPLUG, I don't have any hot-reloading logic or code in my plugin. My plugin doesn't build an extra DLL that I then hot-reload.
Instead, I have a simple extra app/plugin called "LiveReload". It's a simple plugin host. It hosts my VST3 plugin, and monitors my plugin's .vst3 DLL/bundle for changes. So while LiveReload is running, whenever I rebuild my plugin, LiveReload notices the change, saves my plugin's state, reloads my plugin DLL, and restores its state. A plugin is already a DLL, so we don't need "another layer of DLL" to do hot-reloading.
LiveReload can itself run as a plugin in a DAW. It's just a wrapper. So you can hot-reload while running a DAW with debugger attached.
This way, you don't need the live-reloading code and build steps in each individual plugin. Or worry about disabling it in release builds, etc. You just put it into one generic LiveReload app, done.
Right now, I made my LiveReload app/plugin using JUCE, because I didn't want to write a VST3 host from scratch. But if we only want it to host CPLUG plugins (not any VST3), then it could use the more simple CPLUG API (not VST3), and LiveReload itself could be made with CPLUG, not JUCE. Anyway, LiveReload can be under GPL (if needed by JUCE) because your actual plugin doesn't use its code, and you never ship LiveReload to users. It's just a development tool.
I can share my LiveReload code/project if you're interested. I just don't quite have it in a form to make a public Github repo yet.
Thanks for offering to share. What's the advantage of your live reloading over something like cr?
https://github.com/fungos/cr
Sorry I had been drinking when I previously responded lmao. Upon reading your post a few more times I think I understand your concern a little better.
The concern is:
- You would like to do hotreloading or live reloading (is there a difference?) inside a DAW, and cplug only has options for that in standalone mode
- You would like to avoid the mess on unnecessary DLLs
I'm open to adding hot reloading to the other plugin formats. It seems like the easiest thing to do though would be to integrate a readymade solution like cr. Unfortunately I only found out about it a year or so after cplug was written, otherwise I may not have bothered writing my own code.
Currently I believe the multiple DLL mess is essential to fix some edge cases that I personally deal with.
There are a few notes left in comments the api_redesign branch around the parts where I do DLL loading. Basically when you run a program that loads a DLL, and the DLL depends on particular system libraries (Metal on macOS and D3D11 in my case) the operating system is suspect of performing hidden optimisations behind your back and will not unload your library even when call dlclose one million times in a loop. The Windows and iPhone docs both mention this (I'm assuming macOS shares iPhone behaviour here. Unfortunately Apple don't document macOS as well as iPhone). Some debuggers have a similar problem, they don't drop DLL and their symbols, so you need to create a mess where you load a new DLL with a new name the OS and debugger hasn't seen within the lifetime of your running app. If you don't the multiple DLL hack and you try to load an updated DLL, your running app may read functions from the wrong addresses, causing undefined behaviour and a very quick segfault.
The example cplug code doesn't seem to have this problem. It uses CPU rasterisation and requires a couple of OS api calls to copy over a bitmap. I've tested elsewhere adding Metal and DX11 to the example code and I quickly get crashes without the multiple DLL hack.
JUCE uses CPU rasterisation so maybe it doesn't have this problem. If they're lucky their new D2D renderer won't have this problem either.
Unfortunately DLL mess has to stay unless my assumptions above are wrong.
What are your thoughts?