Loads, manages, and safely unloads dynamically linked plugins. More...
#include <PluginManager.h>
Public Member Functions | |
| PluginManager (const std::string &pluginPath="") | |
Construct a PluginManager with a default plugin search path. | |
| std::vector< Plugin * > | getPlugins () |
| Return all currently loaded plugins. | |
| Plugin * | loadPlugin (const std::string &path) |
| Load a single plugin from a shared library path. | |
| void | loadPluginsFromDirectory (const std::string &dir) |
| Load all plugin libraries found in a directory. | |
| std::vector< PluginInfo > | scanPlugins (const std::string &dir) |
| Probe a directory for plugins without keeping them loaded. | |
| void | unloadPlugin (Plugin *plugin) |
| Unload a plugin and close its shared library. | |
Static Public Member Functions | |
| static void | clearPending () |
| Discard all pending operations without executing them. | |
| static bool | isBusy () |
Return true if the manager is currently iterating. | |
| static void | processPending () |
| Flush all pending operations immediately. | |
Static Protected Member Functions | |
| static void | beginBusy () |
| Signal that iteration has begun. | |
| static void | deferOrExecute (std::function< void()> operation) |
Execute operation now if safe, otherwise queue it. | |
| static void | endBusy () |
| Signal that iteration has ended; flush pending operations. | |
Static Protected Attributes | |
| static int | busyDepth |
| Iteration nesting depth. Operations are deferred while this is > 0. | |
| static std::vector< std::function< void()> > | pendingOperations |
| Queue of operations pending until the current iteration completes. | |
Loads, manages, and safely unloads dynamically linked plugins.
PluginManager handles the full plugin lifecycle:
loadPlugin opens a shared library, locates the createPlugin factory (exported by REGISTER_PLUGIN), constructs the plugin, and calls Plugin::onLoad().getPlugins returns all active plugins; type-safe interface queries should use Plugin::getIf<T>().scanPlugins probes a directory for plugin libraries without keeping them loaded, returning PluginInfo records (including CPU-side thumbnail copies) for display in a carousel.unloadPlugin calls Plugin::onUnload(), force-unsubscribes all event and message subscriptions, deletes the plugin, and closes the library handle.PluginManager inherits DeferredOperationsManager<PluginManager>. Calling unloadPlugin from within a message or event callback is safe — the actual unload is deferred until the current iteration completes, preventing use-after-free crashes.
The LOAD_LIB, GET_FUNC, and CLOSE_LIB macros abstract the platform differences between dlopen (macOS/Linux) and LoadLibraryA (Windows).
Definition at line 78 of file PluginManager.h.
| ml::PluginManager::PluginManager | ( | const std::string & | pluginPath = "" | ) |
Construct a PluginManager with a default plugin search path.
| pluginPath | Default directory used by loadPluginsFromDirectory when no path is provided. Can be overridden per-call. |
|
staticprotectedinherited |
Signal that iteration has begun.
Increments the busy-depth counter. Multiple nested calls are safe — operations remain deferred until the outermost endBusy() is reached.
|
staticinherited |
Discard all pending operations without executing them.
Use during application shutdown or full reset when executing the queued operations would be unsafe (e.g., the objects they reference have already been destroyed).
|
staticprotectedinherited |
Execute operation now if safe, otherwise queue it.
If busyDepth > 0 the operation is appended to pendingOperations and will run when the current iteration completes. If the manager is idle the operation executes immediately.
| operation | The callable to execute or defer. |
|
staticprotectedinherited |
Signal that iteration has ended; flush pending operations.
Decrements the busy-depth counter. When the counter reaches zero, all operations in pendingOperations are executed in FIFO order and the queue is cleared.
| std::vector< Plugin * > ml::PluginManager::getPlugins | ( | ) |
Return all currently loaded plugins.
Processes any pending deferred unloads before returning, so the vector is always consistent with the current manager state.
Plugin instances. Do not store these pointers across calls to unloadPlugin.
|
staticinherited |
Return true if the manager is currently iterating.
Can be used by external code that needs to know whether a destructive operation will be deferred.
true when busyDepth > 0. | Plugin * ml::PluginManager::loadPlugin | ( | const std::string & | path | ) |
Load a single plugin from a shared library path.
Opens the library at path, calls the createPlugin factory function (exported by REGISTER_PLUGIN), and calls Plugin::onLoad() on the result. Returns nullptr if the library cannot be opened or the factory symbol is not found.
| path | Absolute or relative path to the plugin shared library (.dylib, .so, or .dll). |
nullptr on failure. | void ml::PluginManager::loadPluginsFromDirectory | ( | const std::string & | dir | ) |
Load all plugin libraries found in a directory.
Scans dir for files with the platform plugin extension and calls loadPlugin for each one. Silently skips files that fail to load.
| dir | Path to the directory to scan. |
|
staticinherited |
Flush all pending operations immediately.
Normally called automatically by endBusy(). Provided as a public escape hatch for unusual teardown sequences.
isBusy() is true can cause iterator invalidation in the currently running loop. Only call manually when you are certain it is safe. | std::vector< PluginInfo > ml::PluginManager::scanPlugins | ( | const std::string & | dir | ) |
Probe a directory for plugins without keeping them loaded.
Temporarily loads each plugin library, reads its name, version, and thumbnail, copies the thumbnail texture to CPU memory, then immediately unloads the library. The resulting PluginInfo records contain everything needed to populate a game-selection carousel.
| dir | Path to the directory to scan. |
PluginInfo records, one per successfully probed plugin. | void ml::PluginManager::unloadPlugin | ( | Plugin * | plugin | ) |
Unload a plugin and close its shared library.
Queues the following sequence for deferred execution:
EventsManager::forceUnsubscribeAll and MessageManager::forceUnsubscribeAll — removes all subscriptions immediately so no callbacks fire after the plugin is gone.Plugin::onUnload() — gives the plugin a chance to clean up.delete plugin — destroys the plugin object.CLOSE_LIB(handle) — unloads the shared library.If called from within an event or message callback, all of the above is deferred until the active iteration completes.
| plugin | Pointer to the plugin to unload. Must have been returned by loadPlugin or getPlugins. Passing nullptr is safe. |
|
inlinestaticprotectedinherited |
Iteration nesting depth. Operations are deferred while this is > 0.
Definition at line 69 of file DeferredOperationsManager.h.
|
inlinestaticprotectedinherited |
Queue of operations pending until the current iteration completes.
Definition at line 72 of file DeferredOperationsManager.h.