diabol, what about treating the loaders as an extension of the core, in other words plugins that can have plugins?
By that I mean there is hierarchical structure like:
Core - plugins.rc
-> plugin A
-> plugin B
-> Loader for x86 API - plugins.rc
-> x86 plugin A
-> x86 plugin B
-> Loader for xoblite APi - plugins.rc
-> xoblite's sole plugin
And so on.. The future Core API would still be flexible as long as the following loader's were updated. You then wouldn't have to specify an order to try them in or anything like that, it would entirely be up to the end user configuration.
Perhaps I'm oversimplifying this, at which point.. Do what I said and not what's easiest? lol
That's exactly the structure I'm going for
However, the core doesn't load plugins by itself anymore, it only loads pluginloaders and forwards plugins to these.
It looks kind of like this (the pluginloaders don't exist yet, tho the 32bit loader is half done)
Blackbox.exe
-> Core Pluginloader (internal, loads whatever plugins the current api supports)
-> PluginA.dll
-> PluginB.dll
-> Wow64Adapter (loads 32bit plugins. uses api redirection to bridge the 64bit/32bit gap)
-> PluginHost32.exe
-> Core Pluginloader (loads whatever 32bit plugins the current api supports)
-> PluginC.dll (some 32bit plugin)
-> PluginD.dll
-> XobliteLoader32.dll (loads xoblite 32bit plugins)
-> PluginE.dll
-> LuaPluginLoader.dll
-> PluginF.lua
-> XobliteLoader.dll
-> PluginG.dll
This builds quite a complex hierarchy, but fits surprisingly well into bb's current plugin system.
Here's what happens when a plugin is loaded (via plugins.rc or bro@m):
Plugin load
1) The pluginmanager tries to load the plugin as a dll for examination.
1.1) If loading it as dll fails, go to step 4
2) The dll image is sanity checked and probed for the pluginloader signature functions.
2.1) If the signature is not found or incomplete, go to step 4
3) The plugin is determined to be a pluginloader, loaded and registered as such.
3.1) done.
4) The plugin is determined not to be a pluginloader.
5) Check if the plugin is marked to be loaded by a certain pluginloader A.
5.1) If not, go to step 7
6) If pluginloader A is present, try to load the plugin with pluginloader A.
6.1) on success, done.
7) Try for each pluginloader if it can load the plugin.
7.1) If one succeeds, done.
8) Loading has failed, report a cumulative error message from all pluginloaders.
Design choices
Internally bb maintains a list of entries for every line in plugins.rc
This also extends to pluginloaders, so they also show up in the enable/disable menu (beside the core loader) and in the 'about plugins' dialog.
plugin-specific information (such as the addresses of the plugin's functions) has been moved to a support structure which can be freely defined by the pluginloader.
For a pluginloader entry, that support structure is a pointer to the pluginloader itself
I have considered the idea of writing plugins which implement the pluginloader concept, so that i wouldn't have to touch bb's PluginManager, but that would have meant that plugins managed by a pluginloader could not be loaded via the plugins menu or plugins.rc, etc.
Making pluginloaders first-class citizens and plugins second-class lifts that restriction and makes both integrate nicely. To the outside, it looks like nothing ever changed and the usage is the same - on the inside, there's a great opportunity to clean up the interfaces and api
Plugins.rc
I've built the loader mechanism the way I did because I love low-level dll introspection (PluginManager.cpp line 372 fuck yeah, that's hot!) and because it requires no changes to existing plugins.rc files.
Pluginloaders are specified exactly the same way as plugins: a line with the name of the dll in it, optionally ! disabled or @ slitted (tho that is silly
The differences:
The restriction of plugins having to be *.dll is dropped as pluginloaders might load scripts or other voodoo and use different file extensions.
Plugin lines can add loader hints, which affect the way they are loaded and are passed to the loader:
bbKeys32.dll (wow64, xoblite) -- specifies plugin bbKeys32.dll should be loaded with the 32bit loader and the loader argument 'xoblite'
bbCalendar.dll (xoblite, bblean1.17.1) -- specifies plugin bbCalendar.dll should preferably be loaded with either xoblite or bblean1.17.1 api
The format itself is not final and in fact not implemented yet, but it will be something simple like this.
Notes:
Currently there is no mechanism for a pluginloader to load another pluginloader (except for the 32bit pluginhost, but that's a whole different can of worms). I might add that if it becomes neccessary, but atm I think it would only overcomplicate things.
With the way it currently works, the plugins are load order dependant.
I think loading pluginloaders before plugins when executing the plugins.rc might prevent some menu stupidity:
- user adds PluginA.xoblite.dll via menu, plugin fails to load
- user adds XobliteLoader.dll via menu
- user enables PluginA.xoblite.dll, plugin loads
- reboot and PluginA.xoblite.dll fails to load, because in plugins.rc it is before XobliteLoader.dll
In the current moj build, the pluginloader mechanism is already live, but because i didn't test it previously it's buggy for anything but the core pluginloader.
It's fixed now and will ship with rc4 or 5 (whenever the 32bit loader is at least half done).