/ include / lecore / plugin.h
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