registration.h
1 // SPDX-FileCopyrightText: 2023-2025 Le'Sec Core collective 2 // 3 // SPDX-License-Identifier: LGPL-3.0-or-later 4 5 #ifndef LSC_REGISTRATION_H 6 # define LSC_REGISTRATION_H 7 8 # include <lscore/export.h> 9 # include <lscore/environment.h> 10 11 # ifdef __cplusplus 12 extern "C" { 13 # endif 14 15 // Registration of implementations means storing a reference into 16 // a bag in an environment. This type is that bag. 17 LSC_DATA_SET_TYPES(implementation_bag); 18 LSC_DATA_SET_STRUCT(implementation_bag) { 19 LSC_DATA_SET_STRUCT_FIELDS(implementation_bag); 20 }; 21 22 // Because the implementation bag in itself is a type common to all 23 // types of implementations, and that registration is centered around 24 // the bag, the exact same set of LSC_NR_ values are used collectively 25 // for all of them. 26 enum { 27 LSC_NR_register_implementation = (0 + LSC_NR__data_set_class_start), 28 LSC_NR_deregister_implementation = (1 + LSC_NR__data_set_class_start), 29 LSC_NR_find_implementation = (2 + LSC_NR__data_set_class_start), 30 LSC_NR_do_all_implementations = (3 + LSC_NR__data_set_class_start), 31 }; 32 33 // Registration and deregistration functions factory 34 # define LSC_REGISTRATION_CALLBACK_TYPES(lsc_name) \ 35 typedef LE_STATUS \ 36 LSC_NAME(do_all_##lsc_name##_implementations_callback_fn) \ 37 (const char *class, const char *id, \ 38 const LSC_plugin_t *plugin, const LSC_env_t *env, \ 39 LSC_NAME(lsc_name##_dispatch_fn) *dispatch_function, \ 40 LSC_NAME(lsc_name##_destroy_fn) *destroy_function, \ 41 const void *dispatch_data, \ 42 const char *docstring, \ 43 void *user_arg) 44 # define LSC_REGISTRATION_FUNCTIONS(lsc_prefix, lsc_name) \ 45 LSC_REGISTRATION_CALLBACK_TYPES(lsc_name); \ 46 static inline LE_STATUS \ 47 LSC_NAME(register_##lsc_name##_implementation) \ 48 (LSC_env_t *env, LSC_plugin_t *plugin, const char *id, \ 49 LSC_NAME(lsc_name##_dispatch_fn) *dispatch_function, \ 50 LSC_NAME(lsc_name##_destroy_fn) *destroy_function, \ 51 const void *dispatch_data, \ 52 const char *docstring) \ 53 { \ 54 LE_STATUS sts; \ 55 LSC_implementation_bag_t *t; \ 56 const char *class = lsc_prefix #lsc_name; \ 57 \ 58 sts = LSC_get_environment_implementation_bag(env, class, &t); \ 59 if (LE_status_is_OK(sts)) \ 60 sts = t->lsc_dispatch(t, LSC_NR_register_implementation, \ 61 plugin, id, \ 62 dispatch_function, destroy_function, \ 63 dispatch_data, docstring); \ 64 return sts; \ 65 } \ 66 static inline LE_STATUS \ 67 LSC_NAME(deregister_##lsc_name##_implementation) \ 68 (LSC_env_t *env, LSC_plugin_t *plugin, const char *id, \ 69 LSC_NAME(lsc_name##_dispatch_fn) *dispatch_function, \ 70 LSC_NAME(lsc_name##_destroy_fn) *destroy_function, \ 71 const void *dispatch_data, \ 72 const char *docstring) \ 73 { \ 74 LE_STATUS sts; \ 75 LSC_implementation_bag_t *t; \ 76 const char *class = lsc_prefix #lsc_name; \ 77 \ 78 sts = LSC_get_environment_implementation_bag(env, class, &t); \ 79 if (LE_status_is_OK(sts)) \ 80 sts = t->lsc_dispatch(t, LSC_NR_deregister_implementation, \ 81 plugin, id, \ 82 dispatch_function, destroy_function, \ 83 dispatch_data, docstring); \ 84 return sts; \ 85 } \ 86 static inline LE_STATUS \ 87 LSC_NAME(find_##lsc_name##_implementation) \ 88 (LSC_env_t *env, const char *id, LSC_plugin_t **plugin, \ 89 LSC_NAME(lsc_name##_dispatch_fn) **dispatch_function, \ 90 LSC_NAME(lsc_name##_destroy_fn) **destroy_function, \ 91 const void **dispatch_data, \ 92 const char **docstring) \ 93 { \ 94 LE_STATUS sts; \ 95 LSC_implementation_bag_t *t; \ 96 const char *class = lsc_prefix #lsc_name; \ 97 \ 98 sts = LSC_get_environment_implementation_bag(env, class, &t); \ 99 if (LE_status_is_OK(sts)) \ 100 sts = t->lsc_dispatch(t, LSC_NR_find_implementation, \ 101 id, plugin, \ 102 dispatch_function, destroy_function, \ 103 dispatch_data, docstring); \ 104 return sts; \ 105 } \ 106 static inline LE_STATUS \ 107 LSC_NAME(do_all_##lsc_name##_implementations) \ 108 (LSC_env_t *env, \ 109 LSC_NAME(do_all_##lsc_name##_implementations_callback_fn) *fn, \ 110 void *user_arg) \ 111 { \ 112 LE_STATUS sts; \ 113 LSC_implementation_bag_t *t; \ 114 const char *tag = lsc_prefix #lsc_name; \ 115 \ 116 sts = LSC_get_environment_implementation_bag(env, tag, &t); \ 117 if (LE_status_is_OK(sts)) \ 118 sts = t->lsc_dispatch(t, LSC_NR_do_all_implementations, \ 119 fn, user_arg); \ 120 return sts; \ 121 } 122 123 # ifdef __cplusplus 124 } 125 # endif 126 127 #endif