/* * Plugin engine for loading plugins and watching plugin updates. * * The plugin engine allows the client to load plugins and call their functions. * * Plugins can also be associated with a state. The engine does not create the * plugin's state because this may require other application-specific state. * * Plugin files are watched for updates. Upon an update, the engine reloads the * plugin into memory and notifies the client. The client should then typically * re-create the plugin's state. */ #pragma once #include #include typedef struct Plugin Plugin; typedef struct PluginEngine PluginEngine; /// Plugin engine creation depluginor. typedef struct PluginEngineDesc { const char* plugins_dir; } PluginEngineDesc; /// Create a new plugin engine. PluginEngine* new_plugin_engine(const PluginEngineDesc*); /// Destroy the plugin engine. void delete_plugin_engine(PluginEngine**); /// Update the plugin engine. /// /// This looks for any plugins that have been modified and reloads them. void plugin_engine_update(PluginEngine*); /// Load a plugin. Plugin* load_plugin(PluginEngine*, const char* filename); /// Delete the plugin. /// /// This unloads the plugin from memory and removes it from the engine. void delete_plugin(Plugin**); /// Set the plugin's state. /// /// The plugin's previous state is deleted if non-null. void set_plugin_state(Plugin*, void* state); /// Get the plugin's state. Return null if the plugin has no state. void* get_plugin_state(Plugin*); /// Return true if the plugin has been reloaded. /// /// If the plugin has been reloaded, subsequent calls to this function return /// false until the plugin is reloaded again. bool plugin_reloaded(Plugin*); /// Resolve a function in the plugin. #define plugin_resolve(plugin, func_sig, func_name) \ (func_sig)(dlsym(*((void**)(plugin)), func_name)) /// Call a function in the plugin. #define plugin_call(plugin, func_sig, func_name, ...) \ (*plugin_resolve(plugin, func_sig, func_name))(__VA_ARGS__)