I’m experimenting with the Browser plugin system (I’d like to be able to do web apps in PILS using the Juce bindings). But I’m confused about the life cycle of a browser plugin instantiation, specifically how to deal with initialization, cleanup, threading etc.
The life cycle of my desktop app (which lives in a single exe file) is like this:
:arrow: 1 . The PILS interpreter kernel and the Juce bindings are initialized using static objects. The C++ runtime will initialize these objects before running main().
:arrow: 2. The details of initializing Juce is handled by START_JUCE_APPLICATION (JPilsApplication)
:arrow: 3. JPilsApplication::initialise() executes a PILS boot expression which returns a PILS function object called the command line handler. (This object actually contains the PILS programming system.)
:arrow: 4. The command line handler is applied to the command line, and to any subsequent command lines passed by anotherInstanceStarted(). (Often, the handler will open a document window, using a file name given in the command line.)
:arrow: 5. The PILS wrappers for Juce components keep a count of the desktop components. When this count reaches zero, quit() is called.
:arrow: 6. JPilsApplication::shutdown() releases the command line handler, and also some objects created by the constructors of the static objects in step 1.
The above is a simplified version that doesn’t discuss threads, allocators etc. etc.
Anyway, I’d like to keep as much as possible of this architecture in the plugin, so that I can create apps on the desktop and turn them into web apps later, without too many changes.
1 . The PILS interpreter kernel and the Juce can still be initialized using static objects. The C++ runtime will initialize them when the plugin is loaded.
:oops: 2. There is no JUCEApplication object, or is there? I first assumed the BrowserObject had this role but this object seems to be destroyed and recreated if you go to another URL and then back.
3. It seems I can use a classic singleton pattern for the PILS command line handler, storing a pointer in a static member, creating it (and booting PILS) at the first use.
:?: 5. The BrowserPluginComponent - or a component inside it - will play the role of the main window (I wonder if I can equip it with a Juce menu bar???) - but the deletion of this window doesn’t imply that the plug is unloaded.
:twisted: 6. I can release the command line handler and the objects created by the constructors of the static objects, in a destructor of a static object, which will get called when the plugin gets unloaded. But I’m not sure this is the right way to go. The command line handler might hold Juce objects that might not be working correctly because Juce might be nuked at this stage. Is there some clean way to be told that Juce is about to go under?
(I tried using the BrowserPlugin and BrowserObject destructors but it turns out these objects aren’t as long-lived as the plugin.)
Then, there is the issue of threading. What can be expected from browser plugins under various architectures? Is the browser plugin model inherently single-threaded, or random-threaded?