diff --git a/Makefile b/Makefile index 16c3fa1..a47f768 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ ASFLAGS := -g $(MACHDEP) # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS := +LIBDIRS := $(WUT_ROOT) #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional diff --git a/include/wups.h b/include/wups.h index bb6857f..6e7f493 100644 --- a/include/wups.h +++ b/include/wups.h @@ -27,8 +27,17 @@ #include "wups/common.h" #include "wups/config.h" -#include "wups/config_imports.h" +#include "wups/config_api.h" #include "wups/function_patching.h" #include "wups/hooks.h" #include "wups/meta.h" #include "wups/storage.h" +#ifdef DEBUG +#include +#endif + +#ifdef DEBUG +#define WUPS_DEBUG_REPORT(fmt, ...) OSReport(fmt, ##__VA_ARGS__) +#else +#define WUPS_DEBUG_REPORT(fmt, ...) +#endif diff --git a/include/wups/config.h b/include/wups/config.h index b0529dd..9491d36 100644 --- a/include/wups/config.h +++ b/include/wups/config.h @@ -38,6 +38,26 @@ #define WUPS_CONFIG_BUTTON_MINUS (1 << 15) typedef int32_t WUPSConfigButtons; +typedef enum WUPSConfigAPIStatus { + WUPSCONFIG_API_RESULT_SUCCESS = 0, + WUPSCONFIG_API_RESULT_INVALID_ARGUMENT = -0x01, + WUPSCONFIG_API_RESULT_OUT_OF_MEMORY = -0x03, + WUPSCONFIG_API_RESULT_NOT_FOUND = -0x06, + WUPSCONFIG_API_RESULT_INVALID_PLUGIN_IDENTIFIER = -0x70, + WUPSCONFIG_API_RESULT_MISSING_CALLBACK = -0x71, + WUPSCONFIG_API_RESULT_MODULE_NOT_FOUND = -0x80, + WUPSCONFIG_API_RESULT_MODULE_MISSING_EXPORT = -0x81, + WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION = -0x82, + WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND = -0x83, + WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED = -0x84, + WUPSCONFIG_API_RESULT_UNKNOWN_ERROR = -0x100, +} WUPSConfigAPIStatus; + +typedef enum WUPSConfigAPICallbackStatus { + WUPSCONFIG_API_CALLBACK_RESULT_SUCCESS = 0, + WUPSCONFIG_API_CALLBACK_RESULT_ERROR = -1, +} WUPSConfigAPICallbackStatus; + typedef struct { int32_t (*getCurrentValueDisplay)(void *context, char *out_buf, int32_t out_size); @@ -54,8 +74,101 @@ typedef struct { void (*onButtonPressed)(void *context, WUPSConfigButtons button); void (*onDelete)(void *context); -} WUPSConfigCallbacks_t; +} WUPSConfigAPIItemCallbacksV1; + +#define WUPS_API_ITEM_OPTION_VERSION_V1 1 +typedef struct WUPSConfigAPIItemOptionsV1 { + const char *displayName; + void *context; + WUPSConfigAPIItemCallbacksV1 callbacks; +} WUPSConfigAPIItemOptionsV1; + +typedef struct WUPSConfigAPICreateItemOptions { + uint32_t version; + union { + WUPSConfigAPIItemOptionsV1 v1; + } data; +} WUPSConfigAPICreateItemOptions; + +typedef uint32_t WUPSConfigAPIVersion; + +typedef struct WUPSConfigItemHandle { + void *handle; +#ifdef __cplusplus + WUPSConfigItemHandle() { + handle = nullptr; + } + explicit WUPSConfigItemHandle(void *handle) : handle(handle) {} + bool operator==(const WUPSConfigItemHandle other) const { + return handle == other.handle; + } + bool operator==(const void *other) const { + return handle == other; + } +#endif +} WUPSConfigItemHandle; + +typedef struct WUPSConfigHandle { + void *handle; +#ifdef __cplusplus + WUPSConfigHandle() { + handle = nullptr; + } + explicit WUPSConfigHandle(void *handle) : handle(handle) {} + bool operator==(const WUPSConfigHandle other) const { + return handle == other.handle; + } + bool operator==(const void *other) const { + return handle == other; + } +#endif +} WUPSConfigHandle; + +typedef struct WUPSConfigCategoryHandle { + void *handle; +#ifdef __cplusplus + WUPSConfigCategoryHandle() { + handle = nullptr; + } + explicit WUPSConfigCategoryHandle(void *handle) : handle(handle) {} + bool operator==(const WUPSConfigCategoryHandle other) const { + return handle == other.handle; + } + bool operator==(const void *other) const { + return handle == other; + } +#endif +} WUPSConfigCategoryHandle; + +#define WUPS_API_CATEGORY_OPTION_VERSION_V1 1 + +typedef struct WUPSConfigAPICreateCategoryOptionsV1 { + const char *name; +} WUPSConfigAPICreateCategoryOptionsV1; + +typedef struct WUPSConfigAPICreateCategoryOptions { + uint32_t version; + union { + WUPSConfigAPICreateCategoryOptionsV1 v1; + } data; +} WUPSConfigAPICreateCategoryOptions; + +#define WUPS_API_CONFIG_API_OPTION_VERSION_V1 1 + +typedef struct WUPSConfigAPIOptionsV1 { + const char *name; +} WUPSConfigAPIOptionsV1; + +typedef struct WUPSConfigAPIOptions { + uint32_t version; + union { + WUPSConfigAPIOptionsV1 v1; + } data; +} WUPSConfigAPIOptions; + +#define WUPS_CONFIG_API_VERSION_ERROR 0xFFFFFFFF -typedef uint32_t WUPSConfigItemHandle; -typedef uint32_t WUPSConfigHandle; -typedef uint32_t WUPSConfigCategoryHandle; \ No newline at end of file +typedef struct wups_loader_init_config_args_t { + uint32_t arg_version; + uint32_t plugin_identifier; +} wups_loader_init_config_args_t; diff --git a/include/wups/config/WUPSConfigItemBoolean.h b/include/wups/config/WUPSConfigItemBoolean.h index 90a0cc0..877dd9d 100644 --- a/include/wups/config/WUPSConfigItemBoolean.h +++ b/include/wups/config/WUPSConfigItemBoolean.h @@ -20,22 +20,6 @@ bool WUPSConfigItemBoolean_AddToCategory(WUPSConfigCategoryHandle cat, const cha bool WUPSConfigItemBoolean_AddToCategoryEx(WUPSConfigCategoryHandle cat, const char *configId, const char *displayName, bool defaultValue, BooleanValueChangedCallback callback, const char *trueValue, const char *falseValue); -#define WUPSConfigItemBoolean_AddToCategoryHandled(__config__, __cat__, __configIs__, __displayName__, __defaultValue__, __callback__) \ - do { \ - if (!WUPSConfigItemBoolean_AddToCategory(__cat__, __configIs__, __displayName__, __defaultValue__, __callback__)) { \ - WUPSConfig_Destroy(__config__); \ - return 0; \ - } \ - } while (0) - -#define WUPSConfigItemBoolean_AddToCategoryHandledEx(__config__, __cat__, __configID__, __displayName__, __defaultValue__, __callback__, __trueValue__, __falseValue__) \ - do { \ - if (!WUPSConfigItemBoolean_AddToCategoryEx(__cat__, __configID__, __displayName__, __defaultValue__, __callback__, __trueValue__, __falseValue__)) { \ - WUPSConfig_Destroy(__config__); \ - return 0; \ - } \ - } while (0) - #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/include/wups/config/WUPSConfigItemIntegerRange.h b/include/wups/config/WUPSConfigItemIntegerRange.h index 0f1bb1e..1d610f3 100644 --- a/include/wups/config/WUPSConfigItemIntegerRange.h +++ b/include/wups/config/WUPSConfigItemIntegerRange.h @@ -20,14 +20,6 @@ bool WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandle cat, cons int32_t defaultValue, int32_t minValue, int32_t maxValue, IntegerRangeValueChangedCallback callback); -#define WUPSConfigItemIntegerRange_AddToCategoryHandled(__config__, __cat__, __configId__, __displayName__, __defaultValue__, __minValue__, __maxValue__, __callback__) \ - do { \ - if (!WUPSConfigItemIntegerRange_AddToCategory(__cat__, __configId__, __displayName__, __defaultValue__, __minValue__, __maxValue__, __callback__)) { \ - WUPSConfig_Destroy(__config__); \ - return 0; \ - } \ - } while (0) - #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/include/wups/config/WUPSConfigItemMultipleValues.h b/include/wups/config/WUPSConfigItemMultipleValues.h index f1f249f..76c5fc0 100644 --- a/include/wups/config/WUPSConfigItemMultipleValues.h +++ b/include/wups/config/WUPSConfigItemMultipleValues.h @@ -1,4 +1,6 @@ -#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -24,14 +26,6 @@ typedef void (*MultipleValuesChangedCallback)(ConfigItemMultipleValues *, uint32 bool WUPSConfigItemMultipleValues_AddToCategory(WUPSConfigCategoryHandle cat, const char *configId, const char *displayName, int defaultValueIndex, ConfigItemMultipleValuesPair *possibleValues, int pairCount, MultipleValuesChangedCallback callback); -#define WUPSConfigItemMultipleValues_AddToCategoryHandled(__config__, __cat__, __configID__, __displayName__, __defaultValueIndex__, __possibleValues__, __pairCount__, __callback__) \ - do { \ - if (!WUPSConfigItemMultipleValues_AddToCategory(__cat__, __configID__, __displayName__, __defaultValueIndex__, __possibleValues__, __pairCount__, __callback__)) { \ - WUPSConfig_Destroy(__config__); \ - return 0; \ - } \ - } while (0) - #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/include/wups/config/WUPSConfigItemStub.h b/include/wups/config/WUPSConfigItemStub.h index c2335bf..a2141c1 100644 --- a/include/wups/config/WUPSConfigItemStub.h +++ b/include/wups/config/WUPSConfigItemStub.h @@ -10,14 +10,6 @@ typedef struct ConfigItemStub { bool WUPSConfigItemStub_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName); -#define WUPSConfigItemStub_AddToCategoryHandled(__config__, __cat__, __configID__, __displayName__) \ - do { \ - if (!WUPSConfigItemStub_AddToCategory(__cat__, __configID__, __displayName__)) { \ - WUPSConfig_Destroy(__config__); \ - return 0; \ - } \ - } while (0) - #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/include/wups/config_api.h b/include/wups/config_api.h new file mode 100644 index 0000000..25ffba9 --- /dev/null +++ b/include/wups/config_api.h @@ -0,0 +1,52 @@ +#pragma once + +#include "config.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef WUPSConfigAPICallbackStatus (*WUPSConfigAPI_MenuOpenedCallback)(WUPSConfigCategoryHandle root); +typedef void (*WUPSConfigAPI_MenuClosedCallback)(); + +WUPSConfigAPIStatus WUPSConfigAPI_InitEx(uint32_t pluginIdentifier, WUPSConfigAPIOptions, WUPSConfigAPI_MenuOpenedCallback, WUPSConfigAPI_MenuClosedCallback); + +WUPSConfigAPIStatus WUPSConfigAPI_Init(WUPSConfigAPIOptionsV1 optionsV1, WUPSConfigAPI_MenuOpenedCallback openedCallback, WUPSConfigAPI_MenuClosedCallback closedCallback); + +WUPSConfigAPIStatus WUPSConfigAPI_GetVersion(WUPSConfigAPIVersion *outVariable); + +WUPSConfigAPIStatus WUPSConfigAPI_Category_CreateEx(WUPSConfigAPICreateCategoryOptions options, WUPSConfigCategoryHandle *out); + +static inline WUPSConfigAPIStatus WUPSConfigAPI_Category_Create(WUPSConfigAPICreateCategoryOptionsV1 options, WUPSConfigCategoryHandle *out) { + WUPSConfigAPICreateCategoryOptions optionsWrapper = { + .version = WUPS_API_CATEGORY_OPTION_VERSION_V1, + .data = {.v1 = options}, + }; + return WUPSConfigAPI_Category_CreateEx(optionsWrapper, out); +} + +WUPSConfigAPIStatus WUPSConfigAPI_Category_Destroy(WUPSConfigCategoryHandle handle); + +WUPSConfigAPIStatus WUPSConfigAPI_Category_AddCategory(WUPSConfigCategoryHandle parentHandle, WUPSConfigCategoryHandle categoryHandle); + +WUPSConfigAPIStatus WUPSConfigAPI_Category_AddItem(WUPSConfigCategoryHandle parentHandle, WUPSConfigItemHandle itemHandle); + +WUPSConfigAPIStatus WUPSConfigAPI_Item_CreateEx(WUPSConfigAPICreateItemOptions options, WUPSConfigItemHandle *out); + +static inline WUPSConfigAPIStatus WUPSConfigAPI_Item_Create(WUPSConfigAPIItemOptionsV1 options, WUPSConfigItemHandle *out) { + WUPSConfigAPICreateItemOptions itemOptions = { + .version = WUPS_API_ITEM_OPTION_VERSION_V1, + .data = {.v1 = options}, + }; + return WUPSConfigAPI_Item_CreateEx(itemOptions, out); +} + +WUPSConfigAPIStatus WUPSConfigAPI_Item_Destroy(WUPSConfigItemHandle handle); + +const char *WUPSConfigAPI_GetStatusStr(WUPSConfigAPIStatus status); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/wups/config_imports.h b/include/wups/config_imports.h deleted file mode 100644 index 275d0ab..0000000 --- a/include/wups/config_imports.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include "config.h" -#include "stdint.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int32_t WUPSConfigItem_Create(WUPSConfigItemHandle *out, const char *configID, const char *displayName, WUPSConfigCallbacks_t callbacks, void *context); - -int32_t WUPSConfigItem_Destroy(WUPSConfigItemHandle handle); - -int32_t WUPSConfig_Destroy(WUPSConfigHandle handle); - -int32_t WUPSConfigItem_SetDisplayName(WUPSConfigItemHandle handle, const char *displayName); - -int32_t WUPSConfigItem_GetDisplayName(WUPSConfigItemHandle handle, char *out_buf, int32_t out_len); - -int32_t WUPSConfigItem_SetConfigID(WUPSConfigItemHandle handle, const char *configID); - -int32_t WUPSConfigItem_GetConfigID(WUPSConfigItemHandle handle, char *out_buf, int32_t out); - -int32_t WUPSConfig_Create(WUPSConfigHandle *out, const char *name); - -int32_t WUPSConfigCategory_Destroy(WUPSConfigCategoryHandle handle); - -int32_t WUPSConfig_GetName(WUPSConfigHandle handle, char *out_buf, int32_t out_len); - -int32_t WUPSConfig_AddCategoryByName(WUPSConfigHandle handle, const char *categoryName, WUPSConfigCategoryHandle *out); - -int32_t WUPSConfig_AddCategory(WUPSConfigHandle handle, WUPSConfigCategoryHandle category); - -/* -int32_t WUPSConfig_GetCategoryCount(WUPSConfigHandle handle, int32_t *category_count); - -int32_t WUPSConfig_GetCategories(WUPSConfigHandle handle, WUPSConfigCategoryHandle *categories_out, int32_t categories_out_size); - */ - -int32_t WUPSConfigCategory_Create(WUPSConfigCategoryHandle *out, const char *name); - -int32_t WUPSConfigCategory_GetName(WUPSConfigCategoryHandle handle, char *out_buf, int32_t out_len); - -int32_t WUPSConfigCategory_AddItem(WUPSConfigCategoryHandle handle, WUPSConfigItemHandle item_Handle); - -#define WUPSConfig_AddCategoryByNameHandled(__config__, __categoryName__, __out__) \ - do { \ - if (WUPSConfig_AddCategoryByName(__config__, __categoryName__, __out__) < 0) { \ - WUPSConfig_Destroy(__config__); \ - return 0; \ - } \ - } while (0) - -#define WUPSConfig_CreateHandled(__config__, __configName__) \ - do { \ - if (WUPSConfig_Create(__config__, __configName__) < 0) { \ - return 0; \ - } \ - } while (0) - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/include/wups/hooks.h b/include/wups/hooks.h index 5a30744..68752df 100644 --- a/include/wups/hooks.h +++ b/include/wups/hooks.h @@ -44,20 +44,21 @@ typedef enum wups_loader_hook_type_t { WUPS_LOADER_HOOK_INIT_WRAPPER, /* Calls __init */ WUPS_LOADER_HOOK_FINI_WRAPPER, /* Calls __fini */ - WUPS_LOADER_HOOK_GET_CONFIG, - WUPS_LOADER_HOOK_CONFIG_CLOSED, + WUPS_LOADER_HOOK_GET_CONFIG_DEPRECATED, /* Deprecated implementation */ + WUPS_LOADER_HOOK_CONFIG_CLOSED_DEPRECATED, /* Deprecated implementation */ WUPS_LOADER_HOOK_INIT_STORAGE_DEPRECATED, /* Deprecated implementation */ WUPS_LOADER_HOOK_INIT_PLUGIN, /* Called when exiting the plugin loader */ WUPS_LOADER_HOOK_DEINIT_PLUGIN, /* Called when re-entering the plugin loader */ WUPS_LOADER_HOOK_APPLICATION_STARTS, /* Called when an application gets started */ - WUPS_LOADER_HOOK_RELEASE_FOREGROUND, /* Called when an foreground is going to be released */ - WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND, /* Called when an foreground is acquired */ + WUPS_LOADER_HOOK_RELEASE_FOREGROUND, /* Called when a foreground is going to be released */ + WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND, /* Called when a foreground is acquired */ WUPS_LOADER_HOOK_APPLICATION_REQUESTS_EXIT, /* Called when an application wants to exit */ WUPS_LOADER_HOOK_APPLICATION_ENDS, /* Called when an application ends */ WUPS_LOADER_HOOK_INIT_STORAGE, /* Only for internal usage */ + WUPS_LOADER_HOOK_INIT_CONFIG, /* Only for internal usage */ } wups_loader_hook_type_t; typedef struct wups_loader_hook_t { @@ -100,15 +101,11 @@ typedef struct wups_loader_hook_t { WUPS_HOOK_EX(WUPS_LOADER_HOOK_APPLICATION_ENDS, on_app_ending); \ void on_app_ending(void) -#define WUPS_GET_CONFIG() \ - WUPSConfigHandle on_get_wups_config(void); \ - WUPS_HOOK_EX(WUPS_LOADER_HOOK_GET_CONFIG, on_get_wups_config); \ - WUPSConfigHandle on_get_wups_config(void) +#define WUPS_GET_CONFIG(x) \ + static_assert(false, "Please use \"WUPSConfigAPI_Init\" inside \"INITIALIZE_PLUGIN\" to provide a callback instead"); -#define WUPS_CONFIG_CLOSED() \ - void on_wups_config_closed(void); \ - WUPS_HOOK_EX(WUPS_LOADER_HOOK_CONFIG_CLOSED, on_wups_config_closed); \ - void on_wups_config_closed(void) +#define WUPS_CONFIG_CLOSED() \ + static_assert(false, "Please use \"WUPSConfigAPI_Init\" inside \"INITIALIZE_PLUGIN\" to provide a callback instead"); #define WUPS_USE_STORAGE(x) \ WUPS_META(storage_id, x); \ @@ -118,12 +115,21 @@ typedef struct wups_loader_hook_t { WUPS_InitStorage(args); \ } + #ifdef __cplusplus #define __EXTERN_C_MACRO extern "C" #else #define __EXTERN_C_MACRO #endif +#define WUPS_INIT_CONFIG_FUNCTIONS() \ + __EXTERN_C_MACRO WUPSConfigAPIStatus WUPSConfigAPI_InitLibrary_Internal(wups_loader_init_config_args_t args); \ + void wups_init_config_functions(wups_loader_init_config_args_t); \ + WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_CONFIG, wups_init_config_functions); \ + void wups_init_config_functions(wups_loader_init_config_args_t args) { \ + WUPSConfigAPI_InitLibrary_Internal(args); \ + } + #define WUPS_USE_WUT_MALLOC() \ __EXTERN_C_MACRO void __init_wut_malloc(); \ void on_init_wut_malloc() { \ diff --git a/include/wups/meta.h b/include/wups/meta.h index e935c71..3cd6bec 100644 --- a/include/wups/meta.h +++ b/include/wups/meta.h @@ -48,6 +48,7 @@ extern "C" { WUPS_USE_WUT_STDCPP(); \ WUPS___INIT_WRAPPER(); \ WUPS___FINI_WRAPPER(); \ + WUPS_INIT_CONFIG_FUNCTIONS(); \ WUPS_META(buildtimestamp, __DATE__ " " __TIME__); \ extern const char wups_meta_plugin_name[] WUPS_SECTION("meta"); \ const char wups_meta_plugin_name[] = __plugin_name; \ diff --git a/libraries/libwups/WUPSConfigItemBoolean.cpp b/libraries/libwups/WUPSConfigItemBoolean.cpp index e74f10d..f24637c 100644 --- a/libraries/libwups/WUPSConfigItemBoolean.cpp +++ b/libraries/libwups/WUPSConfigItemBoolean.cpp @@ -4,8 +4,6 @@ #include #include -void WUPSConfigItemBoolean_onDelete(void *context); - int32_t WUPSConfigItemBoolean_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) { auto *item = (ConfigItemBoolean *) context; snprintf(out_buf, out_size, " %s", item->value ? item->trueValue : item->falseValue); @@ -58,10 +56,22 @@ void WUPSConfigItemBoolean_restoreDefault(void *context) { void WUPSConfigItemBoolean_onSelected(void *context, bool isSelected) { } +static void WUPSConfigItemBoolean_Cleanup(ConfigItemBoolean *item) { + if (!item) { + return; + } + free(item->configId); + free(item); +} + +void WUPSConfigItemBoolean_onDelete(void *context) { + WUPSConfigItemBoolean_Cleanup((ConfigItemBoolean *) context); +} + extern "C" bool WUPSConfigItemBoolean_AddToCategoryEx(WUPSConfigCategoryHandle cat, const char *configId, const char *displayName, bool defaultValue, BooleanValueChangedCallback callback, const char *trueValue, const char *falseValue) { - if (cat == 0) { + if (cat == nullptr) { return false; } auto *item = (ConfigItemBoolean *) malloc(sizeof(ConfigItemBoolean)); @@ -81,7 +91,7 @@ WUPSConfigItemBoolean_AddToCategoryEx(WUPSConfigCategoryHandle cat, const char * snprintf(item->trueValue, sizeof(item->trueValue), "%s", trueValue); snprintf(item->falseValue, sizeof(item->falseValue), "%s", falseValue); - WUPSConfigCallbacks_t callbacks = { + WUPSConfigAPIItemCallbacksV1 callbacks = { .getCurrentValueDisplay = &WUPSConfigItemBoolean_getCurrentValueDisplay, .getCurrentValueSelectedDisplay = &WUPSConfigItemBoolean_getCurrentValueSelectedDisplay, .onSelected = &WUPSConfigItemBoolean_onSelected, @@ -91,24 +101,24 @@ WUPSConfigItemBoolean_AddToCategoryEx(WUPSConfigCategoryHandle cat, const char * .onButtonPressed = &WUPSConfigItemBoolean_onButtonPressed, .onDelete = &WUPSConfigItemBoolean_onDelete}; - if (WUPSConfigItem_Create(&item->handle, configId, displayName, callbacks, item) < 0) { - free(item); + WUPSConfigAPIItemOptionsV1 options = { + .displayName = displayName, + .context = item, + .callbacks = callbacks, + }; + + if (WUPSConfigAPI_Item_Create(options, &item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigItemBoolean_Cleanup(item); return false; } - if (WUPSConfigCategory_AddItem(cat, item->handle) < 0) { - WUPSConfigItem_Destroy(item->handle); + if (WUPSConfigAPI_Category_AddItem(cat, item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigAPI_Item_Destroy(item->handle); return false; } return true; } -void WUPSConfigItemBoolean_onDelete(void *context) { - auto *item = (ConfigItemBoolean *) context; - free(item->configId); - free(item); -} - extern "C" bool WUPSConfigItemBoolean_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, bool defaultValue, BooleanValueChangedCallback callback) { return WUPSConfigItemBoolean_AddToCategoryEx(cat, configID, displayName, defaultValue, callback, "true", "false"); } diff --git a/libraries/libwups/WUPSConfigItemIntegerRange.cpp b/libraries/libwups/WUPSConfigItemIntegerRange.cpp index e685941..e6ff09c 100644 --- a/libraries/libwups/WUPSConfigItemIntegerRange.cpp +++ b/libraries/libwups/WUPSConfigItemIntegerRange.cpp @@ -59,13 +59,19 @@ void WUPSConfigItemIntegerRange_restoreDefault(void *context) { item->value = item->defaultValue; } -void WUPSConfigItemIntegerRange_onDelete(void *context) { - auto *item = (ConfigItemIntegerRange *) context; +void WUPSConfigItemIntegerRange_onSelected(void *context, bool isSelected) { +} + +static void WUPSConfigItemIntegerRange_Cleanup(ConfigItemIntegerRange *item) { + if (!item) { + return; + } free(item->configId); free(item); } -void WUPSConfigItemIntegerRange_onSelected(void *context, bool isSelected) { +void WUPSConfigItemIntegerRange_onDelete(void *context) { + WUPSConfigItemIntegerRange_Cleanup((ConfigItemIntegerRange *) context); } extern "C" bool WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandle cat, const char *configId, const char *displayName, int32_t defaultValue, int32_t minValue, int32_t maxValue, @@ -90,7 +96,7 @@ extern "C" bool WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandl item->maxValue = maxValue; item->callback = (void *) callback; - WUPSConfigCallbacks_t callbacks = { + WUPSConfigAPIItemCallbacksV1 callbacks = { .getCurrentValueDisplay = &WUPSConfigItemIntegerRange_getCurrentValueDisplay, .getCurrentValueSelectedDisplay = &WUPSConfigItemIntegerRange_getCurrentValueSelectedDisplay, .onSelected = &WUPSConfigItemIntegerRange_onSelected, @@ -100,13 +106,19 @@ extern "C" bool WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandl .onButtonPressed = &WUPSConfigItemIntegerRange_onButtonPressed, .onDelete = &WUPSConfigItemIntegerRange_onDelete}; - if (WUPSConfigItem_Create(&(item->handle), configId, displayName, callbacks, item) < 0) { - free(item); + WUPSConfigAPIItemOptionsV1 options = { + .displayName = displayName, + .context = item, + .callbacks = callbacks, + }; + + if (WUPSConfigAPI_Item_Create(options, &(item->handle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigItemIntegerRange_Cleanup(item); return false; }; - if (WUPSConfigCategory_AddItem(cat, item->handle) < 0) { - WUPSConfigItem_Destroy(item->handle); + if (WUPSConfigAPI_Category_AddItem(cat, item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigAPI_Item_Destroy(item->handle); return false; } return true; diff --git a/libraries/libwups/WUPSConfigItemMultipleValues.cpp b/libraries/libwups/WUPSConfigItemMultipleValues.cpp index a1dc804..0683928 100644 --- a/libraries/libwups/WUPSConfigItemMultipleValues.cpp +++ b/libraries/libwups/WUPSConfigItemMultipleValues.cpp @@ -4,8 +4,6 @@ #include #include -void WUPSConfigItemMultipleValues_onDelete(void *context); - int32_t WUPSConfigItemMultipleValues_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) { auto *item = (ConfigItemMultipleValues *) context; @@ -72,6 +70,27 @@ void WUPSConfigItemMultipleValues_restoreDefault(void *context) { void WUPSConfigItemMultipleValues_onSelected(void *context, bool isSelected) { } +static void WUPSConfigItemMultipleValues_Cleanup(ConfigItemMultipleValues *item) { + if (!item) { + return; + } + + for (int i = 0; i < item->valueCount; ++i) { + free(item->values[i].valueName); + } + + free(item->configId); + free(item->values); + + free(item); +} + +void WUPSConfigItemMultipleValues_onDelete(void *context) { + auto *item = (ConfigItemMultipleValues *) context; + + WUPSConfigItemMultipleValues_Cleanup(item); +} + extern "C" bool WUPSConfigItemMultipleValues_AddToCategory(WUPSConfigCategoryHandle cat, const char *configId, const char *displayName, int32_t defaultValueIndex, ConfigItemMultipleValuesPair *possibleValues, @@ -92,9 +111,7 @@ WUPSConfigItemMultipleValues_AddToCategory(WUPSConfigCategoryHandle cat, const c values[i].valueName = nullptr; continue; } - auto bufLen = strlen(possibleValues[i].valueName) + 1; - values[i].valueName = (char *) malloc(bufLen); - strncpy(values[i].valueName, possibleValues[i].valueName, bufLen); + values[i].valueName = strdup(possibleValues[i].valueName); } item->valueCount = pairCount; @@ -109,7 +126,7 @@ WUPSConfigItemMultipleValues_AddToCategory(WUPSConfigCategoryHandle cat, const c item->configId = nullptr; } - WUPSConfigCallbacks_t callbacks = { + WUPSConfigAPIItemCallbacksV1 callbacks = { .getCurrentValueDisplay = &WUPSConfigItemMultipleValues_getCurrentValueDisplay, .getCurrentValueSelectedDisplay = &WUPSConfigItemMultipleValues_getCurrentValueSelectedDisplay, .onSelected = &WUPSConfigItemMultipleValues_onSelected, @@ -119,27 +136,20 @@ WUPSConfigItemMultipleValues_AddToCategory(WUPSConfigCategoryHandle cat, const c .onButtonPressed = &WUPSConfigItemMultipleValues_onButtonPressed, .onDelete = &WUPSConfigItemMultipleValues_onDelete}; - if (WUPSConfigItem_Create(&item->handle, configId, displayName, callbacks, item) < 0) { - free(item); + WUPSConfigAPIItemOptionsV1 options = { + .displayName = displayName, + .context = item, + .callbacks = callbacks, + }; + + if (WUPSConfigAPI_Item_Create(options, &item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigItemMultipleValues_Cleanup(item); return false; } - if (WUPSConfigCategory_AddItem(cat, item->handle) < 0) { - WUPSConfigItem_Destroy(item->handle); + if (WUPSConfigAPI_Category_AddItem(cat, item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigAPI_Item_Destroy(item->handle); return false; } return true; -} - -void WUPSConfigItemMultipleValues_onDelete(void *context) { - auto *item = (ConfigItemMultipleValues *) context; - - for (int i = 0; i < item->valueCount; ++i) { - free(item->values[i].valueName); - } - - free(item->configId); - free(item->values); - - free(item); } \ No newline at end of file diff --git a/libraries/libwups/WUPSConfigItemStub.cpp b/libraries/libwups/WUPSConfigItemStub.cpp index 1824f0f..cef399e 100644 --- a/libraries/libwups/WUPSConfigItemStub.cpp +++ b/libraries/libwups/WUPSConfigItemStub.cpp @@ -4,8 +4,6 @@ #include #include -void WUPSConfigItemStub_onDelete(void *context); - int32_t WUPSConfigItemStub_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) { memset(out_buf, 0, out_size); return 0; @@ -33,6 +31,15 @@ void WUPSConfigItemStub_restoreDefault(void *context) { void WUPSConfigItemStub_onSelected(void *context, bool isSelected) { } +static void WUPSConfigItemStub_Cleanup(ConfigItemStub *item) { + free(item); +} + +void WUPSConfigItemStub_onDelete(void *context) { + WUPSConfigItemStub_Cleanup((ConfigItemStub *) context); +} + + extern "C" bool WUPSConfigItemStub_AddToCategoryEx(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName) { if (cat == 0) { @@ -44,7 +51,7 @@ WUPSConfigItemStub_AddToCategoryEx(WUPSConfigCategoryHandle cat, const char *con return false; } - WUPSConfigCallbacks_t callbacks = { + WUPSConfigAPIItemCallbacksV1 callbacks = { .getCurrentValueDisplay = &WUPSConfigItemStub_getCurrentValueDisplay, .getCurrentValueSelectedDisplay = &WUPSConfigItemStub_getCurrentValueSelectedDisplay, .onSelected = &WUPSConfigItemStub_onSelected, @@ -54,23 +61,24 @@ WUPSConfigItemStub_AddToCategoryEx(WUPSConfigCategoryHandle cat, const char *con .onButtonPressed = &WUPSConfigItemStub_onButtonPressed, .onDelete = &WUPSConfigItemStub_onDelete}; - if (WUPSConfigItem_Create(&item->handle, configID, displayName, callbacks, item) < 0) { - free(item); + WUPSConfigAPIItemOptionsV1 options = { + .displayName = displayName, + .context = item, + .callbacks = callbacks, + }; + + if (WUPSConfigAPI_Item_Create(options, &item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigItemStub_Cleanup(item); return false; } - if (WUPSConfigCategory_AddItem(cat, item->handle) < 0) { - WUPSConfigItem_Destroy(item->handle); + if (WUPSConfigAPI_Category_AddItem(cat, item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigAPI_Item_Destroy(item->handle); return false; } return true; } -void WUPSConfigItemStub_onDelete(void *context) { - auto *item = (ConfigItemStub *) context; - free(item); -} - extern "C" bool WUPSConfigItemStub_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName) { return WUPSConfigItemStub_AddToCategoryEx(cat, configID, displayName); } diff --git a/libraries/libwups/config.def b/libraries/libwups/config.def deleted file mode 100644 index eb31b2d..0000000 --- a/libraries/libwups/config.def +++ /dev/null @@ -1,20 +0,0 @@ -:NAME homebrew_wupsbackend - -:TEXT -WUPSConfigItem_Create -WUPSConfigItem_Destroy -WUPSConfigItem_SetDisplayName -WUPSConfigItem_GetDisplayName -WUPSConfigItem_SetConfigID -WUPSConfigItem_GetConfigID - -WUPSConfig_Create -WUPSConfig_Destroy -WUPSConfig_GetName -WUPSConfig_AddCategoryByName -WUPSConfig_AddCategory - -WUPSConfigCategory_Create -WUPSConfigCategory_Destroy -WUPSConfigCategory_GetName -WUPSConfigCategory_AddItem \ No newline at end of file diff --git a/libraries/libwups/config_api.cpp b/libraries/libwups/config_api.cpp new file mode 100644 index 0000000..d5c5c25 --- /dev/null +++ b/libraries/libwups/config_api.cpp @@ -0,0 +1,245 @@ +#include "wups/config_api.h" +#include "wups.h" +#include +#include + +static OSDynLoad_Module sModuleHandle = nullptr; + +static WUPSConfigAPIStatus (*sAPIGetVersion)(WUPSConfigAPIVersion *out) = nullptr; +static WUPSConfigAPIStatus (*sAPIInitEx)(uint32_t pluginIdentifier, WUPSConfigAPIOptions options, WUPSConfigAPI_MenuOpenedCallback openedCallback, WUPSConfigAPI_MenuClosedCallback closedCallback) = nullptr; +static WUPSConfigAPIStatus (*sAPICategoryCreateEx)(WUPSConfigAPICreateCategoryOptions options, WUPSConfigCategoryHandle *out) = nullptr; +static WUPSConfigAPIStatus (*sAPICategoryDestroy)(WUPSConfigCategoryHandle handle) = nullptr; +static WUPSConfigAPIStatus (*sAPICategoryAddCategory)(WUPSConfigCategoryHandle parentHandle, WUPSConfigCategoryHandle categoryHandle) = nullptr; +static WUPSConfigAPIStatus (*sAPICategoryAddItem)(WUPSConfigCategoryHandle parentHandle, WUPSConfigItemHandle itemHandle) = nullptr; +static WUPSConfigAPIStatus (*sAPIItemCreateEx)(WUPSConfigAPICreateItemOptions options, WUPSConfigItemHandle *out) = nullptr; +static WUPSConfigAPIStatus (*sAPIItemDestroy)(WUPSConfigItemHandle handle) = nullptr; + +static WUPSConfigAPIVersion sConfigAPIVersion = WUPS_CONFIG_API_VERSION_ERROR; + +static bool sConfigLibInitDone = false; +static uint32_t sConfigPluginIdentifier = 0xFFFFFFFF; + +const char *WUPSConfigAPI_GetStatusStr(WUPSConfigAPIStatus status) { + switch (status) { + case WUPSCONFIG_API_RESULT_SUCCESS: + return "WUPSCONFIG_API_RESULT_SUCCESS"; + case WUPSCONFIG_API_RESULT_INVALID_ARGUMENT: + return "WUPSCONFIG_API_RESULT_INVALID_ARGUMENT"; + case WUPSCONFIG_API_RESULT_OUT_OF_MEMORY: + return "WUPSCONFIG_API_RESULT_OUT_OF_MEMORY"; + case WUPSCONFIG_API_RESULT_NOT_FOUND: + return "WUPSCONFIG_API_RESULT_NOT_FOUND"; + case WUPSCONFIG_API_RESULT_MODULE_NOT_FOUND: + return "WUPSCONFIG_API_RESULT_MODULE_NOT_FOUND"; + case WUPSCONFIG_API_RESULT_INVALID_PLUGIN_IDENTIFIER: + return "WUPSCONFIG_API_RESULT_INVALID_PLUGIN_IDENTIFIER"; + case WUPSCONFIG_API_RESULT_MODULE_MISSING_EXPORT: + return "WUPSCONFIG_API_RESULT_MODULE_MISSING_EXPORT"; + case WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION: + return "WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION"; + case WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND: + return "WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND"; + case WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED: + return "WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED"; + case WUPSCONFIG_API_RESULT_UNKNOWN_ERROR: + return "WUPSCONFIG_API_RESULT_UNKNOWN_ERROR"; + case WUPSCONFIG_API_RESULT_MISSING_CALLBACK: + return "WUPSCONFIG_API_RESULT_MISSING_CALLBACK"; + } + return "WUPSCONFIG_API_RESULT_UNKNOWN_ERROR"; +} + +extern "C" WUPSConfigAPIStatus WUPSConfigAPI_InitLibrary_Internal(wups_loader_init_config_args_t args) { + if (sConfigLibInitDone) { + return WUPSCONFIG_API_RESULT_SUCCESS; + } + if (args.arg_version != 1) { + return WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION; + } + + if (OSDynLoad_Acquire("homebrew_wupsbackend", &sModuleHandle) != OS_DYNLOAD_OK) { + WUPS_DEBUG_REPORT("libuwps: OSDynLoad_Acquire \"homebrew_wupsbackend\" failed.\n"); + return WUPSCONFIG_API_RESULT_MODULE_NOT_FOUND; + } + + if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "WUPSConfigAPI_GetVersion", (void **) &sAPIGetVersion) != OS_DYNLOAD_OK) { + WUPS_DEBUG_REPORT("libuwps: FindExport WUPSConfigAPI_GetVersion failed.\n"); + return WUPSCONFIG_API_RESULT_MODULE_MISSING_EXPORT; + } + auto res = WUPSConfigAPI_GetVersion(&sConfigAPIVersion); + if (res != WUPSCONFIG_API_RESULT_SUCCESS) { + return WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION; + } + + if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "WUPSConfigAPI_InitEx", (void **) &sAPIInitEx) != OS_DYNLOAD_OK) { + WUPS_DEBUG_REPORT("libwups: FindExport WUPSConfigAPI_InitEx failed.\n"); + return WUPSCONFIG_API_RESULT_MODULE_MISSING_EXPORT; + } + if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "WUPSConfigAPI_Category_CreateEx", (void **) &sAPICategoryCreateEx) != OS_DYNLOAD_OK) { + WUPS_DEBUG_REPORT("libwups: FindExport WUPSConfigAPI_Category_CreateEx failed.\n"); + return WUPSCONFIG_API_RESULT_MODULE_MISSING_EXPORT; + } + + if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "WUPSConfigAPI_Category_Destroy", (void **) &sAPICategoryDestroy) != OS_DYNLOAD_OK) { + WUPS_DEBUG_REPORT("libwups: FindExport WUPSConfigAPI_Category_Destroy failed.\n"); + return WUPSCONFIG_API_RESULT_MODULE_MISSING_EXPORT; + } + if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "WUPSConfigAPI_Category_AddCategory", (void **) &sAPICategoryAddCategory) != OS_DYNLOAD_OK) { + WUPS_DEBUG_REPORT("libwups: FindExport WUPSConfigAPI_Category_AddCategory failed.\n"); + return WUPSCONFIG_API_RESULT_MODULE_MISSING_EXPORT; + } + if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "WUPSConfigAPI_Category_AddItem", (void **) &sAPICategoryAddItem) != OS_DYNLOAD_OK) { + WUPS_DEBUG_REPORT("libwups: FindExport WUPSConfigAPI_Category_AddItem failed.\n"); + return WUPSCONFIG_API_RESULT_MODULE_MISSING_EXPORT; + } + + if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "WUPSConfigAPI_Item_CreateEx", (void **) &sAPIItemCreateEx) != OS_DYNLOAD_OK) { + WUPS_DEBUG_REPORT("libwups: FindExport WUPSConfigAPI_Item_Create failed.\n"); + return WUPSCONFIG_API_RESULT_MODULE_MISSING_EXPORT; + } + if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "WUPSConfigAPI_Item_Destroy", (void **) &sAPIItemDestroy) != OS_DYNLOAD_OK) { + WUPS_DEBUG_REPORT("libwups: FindExport WUPSConfigAPI_Item_Destroy failed.\n"); + return WUPSCONFIG_API_RESULT_MODULE_MISSING_EXPORT; + } + + sConfigLibInitDone = true; + sConfigPluginIdentifier = args.plugin_identifier; + + return WUPSCONFIG_API_RESULT_SUCCESS; +} + +extern "C" WUPSConfigAPIStatus WUPSConfigAPI_DeInitLibrary_Internal() { + return WUPSCONFIG_API_RESULT_SUCCESS; +} + +WUPSConfigAPIStatus WUPSConfigAPI_GetVersion(WUPSConfigAPIVersion *outVariable) { + if (sAPIGetVersion == nullptr) { + if (OSDynLoad_Acquire("homebrew_notifications", &sModuleHandle) != OS_DYNLOAD_OK) { + WUPS_DEBUG_REPORT("libwups: OSDynLoad_Acquire failed.\n"); + return WUPSCONFIG_API_RESULT_MODULE_NOT_FOUND; + } + + if (OSDynLoad_FindExport(sModuleHandle, OS_DYNLOAD_EXPORT_FUNC, "WUPSConfigAPI_GetVersion", (void **) &sAPIGetVersion) != OS_DYNLOAD_OK) { + WUPS_DEBUG_REPORT("libwups: FindExport WUPSConfigAPI_GetVersion failed.\n"); + return WUPSCONFIG_API_RESULT_MODULE_MISSING_EXPORT; + } + } + + return sAPIGetVersion(outVariable); +} + +WUPSConfigAPIStatus WUPSConfigAPI_InitEx(uint32_t pluginIdentifier, WUPSConfigAPIOptions options, WUPSConfigAPI_MenuOpenedCallback openedCallback, WUPSConfigAPI_MenuClosedCallback closedCallback) { + if (sConfigAPIVersion == WUPS_CONFIG_API_VERSION_ERROR) { + return WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED; + } + if (sAPIInitEx == nullptr || sConfigAPIVersion < 1) { + return WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND; + } + + if (openedCallback == nullptr || closedCallback == nullptr || options.version != 1) { + return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; + } + + return sAPIInitEx(pluginIdentifier, options, openedCallback, closedCallback); +} + +WUPSConfigAPIStatus WUPSConfigAPI_Init(WUPSConfigAPIOptionsV1 optionsV1, WUPSConfigAPI_MenuOpenedCallback openedCallback, WUPSConfigAPI_MenuClosedCallback closedCallback) { + if (sConfigPluginIdentifier == 0xFFFFFFFF) { + return WUPSCONFIG_API_RESULT_INVALID_PLUGIN_IDENTIFIER; + } + WUPSConfigAPIOptions options = { + .version = WUPS_API_CONFIG_API_OPTION_VERSION_V1, + .data = {.v1 = optionsV1}, + }; + return WUPSConfigAPI_InitEx(sConfigPluginIdentifier, options, openedCallback, closedCallback); +} + +WUPSConfigAPIStatus WUPSConfigAPI_Category_CreateEx(WUPSConfigAPICreateCategoryOptions options, WUPSConfigCategoryHandle *out) { + if (sConfigAPIVersion == WUPS_CONFIG_API_VERSION_ERROR) { + return WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED; + } + if (sAPICategoryCreateEx == nullptr || sConfigAPIVersion < 1) { + return WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND; + } + + if (out == nullptr) { + return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; + } + + return sAPICategoryCreateEx(options, out); +} + +WUPSConfigAPIStatus WUPSConfigAPI_Category_Destroy(WUPSConfigCategoryHandle handle) { + if (sConfigAPIVersion == WUPS_CONFIG_API_VERSION_ERROR) { + return WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED; + } + if (sAPICategoryDestroy == nullptr || sConfigAPIVersion < 1) { + return WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND; + } + + if (handle == nullptr) { + return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; + } + + return sAPICategoryDestroy(handle); +} + +WUPSConfigAPIStatus WUPSConfigAPI_Category_AddCategory(WUPSConfigCategoryHandle parentHandle, WUPSConfigCategoryHandle categoryHandle) { + if (sConfigAPIVersion == WUPS_CONFIG_API_VERSION_ERROR) { + return WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED; + } + if (sAPICategoryAddCategory == nullptr || sConfigAPIVersion < 1) { + return WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND; + } + + if (parentHandle == nullptr || categoryHandle == nullptr) { + return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; + } + + return sAPICategoryAddCategory(parentHandle, categoryHandle); +} + +WUPSConfigAPIStatus WUPSConfigAPI_Category_AddItem(WUPSConfigCategoryHandle parentHandle, WUPSConfigItemHandle itemHandle) { + if (sConfigAPIVersion == WUPS_CONFIG_API_VERSION_ERROR) { + return WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED; + } + if (sAPICategoryAddItem == nullptr || sConfigAPIVersion < 1) { + return WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND; + } + + if (parentHandle == 0 || itemHandle == 0) { + return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; + } + + return sAPICategoryAddItem(parentHandle, itemHandle); +} + +WUPSConfigAPIStatus WUPSConfigAPI_Item_CreateEx(WUPSConfigAPICreateItemOptions options, WUPSConfigItemHandle *out) { + if (sConfigAPIVersion == WUPS_CONFIG_API_VERSION_ERROR) { + return WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED; + } + if (sAPIItemCreateEx == nullptr || sConfigAPIVersion < 1) { + return WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND; + } + + if (out == nullptr) { + return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; + } + + return sAPIItemCreateEx(options, out); +} + +WUPSConfigAPIStatus WUPSConfigAPI_Item_Destroy(WUPSConfigItemHandle handle) { + if (sConfigAPIVersion == WUPS_CONFIG_API_VERSION_ERROR) { + return WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED; + } + if (sAPIItemDestroy == nullptr || sConfigAPIVersion < 1) { + return WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND; + } + + if (handle == nullptr) { + return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; + } + + return sAPIItemDestroy(handle); +} \ No newline at end of file diff --git a/libraries/libwups/storage.cpp b/libraries/libwups/storage.cpp index bb8d547..bd5c2de 100644 --- a/libraries/libwups/storage.cpp +++ b/libraries/libwups/storage.cpp @@ -1,6 +1,5 @@ -#include #include -#include +#include struct wups_internal_functions_t { OpenStorageFunction openfunction_ptr = nullptr; @@ -18,7 +17,7 @@ struct wups_internal_functions_t { static wups_internal_functions_t __internal_functions __attribute__((section(".data"))) = {}; WUPSStorageError WUPS_InitStorage(wups_loader_init_storage_args_t args) { - if (args.version != WUPS_STORAGE_CUR_API_VERSION) { + if (args.version > WUPS_STORAGE_CUR_API_VERSION) { __internal_functions = {}; return WUPS_STORAGE_ERROR_INVALID_VERSION; } diff --git a/plugins/example_plugin/Makefile b/plugins/example_plugin/Makefile index 565db8d..c84c3ef 100644 --- a/plugins/example_plugin/Makefile +++ b/plugins/example_plugin/Makefile @@ -96,7 +96,7 @@ export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) all: $(BUILD) $(BUILD): - @[ -d $@ ] || mkdir -p $@ + @$(shell [ ! -d $(BUILD) ] && mkdir -p $(BUILD)) @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile #------------------------------------------------------------------------------- diff --git a/plugins/example_plugin/src/main.cpp b/plugins/example_plugin/src/main.c similarity index 52% rename from plugins/example_plugin/src/main.cpp rename to plugins/example_plugin/src/main.c index 62c7c12..2a62259 100644 --- a/plugins/example_plugin/src/main.cpp +++ b/plugins/example_plugin/src/main.c @@ -1,9 +1,10 @@ #include "utils/logger.h" #include #include -#include +#include #include #include +#include /** Mandatory plugin information. @@ -28,6 +29,113 @@ WUPS_USE_STORAGE("example_plugin"); // Unique id for the storage api bool logFSOpen = true; +/** + * Callback that will be called if the config has been changed + */ +void logFSOpenChanged(ConfigItemBoolean *item, bool newValue) { + DEBUG_FUNCTION_LINE_INFO("New value in logFSOpenChanged: %d", newValue); + logFSOpen = newValue; + // If the value has changed, we store it in the storage. + WUPS_StoreInt(NULL, LOG_FS_OPEN_CONFIG_ID, logFSOpen); +} + +WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle root) { + // We open the storage, so we can persist the configuration the user did. + if (WUPS_OpenStorage() != WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE("Failed to open storage"); + return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; + } + + { + // Let's create a new category called "Settings" + WUPSConfigCategoryHandle settingsCategory; + WUPSConfigAPICreateCategoryOptionsV1 settingsCategoryOptions = {.name = "Settings"}; + if (WUPSConfigAPI_Category_Create(settingsCategoryOptions, &settingsCategory) != WUPSCONFIG_API_RESULT_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("Failed to create settings category"); + return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; + } + + // Add a new item to this settings category + if (!WUPSConfigItemBoolean_AddToCategory(settingsCategory, LOG_FS_OPEN_CONFIG_ID, "Log FSOpen calls", logFSOpen, &logFSOpenChanged)) { + DEBUG_FUNCTION_LINE_ERR("Failed to add item to category"); + return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; + } + + // Add the category to the root. + if (WUPSConfigAPI_Category_AddCategory(root, settingsCategory) != WUPSCONFIG_API_RESULT_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("Failed to add category to root item"); + } + } + + { + // We can also have categories inside categories! + WUPSConfigCategoryHandle categoryLevel1; + WUPSConfigAPICreateCategoryOptionsV1 catLev1Options = {.name = "Category with subcategory"}; + if (WUPSConfigAPI_Category_Create(catLev1Options, &categoryLevel1) != WUPSCONFIG_API_RESULT_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("Failed to create categoryLevel1"); + return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; + } + WUPSConfigCategoryHandle categoryLevel2; + WUPSConfigAPICreateCategoryOptionsV1 catLev2Options = {.name = "Category inside category"}; + if (WUPSConfigAPI_Category_Create(catLev2Options, &categoryLevel2) != WUPSCONFIG_API_RESULT_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("Failed to create categoryLevel1"); + return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; + } + if (!WUPSConfigItemBoolean_AddToCategory(categoryLevel2, "stubInsideCategory", "This is stub item inside a nested category", false, NULL)) { + DEBUG_FUNCTION_LINE_ERR("Failed to add stub item to root category"); + return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; + } + + // add categoryLevel2 to categoryLevel1 + if (WUPSConfigAPI_Category_AddCategory(categoryLevel1, categoryLevel2) != WUPSCONFIG_API_RESULT_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("Failed to add category to root item"); + return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; + } + + // add categoryLevel2 to categoryLevel1 + if (WUPSConfigAPI_Category_AddCategory(root, categoryLevel1) != WUPSCONFIG_API_RESULT_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("Failed to add category to root item"); + return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; + } + } + + { + // We can also directly add items to the root category + if (!WUPSConfigItemBoolean_AddToCategory(root, "stub0", "This is stub item without category", false, NULL)) { + DEBUG_FUNCTION_LINE_ERR("Failed to add stub item to root category"); + return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; + } + ConfigItemMultipleValuesPair values[10]; + int numOfElements = sizeof(values) / sizeof(values[0]); + for (int i = 0; i < numOfElements; i++) { +#define STR_SIZE 10 + char *str = (char *) malloc(STR_SIZE); + if (!str) { + OSFatal("Failed to allocate memory"); + } + snprintf(str, STR_SIZE, "%d", i); + values[i].value = i; + values[i].valueName = str; + } + bool multValuesRes = WUPSConfigItemMultipleValues_AddToCategory(root, "multival", "Multiple values", 0, values, numOfElements, NULL); + for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) { + free(values[i].valueName); + } + if (!multValuesRes) { + return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; + } + } + + return WUPSCONFIG_API_CALLBACK_RESULT_SUCCESS; +} + +void ConfigMenuClosedCallback() { + // Save all changes + if (WUPS_CloseStorage() != WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("Failed to close storage"); + } +} + /** Gets called ONCE when the plugin was loaded. **/ @@ -36,15 +144,20 @@ INITIALIZE_PLUGIN() { initLogging(); DEBUG_FUNCTION_LINE("INITIALIZE_PLUGIN of example_plugin!"); + WUPSConfigAPIOptionsV1 configOptions = {.name = "example_plugin"}; + if (WUPSConfigAPI_Init(configOptions, ConfigMenuOpenedCallback, ConfigMenuClosedCallback) != WUPSCONFIG_API_RESULT_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("Failed to init config api"); + } + // Open storage to read values WUPSStorageError storageRes = WUPS_OpenStorage(); if (storageRes != WUPS_STORAGE_ERROR_SUCCESS) { DEBUG_FUNCTION_LINE("Failed to open storage %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes); } else { // Try to get value from storage - if ((storageRes = WUPS_GetBool(nullptr, LOG_FS_OPEN_CONFIG_ID, &logFSOpen)) == WUPS_STORAGE_ERROR_NOT_FOUND) { + if ((storageRes = WUPS_GetBool(NULL, LOG_FS_OPEN_CONFIG_ID, &logFSOpen)) == WUPS_STORAGE_ERROR_NOT_FOUND) { // Add the value to the storage if it's missing. - if (WUPS_StoreBool(nullptr, LOG_FS_OPEN_CONFIG_ID, logFSOpen) != WUPS_STORAGE_ERROR_SUCCESS) { + if (WUPS_StoreBool(NULL, LOG_FS_OPEN_CONFIG_ID, logFSOpen) != WUPS_STORAGE_ERROR_SUCCESS) { DEBUG_FUNCTION_LINE("Failed to store bool"); } } else if (storageRes != WUPS_STORAGE_ERROR_SUCCESS) { @@ -89,41 +202,6 @@ ON_APPLICATION_REQUESTS_EXIT() { DEBUG_FUNCTION_LINE_INFO("ON_APPLICATION_REQUESTS_EXIT of example_plugin!"); } -/** - * Callback that will be called if the config has been changed - */ -void logFSOpenChanged(ConfigItemBoolean *item, bool newValue) { - DEBUG_FUNCTION_LINE_INFO("New value in logFSOpenChanged: %d", newValue); - logFSOpen = newValue; - // If the value has changed, we store it in the storage. - WUPS_StoreInt(nullptr, LOG_FS_OPEN_CONFIG_ID, logFSOpen); -} - -WUPS_GET_CONFIG() { - // We open the storage, so we can persist the configuration the user did. - if (WUPS_OpenStorage() != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE("Failed to open storage"); - return 0; - } - - WUPSConfigHandle config; - WUPSConfig_CreateHandled(&config, "Example Plugin"); - - WUPSConfigCategoryHandle cat; - WUPSConfig_AddCategoryByNameHandled(config, "Logging", &cat); - - WUPSConfigItemBoolean_AddToCategoryHandled(config, cat, LOG_FS_OPEN_CONFIG_ID, "Log FSOpen calls", logFSOpen, &logFSOpenChanged); - - return config; -} - -WUPS_CONFIG_CLOSED() { - // Save all changes - if (WUPS_CloseStorage() != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE_ERR("Failed to close storage"); - } -} - /** This defines a function replacement. It allows to replace the system function with an own function.