aboutsummaryrefslogtreecommitdiff
path: root/plugin/include/plugin.h
blob: abca9b5cbdbfb3f60915f1dc504b8313224b8dac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
 * 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 <stdbool.h>

#include <dlfcn.h>

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__)