plugin.h
1 // SPDX-FileCopyrightText: 2026 Le'Core collective 2 // 3 // SPDX-License-Identifier: LGPL-3.0-or-later 4 5 #ifndef LE_CORE_PLUGIN_H 6 # define LE_CORE_PLUGIN_H 7 8 # include <lecore/environment.h> 9 # include <lecore/export.h> 10 # include <lecore/macros.h> 11 # include <lecore/types.h> 12 13 # ifdef __cplusplus 14 extern "C" { 15 # endif 16 17 // Plugin invocation type, constructed like a core structure, with a little 18 // extra. We only implement the types, structure and constructor and 19 // destructor, no other functions. 20 // 21 // However, since this is a structure that's shared between the plugin 22 // itself and the aplication, and both may need to store associated data, 23 // this type supports setting and getting application specific data, by 24 // index. Index zero is reserved for the plugin's own data, and can only 25 // be accessed through specially crafted functions. 26 27 #define LeCore_plugin_st LE_CORE_NAME1(plugin_st) 28 #define LeCore_plugin_t LE_CORE_NAME1(plugin_t) 29 #define LeCore_plugin_dispatch_fn LE_CORE_NAME1(plugin_dispatch_fn) 30 #define LeCore_get_plugin_application_data LE_CORE_NAME1(get_plugin_application_data) 31 #define LeCore_get_plugin_application_data_args LE_CORE_NAME1(get_plugin_application_data_args) 32 #define LeCore_NR_get_plugin_application_data LE_CORE_NAME1(NR_get_plugin_application_data) 33 #define LeCore_set_plugin_application_data LE_CORE_NAME1(set_plugin_application_data) 34 #define LeCore_set_plugin_application_data_args LE_CORE_NAME1(set_plugin_application_data_args) 35 #define LeCore_NR_set_plugin_application_data LE_CORE_NAME1(NR_set_plugin_application_data) 36 37 // Set up aliases for core.inc 38 #define LeCore_st LeCore_plugin_st 39 #define LeCore_t LeCore_plugin_t 40 #define LeCore_dispatch_fn LeCore_plugin_dispatch_fn 41 #define LeCore_get_application_data LeCore_get_plugin_application_data 42 #define LeCore_get_application_data_args LeCore_get_plugin_application_data_args 43 #define LeCore_NR_get_application_data LeCore_NR_get_plugin_application_data 44 #define LeCore_set_application_data LeCore_set_plugin_application_data 45 #define LeCore_set_application_data_args LeCore_set_plugin_application_data_args 46 #define LeCore_NR_set_application_data LeCore_NR_set_plugin_application_data 47 #define LE_CORE_IMPL_APPDATA_FUNCTIONS 48 #include <lecore/core.inc> 49 50 // Start and stop function signatures. They are not at all mandatory. 51 // In fact, Le'Core couldn't care less! However, it's convenient for 52 // applications to have access to both "standard" names and signatures. 53 typedef LE_STATUS LeCore_plugin_start_fn(LeCore_plugin_t plugin); 54 typedef LE_STATUS LeCore_plugin_stop_fn(LeCore_plugin_t plugin); 55 56 // Convenience start and stop function declarations for dynamically 57 // loadable plugins. 58 LE_CORE_EXPORT LeCore_plugin_start_fn LeCore_plugin_start; 59 LE_CORE_EXPORT LeCore_plugin_stop_fn LeCore_plugin_stop; 60 // Convenience docstring declaration for dynamically loadable plugins. 61 LE_CORE_EXPORT extern const char LeCore_plugin_docstring[]; 62 63 // Functions to invoke and revoke a plugin. 64 // 65 // They are really just like the core construct and destruct functions 66 // found in core.inc, except that LeCore_invoke_plugin() assigns an 67 // internal dispatch function to the environment. 68 // In fact, LeCore_revoke_plugin() is just a simpler duplicate of the core 69 // destruct function. 70 #define LeCore_invoke_plugin LE_CORE_NAME1(invoke_plugin) 71 LE_CORE_EXPORT LE_STATUS LeCore_invoke_plugin(LeCore_plugin_start_fn *start, 72 LeCore_plugin_t *plugin, 73 LeCore_env_t env); 74 75 #define LeCore_revoke_plugin LE_CORE_NAME1(revoke_plugin) 76 #define LeCore_NR_revoke_plugin LE_CORE_NAME1(NR_revoke_plugin) 77 enum { LeCore_NR_revoke_plugin = 32 }; 78 static inline LE_STATUS LeCore_revoke_plugin(LeCore_plugin_stop_fn *stop, 79 LeCore_plugin_t *plugin) { 80 LE_STATUS sts; 81 if ((stop == NULL || LE_status_is_OK(sts = stop(*plugin))) 82 && LE_status_is_OK(sts = plugin->le_dispatch(*plugin, 83 LeCore_NR_revoke_plugin))) 84 *plugin = (LeCore_plugin_t){ NULL, NULL, NULL }; 85 return sts; 86 } 87 88 // LeCore_plugin_t setters and getters 89 90 #define LeCore_set_plugin_data LE_CORE_NAME1(set_plugin_data) 91 #define LeCore_set_plugin_data_args LE_CORE_NAME1(set_plugin_data_args) 92 #define LeCore_NR_set_plugin_data LE_CORE_NAME1(NR_set_plugin_data) 93 94 enum { LeCore_NR_set_plugin_data = 33 }; 95 typedef struct { 96 void *data; // in 97 } LeCore_set_plugin_data_args; 98 99 static inline LE_STATUS 100 LeCore_set_plugin_data(LeCore_plugin_t plugin, void *data) 101 { 102 return plugin.le_dispatch(plugin, LeCore_NR_set_plugin_data, 103 (LeCore_set_plugin_data_args){data}); 104 } 105 106 enum { LeCore_NR_get_plugin_data = 34 }; 107 typedef struct { 108 void **data; // in 109 } LeCore_get_plugin_data_args; 110 111 static inline LE_STATUS 112 LeCore_get_plugin_data(LeCore_plugin_t plugin, void **data) 113 { 114 return plugin.le_dispatch(plugin, LeCore_NR_get_plugin_data, 115 (LeCore_set_plugin_data_args){data}); 116 } 117 118 enum { LeCore_NR_get_plugin_parent_environment = 35 }; 119 typedef struct { 120 LeCore_env_t *parent_env; // out 121 } LeCore_get_plugin_parent_environment_args; 122 123 static inline LE_STATUS 124 LeCore_get_plugin_parent_environment(LeCore_plugin_t plugin, 125 LeCore_env_t *parent_env) 126 { 127 return plugin.le_dispatch(plugin, LeCore_NR_get_plugin_parent_environment, 128 (LeCore_get_plugin_parent_environment_args){parent_env}); 129 } 130 131 # ifdef __cplusplus 132 } 133 # endif 134 135 #endif