diff --git a/Makefile b/Makefile index a47f768..7f694c6 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,8 @@ TOPDIR ?= $(CURDIR) include $(TOPDIR)/share/wups_rules export WUPS_MAJOR := 0 -export WUPS_MINOR := 7 -export WUPS_PATCH := 2 +export WUPS_MINOR := 8 +export WUPS_PATCH := 0 VERSION := $(WUPS_MAJOR).$(WUPS_MINOR).$(WUPS_PATCH) @@ -23,15 +23,14 @@ INCLUDES := include #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -CFLAGS := -g -Wall -Werror -save-temps \ +CFLAGS := -g -O2 -Wall -Werror -save-temps \ -ffunction-sections -fdata-sections \ - -fno-exceptions -fno-rtti \ $(MACHDEP) \ $(BUILD_CFLAGS) CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ -D__WUPS__ -CXXFLAGS := $(CFLAGS) -std=gnu++20 +CXXFLAGS := $(CFLAGS) -std=c++20 ASFLAGS := -g $(MACHDEP) diff --git a/include/wups.h b/include/wups.h index 6e7f493..a3d968a 100644 --- a/include/wups.h +++ b/include/wups.h @@ -32,12 +32,4 @@ #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 +#include "wups/wups_debug.h" diff --git a/include/wups/config.h b/include/wups/config.h index 9491d36..d7e6a85 100644 --- a/include/wups/config.h +++ b/include/wups/config.h @@ -17,26 +17,54 @@ #pragma once +#include #include +#include -#define WUPS_CONFIG_BUTTON_NONE 0 -#define WUPS_CONFIG_BUTTON_LEFT (1 << 0) -#define WUPS_CONFIG_BUTTON_RIGHT (1 << 1) -#define WUPS_CONFIG_BUTTON_UP (1 << 2) -#define WUPS_CONFIG_BUTTON_DOWN (1 << 3) -#define WUPS_CONFIG_BUTTON_A (1 << 4) -#define WUPS_CONFIG_BUTTON_B (1 << 5) -#define WUPS_CONFIG_BUTTON_ZL (1 << 6) -#define WUPS_CONFIG_BUTTON_ZR (1 << 7) -#define WUPS_CONFIG_BUTTON_L (1 << 8) -#define WUPS_CONFIG_BUTTON_R (1 << 9) -#define WUPS_CONFIG_BUTTON_X (1 << 10) -#define WUPS_CONFIG_BUTTON_Y (1 << 11) -#define WUPS_CONFIG_BUTTON_STICK_L (1 << 12) -#define WUPS_CONFIG_BUTTON_STICK_R (1 << 13) -#define WUPS_CONFIG_BUTTON_PLUS (1 << 14) -#define WUPS_CONFIG_BUTTON_MINUS (1 << 15) -typedef int32_t WUPSConfigButtons; +typedef uint32_t WUPSConfigButtons; + +typedef enum WUPS_CONFIG_SIMPLE_INPUT { + WUPS_CONFIG_BUTTON_NONE = 0, + WUPS_CONFIG_BUTTON_LEFT = (1 << 0), + WUPS_CONFIG_BUTTON_RIGHT = (1 << 1), + WUPS_CONFIG_BUTTON_UP = (1 << 2), + WUPS_CONFIG_BUTTON_DOWN = (1 << 3), + WUPS_CONFIG_BUTTON_A = (1 << 4), + WUPS_CONFIG_BUTTON_B = (1 << 5), + WUPS_CONFIG_BUTTON_ZL = (1 << 6), + WUPS_CONFIG_BUTTON_ZR = (1 << 7), + WUPS_CONFIG_BUTTON_L = (1 << 8), + WUPS_CONFIG_BUTTON_R = (1 << 9), + WUPS_CONFIG_BUTTON_X = (1 << 10), + WUPS_CONFIG_BUTTON_Y = (1 << 11), + WUPS_CONFIG_BUTTON_STICK_L = (1 << 12), + WUPS_CONFIG_BUTTON_STICK_R = (1 << 13), + WUPS_CONFIG_BUTTON_PLUS = (1 << 14), + WUPS_CONFIG_BUTTON_MINUS = (1 << 15), +} WUPS_CONFIG_SIMPLE_INPUT; + +typedef struct { + WUPS_CONFIG_SIMPLE_INPUT buttons_h; + WUPS_CONFIG_SIMPLE_INPUT buttons_d; + WUPS_CONFIG_SIMPLE_INPUT buttons_r; + bool validPointer; + bool touched; + float pointerAngle; + int32_t x; + int32_t y; +} WUPSConfigSimplePadData; + +typedef struct { + struct { + VPADReadError vpadError; + VPADTouchData tpCalib; + VPADStatus data; + } vpad; + struct { + KPADError kpadError[4]; + KPADStatus data[4]; + } kpad; +} WUPSConfigComplexPadData; typedef enum WUPSConfigAPIStatus { WUPSCONFIG_API_RESULT_SUCCESS = 0, @@ -76,17 +104,111 @@ typedef struct { void (*onDelete)(void *context); } WUPSConfigAPIItemCallbacksV1; +typedef struct { + /** + * Set the string which is displayed for an item + * @param context The context which has been passed to the item during creating + * @param out_buf Buffer where the string should be written to + * @param out_size Size of out_buf + * + * \result non-zero result indicates an error. + */ + int32_t (*getCurrentValueDisplay)(void *context, char *out_buf, int32_t out_size); + + /** + * Set the string which is displayed for an item when the cursor is on is item + * @param context The context which has been passed to the item during creating + * @param out_buf Buffer where the string should be written to + * @param out_size Size of out_buf + * + * \result non-zero result indicates an error. + */ + int32_t (*getCurrentValueSelectedDisplay)(void *context, char *out_buf, int32_t out_size); + + /** + * Called when the cursor enters or leaves this item + * @param context The context which has been passed to the item during creating + * @param isSelected True if the item cursor is now pointing to this item, \n + * False if it's not pointing to this item anymore + */ + void (*onSelected)(void *context, bool isSelected); + + /** + * Called when the current value of this item should be set to the default value + * @param context The context which has been passed to the item during creating + */ + void (*restoreDefault)(void *context); + + /** + * Determines if movement to different item is allowed. + * @param context The context which has been passed to the item during creating + * \return True if it should be not possible to select a different item or exit the current category \n + * False if it should be possible to select a different item or exit the current category + */ + bool (*isMovementAllowed)(void *context); + + /** + * Called when the config menu has been closed + * @param context The context which has been passed to the item during creating + */ + void (*onCloseCallback)(void *context); + + /** + * This function is called on each frame and provides information about the current inputs. + * The inputs are simplified and all 5 possible controller inputs (from Gamepad and up to 4 Wiimotes/Pro Controller) + * are unified in this single unified struct. + * + * @param context The context which has been passed to the item during creating + * @param input Simplified version of the current inputs + * + * \note To get the full input for all possible controllers see "onInputEx" + * + * @see onInputEx + */ + void (*onInput)(void *context, WUPSConfigSimplePadData input); + + /** + * This function is called on each frame and provides information about the current inputs. + * The structs contains information for current individual Gampepad and Wiimote/Pro Contoller inputs. + * + * @param context The context which has been passed to the item during creating + * @param input current input for all possibles controller + * + * \note To get a simplified input callback that combines all controller into a single struct see "onInput" + * + * @see onInput + */ + void (*onInputEx)(void *context, WUPSConfigComplexPadData input); + + /** + * This function is called when the item is about to be deleted. It can be used to free any alloated memory. + * + * @param context The context which has been passed to the item during creating + */ + void (*onDelete)(void *context); +} WUPSConfigAPIItemCallbacksV2; + #define WUPS_API_ITEM_OPTION_VERSION_V1 1 +#define WUPS_API_ITEM_OPTION_VERSION_V2 2 + typedef struct WUPSConfigAPIItemOptionsV1 { + const char *configId; const char *displayName; void *context; WUPSConfigAPIItemCallbacksV1 callbacks; } WUPSConfigAPIItemOptionsV1; +typedef struct WUPSConfigAPIItemOptionsV2 { + const char *displayName; + void *context; + WUPSConfigAPIItemCallbacksV2 callbacks; +} WUPSConfigAPIItemOptionsV2; + typedef struct WUPSConfigAPICreateItemOptions { uint32_t version; union { WUPSConfigAPIItemOptionsV1 v1; + WUPSConfigAPIItemOptionsV2 v2; } data; } WUPSConfigAPICreateItemOptions; diff --git a/include/wups/config/WUPSConfigCategory.h b/include/wups/config/WUPSConfigCategory.h new file mode 100644 index 0000000..22d3db1 --- /dev/null +++ b/include/wups/config/WUPSConfigCategory.h @@ -0,0 +1,51 @@ +#pragma once + +#ifdef __cplusplus + +#include "WUPSConfigItem.h" +#include +#include +#include + +class WUPSConfigCategory { +public: + explicit WUPSConfigCategory(WUPSConfigCategoryHandle handle) noexcept; + virtual ~WUPSConfigCategory(); + + WUPSConfigCategory(const WUPSConfigCategory &) = delete; + + WUPSConfigCategory(WUPSConfigCategory &&src) noexcept : mHandle(src.mHandle) { + src.mHandle = {}; + } + + WUPSConfigCategory &operator=(WUPSConfigCategory &&src) noexcept { + if (this != &src) { + src.mHandle = {}; + } + return *this; + } + + static std::optional Create(std::string_view name, WUPSConfigAPIStatus &error) noexcept; + + static WUPSConfigCategory Create(std::string_view name); + + bool add(WUPSConfigCategory &&cat, WUPSConfigAPIStatus &error) noexcept; + + void add(WUPSConfigCategory &&cat); + + bool add(WUPSConfigItem &&item, WUPSConfigAPIStatus &error) noexcept; + + void add(WUPSConfigItem &&item); + + [[nodiscard]] const WUPSConfigCategoryHandle &getHandle() const { + return mHandle; + } + + void release() { + mHandle = {}; + } + +private: + WUPSConfigCategoryHandle mHandle = {}; +}; +#endif \ No newline at end of file diff --git a/include/wups/config/WUPSConfigItem.h b/include/wups/config/WUPSConfigItem.h new file mode 100644 index 0000000..c51ba3d --- /dev/null +++ b/include/wups/config/WUPSConfigItem.h @@ -0,0 +1,41 @@ +#pragma once + +#ifdef __cplusplus + +#include "wups/config.h" +#include + +class WUPSConfigItem { +protected: + explicit WUPSConfigItem(WUPSConfigItemHandle itemHandle) : mHandle(itemHandle) { + } + +public: + virtual ~WUPSConfigItem(); + + WUPSConfigItem(const WUPSConfigItem &) = delete; + + WUPSConfigItem(WUPSConfigItem &&src) noexcept : mHandle(src.mHandle) { + src.mHandle = {}; + } + + WUPSConfigItem &operator=(WUPSConfigItem &&src) noexcept { + if (this != &src) { + src.mHandle = {}; + } + return *this; + } + + [[nodiscard]] const WUPSConfigItemHandle &getHandle() const { + return mHandle; + } + + void release() { + mHandle = {}; + } + +private: + WUPSConfigItemHandle mHandle = {}; +}; + +#endif diff --git a/include/wups/config/WUPSConfigItemBoolean.h b/include/wups/config/WUPSConfigItemBoolean.h index 877dd9d..942956a 100644 --- a/include/wups/config/WUPSConfigItemBoolean.h +++ b/include/wups/config/WUPSConfigItemBoolean.h @@ -1,25 +1,132 @@ -#include +#pragma once + +#include "WUPSConfigItem.h" +#include #ifdef __cplusplus extern "C" { #endif typedef struct ConfigItemBoolean { - char *configId; WUPSConfigItemHandle handle; + const char *identifier; bool defaultValue; + bool valueAtCreation; bool value; char trueValue[32]; char falseValue[32]; - void *callback; + void *valueChangedCallback; } ConfigItemBoolean; typedef void (*BooleanValueChangedCallback)(ConfigItemBoolean *, bool); -bool WUPSConfigItemBoolean_AddToCategory(WUPSConfigCategoryHandle cat, const char *configId, const char *displayName, bool defaultValue, BooleanValueChangedCallback callback); -bool WUPSConfigItemBoolean_AddToCategoryEx(WUPSConfigCategoryHandle cat, const char *configId, const char *displayName, bool defaultValue, BooleanValueChangedCallback callback, const char *trueValue, - const char *falseValue); +WUPSConfigAPIStatus +WUPSConfigItemBoolean_CreateEx(const char *identifier, + const char *displayName, + bool defaultValue, + bool currentValue, + BooleanValueChangedCallback callback, + const char *trueValue, + const char *falseValue, + WUPSConfigItemHandle *outHandle); + + +/** + * @brief Adds a boolean configuration item to the specified category. + * + * This function adds a boolean configuration item to the given category. The item is displayed with a specified display name. + * The default value and current value of the item are set to the provided values. A callback function is called whenever + * the value of the item changes. + * + * @param cat The handle of the category to add the item to. + * @param identifier Optional identifier for the item. Can be NULL. + * @param displayName The display name of the item. + * @param defaultValue The default value of the item. + * @param currentValue The current value of the item. + * @param callback A callback function that will be called when the config menu closes and the value of the item has been changed. + * @return True if the item was added successfully, false otherwise. + */ +WUPSConfigAPIStatus +WUPSConfigItemBoolean_AddToCategory(WUPSConfigCategoryHandle cat, + const char *identifier, + const char *displayName, + bool defaultValue, + bool currentValue, + BooleanValueChangedCallback callback); + +/** + * @brief Adds a boolean configuration item to the specified category. + * + * This function adds a boolean configuration item to the given category. The item is displayed with a specified display name. + * The default value and current value of the item are set to the provided values. A callback function is called whenever + * the value of the item changes. + * + * @param cat The handle of the category to add the item to. + * @param identifier Optional identifier for the item. Can be NULL. + * @param displayName The display name of the item. + * @param defaultValue The default value of the item. + * @param currentValue The current value of the item. + * @param callback A callback function that will be called when the config menu closes and the value of the item has been changed. + * @param trueValue The string representation of the true value. + * @param falseValue The string representation of the false value. + * @return True if the item was successfully added to the category, false otherwise. + */ +WUPSConfigAPIStatus +WUPSConfigItemBoolean_AddToCategoryEx(WUPSConfigCategoryHandle cat, + const char *identifier, + const char *displayName, + bool defaultValue, + bool currentValue, + BooleanValueChangedCallback callback, + const char *trueValue, + const char *falseValue); #ifdef __cplusplus } +#endif + +#ifdef __cplusplus + +#include "WUPSConfigItem.h" +#include +#include +#include +#include + +class WUPSConfigItemBoolean : public WUPSConfigItem { +public: + static std::optional CreateEx(std::optional identifier, + std::string_view displayName, + bool defaultValue, + bool currentValue, + BooleanValueChangedCallback callback, + std::string_view trueValue, + std::string_view falseValue, + WUPSConfigAPIStatus &err) noexcept; + + static WUPSConfigItemBoolean CreateEx(std::optional identifier, + std::string_view displayName, + bool defaultValue, + bool currentValue, + BooleanValueChangedCallback callback, + std::string_view trueValue, + std::string_view falseValue); + + static std::optional Create(std::optional identifier, + std::string_view displayName, + bool defaultValue, + bool currentValue, + BooleanValueChangedCallback callback, + WUPSConfigAPIStatus &err) noexcept; + + static WUPSConfigItemBoolean Create(std::optional identifier, + std::string_view displayName, + bool defaultValue, + bool currentValue, + BooleanValueChangedCallback callback); + +private: + explicit WUPSConfigItemBoolean(WUPSConfigItemHandle itemHandle) : WUPSConfigItem(itemHandle) { + } +}; #endif \ No newline at end of file diff --git a/include/wups/config/WUPSConfigItemIntegerRange.h b/include/wups/config/WUPSConfigItemIntegerRange.h index 1d610f3..51cced2 100644 --- a/include/wups/config/WUPSConfigItemIntegerRange.h +++ b/include/wups/config/WUPSConfigItemIntegerRange.h @@ -1,25 +1,92 @@ -#include +#pragma once + +#include #ifdef __cplusplus extern "C" { #endif typedef struct ConfigItemIntegerRange { - char *configId; WUPSConfigItemHandle handle; + const char *identifier; int defaultValue; int value; + int valueAtCreation; int minValue; int maxValue; - void *callback; + void *valueChangedCallback; } ConfigItemIntegerRange; typedef void (*IntegerRangeValueChangedCallback)(ConfigItemIntegerRange *, int32_t); -bool WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandle cat, const char *configId, const char *displayName, - int32_t defaultValue, int32_t minValue, int32_t maxValue, - IntegerRangeValueChangedCallback callback); +WUPSConfigAPIStatus +WUPSConfigItemIntegerRange_Create(const char *identifier, + const char *displayName, + int32_t defaultValue, int32_t currentValue, + int32_t minValue, int32_t maxValue, + IntegerRangeValueChangedCallback callback, + WUPSConfigItemHandle *outHandle); + +/** + * \brief Adds an integer range configuration item to a category. + * + * This function creates a new ConfigItemIntegerRange item and adds it to the specified category. + * The item represents an integer value within a specified range, and allows the user to modify the value. + * + * \param cat The category handle to which the item should be added. + * \param identifier Optional identifier for the item. Can be NULL. + * \param displayName The display name for the item. + * \param defaultValue The default value for the item. + * \param currentValue The current value for the item. + * \param minValue The minimum value allowed for the item. + * \param maxValue The maximum value allowed for the item. + * \param callback A callback function that will be called when the config menu closes and the value of the item has been changed. + * + * \return Returns true if the item was successfully added to the category, false otherwise. + * + * @note The defaultValue and currentValue must in the specified range. + */ +WUPSConfigAPIStatus +WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandle cat, + const char *identifier, + const char *displayName, + int32_t defaultValue, int32_t currentValue, + int32_t minValue, int32_t maxValue, + IntegerRangeValueChangedCallback callback); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif + + +#ifdef __cplusplus +#include "WUPSConfigItem.h" +#include +#include +#include +#include +#include + +class WUPSConfigItemIntegerRange : public WUPSConfigItem { + +public: + static std::optional Create( + std::optional identifier, + std::string_view displayName, + int32_t defaultValue, int32_t currentValue, + int32_t minValue, int32_t maxValue, + IntegerRangeValueChangedCallback valuesChangedCallback, + WUPSConfigAPIStatus &err) noexcept; + + static WUPSConfigItemIntegerRange Create( + std::optional identifier, + std::string_view displayName, + int32_t defaultValue, int32_t currentValue, + int32_t minValue, int32_t maxValue, + IntegerRangeValueChangedCallback valuesChangedCallback); + +private: + explicit WUPSConfigItemIntegerRange(WUPSConfigItemHandle itemHandle) : WUPSConfigItem(itemHandle) { + } +}; +#endif diff --git a/include/wups/config/WUPSConfigItemMultipleValues.h b/include/wups/config/WUPSConfigItemMultipleValues.h index 76c5fc0..d0c2533 100644 --- a/include/wups/config/WUPSConfigItemMultipleValues.h +++ b/include/wups/config/WUPSConfigItemMultipleValues.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include @@ -8,24 +10,107 @@ extern "C" { typedef struct ConfigItemMultipleValuesPair { uint32_t value; - char *valueName; + const char *valueName; } ConfigItemMultipleValuesPair; typedef struct ConfigItemMultipleValues { - char *configId; WUPSConfigItemHandle handle; + const char *identifier; int32_t defaultValueIndex; int32_t valueIndex; - void *callback; + int32_t valueIndexAtCreation; ConfigItemMultipleValuesPair *values; int valueCount; + void *valueChangedCallback; } ConfigItemMultipleValues; typedef void (*MultipleValuesChangedCallback)(ConfigItemMultipleValues *, uint32_t); -bool WUPSConfigItemMultipleValues_AddToCategory(WUPSConfigCategoryHandle cat, const char *configId, const char *displayName, int defaultValueIndex, ConfigItemMultipleValuesPair *possibleValues, - int pairCount, MultipleValuesChangedCallback callback); + +WUPSConfigAPIStatus +WUPSConfigItemMultipleValues_Create(const char *identifier, const char *displayName, + int defaultValueIndex, int currentValueIndex, + ConfigItemMultipleValuesPair *possibleValues, int pairCount, + MultipleValuesChangedCallback callback, + WUPSConfigItemHandle *outHandle); + +/** + * @brief Add a multiple values configuration item to a category. + * + * This function adds a multiple values configuration item to a specified category. + * The item will be displayed in the configuration menu with the provided display name. + * + * @param cat The handle of the category where the item should be added. + * @param identifier The identifier of the item. It is used to uniquely identify the item. + * @param displayName The display name of the item. It will be shown in the configuration menu. + * @param defaultValueIndex The index of the default value in the array of possible values. + * @param currentValueIndex The index of the current value in the array of possible values. + * @param possibleValues An array of possible values for the item. + * @param pairCount The number of pairs (value and value name) in the possibleValues array. + * @param callback A callback function that will be called when the config menu closes and the value of the item has been changed. + * + * @return true if the item was successfully added to the category, false otherwise. + * + * @note The defaultValueIndex and currentValueIndex must be valid for the given pairCount. + */ +WUPSConfigAPIStatus +WUPSConfigItemMultipleValues_AddToCategory(WUPSConfigCategoryHandle cat, const char *identifier, const char *displayName, + int defaultValueIndex, int currentValueIndex, + ConfigItemMultipleValuesPair *possibleValues, int pairCount, + MultipleValuesChangedCallback callback); #ifdef __cplusplus } +#endif + + +#ifdef __cplusplus + +#include "WUPSConfigItem.h" +#include +#include +#include +#include +#include + +class WUPSConfigItemMultipleValues : public WUPSConfigItem { + +public: + struct ValuePair { + uint32_t value; + std::string_view name; + }; + + static std::optional CreateFromIndex(std::optional identifier, + std::string_view displayName, + int defaultValueIndex, int currentValueIndex, + const std::span &possibleValues, + MultipleValuesChangedCallback valuesChangedCallback, + WUPSConfigAPIStatus &err) noexcept; + + static WUPSConfigItemMultipleValues CreateFromIndex(std::optional identifier, + std::string_view displayName, + int defaultValueIndex, int currentValueIndex, + const std::span &possibleValues, + MultipleValuesChangedCallback valuesChangedCallback); + + static std::optional CreateFromValue( + std::optional identifier, + std::string_view displayName, + uint32_t defaultValue, uint32_t currentValue, + const std::span &possibleValues, + MultipleValuesChangedCallback valuesChangedCallback, + WUPSConfigAPIStatus &err) noexcept; + + static WUPSConfigItemMultipleValues CreateFromValue( + std::optional identifier, + std::string_view displayName, + int32_t defaultValue, int32_t currentValue, + const std::span &possibleValues, + MultipleValuesChangedCallback valuesChangedCallback); + +private: + explicit WUPSConfigItemMultipleValues(WUPSConfigItemHandle itemHandle) : WUPSConfigItem(itemHandle) { + } +}; #endif \ No newline at end of file diff --git a/include/wups/config/WUPSConfigItemStub.h b/include/wups/config/WUPSConfigItemStub.h index a2141c1..ecff758 100644 --- a/include/wups/config/WUPSConfigItemStub.h +++ b/include/wups/config/WUPSConfigItemStub.h @@ -1,4 +1,6 @@ -#include +#pragma once + +#include #ifdef __cplusplus extern "C" { @@ -8,8 +10,39 @@ typedef struct ConfigItemStub { WUPSConfigItemHandle handle; } ConfigItemStub; -bool WUPSConfigItemStub_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName); +WUPSConfigAPIStatus WUPSConfigItemStub_Create(const char *displayName, + WUPSConfigItemHandle *outHandle); + +/** + * @brief Adds a stub item to a category to display information + * + * @param cat The handle of the category to which the item should be added. + * @param displayName The display name of the item. + * @return true if the item was added successfully, false otherwise. + */ +WUPSConfigAPIStatus +WUPSConfigItemStub_AddToCategory(WUPSConfigCategoryHandle cat, const char *displayName); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif +#ifdef __cplusplus + +#include "WUPSConfigItem.h" +#include +#include +#include +#include + +class WUPSConfigItemStub : public WUPSConfigItem { +public: + static std::optional Create(std::string_view displayName, + WUPSConfigAPIStatus &err) noexcept; + + static WUPSConfigItemStub Create(std::string_view displayName); + +private: + explicit WUPSConfigItemStub(WUPSConfigItemHandle itemHandle) : WUPSConfigItem(itemHandle) { + } +}; +#endif diff --git a/include/wups/config_api.h b/include/wups/config_api.h index 25ffba9..855b308 100644 --- a/include/wups/config_api.h +++ b/include/wups/config_api.h @@ -1,6 +1,8 @@ #pragma once #include "config.h" +#include "config/WUPSConfigCategory.h" +#include "config/WUPSConfigItem.h" #include #include @@ -11,14 +13,71 @@ extern "C" { typedef WUPSConfigAPICallbackStatus (*WUPSConfigAPI_MenuOpenedCallback)(WUPSConfigCategoryHandle root); typedef void (*WUPSConfigAPI_MenuClosedCallback)(); +/** + * @brief Initialize the WUPSConfigAPI with extended options. For internal use. + * @see WUPSConfigAPI_Init instead + */ WUPSConfigAPIStatus WUPSConfigAPI_InitEx(uint32_t pluginIdentifier, WUPSConfigAPIOptions, WUPSConfigAPI_MenuOpenedCallback, WUPSConfigAPI_MenuClosedCallback); +/** + * @brief Initializes the WUPSConfigAPI with the given options, opened callback, and closed callback. + * + * This function initializes the WUPSConfigAPI with the provided options, opened callback, and closed callback. + * If the initialization is successful, it returns WUPSCONFIG_API_RESULT_SUCCESS. Otherwise, it returns + * an appropriate error code indicating the reason for failure. + * + * @param optionsV1 The options for the WUPSConfigAPI. It contains the name of the plugin. + * @param openedCallback The callback function to be called when the menu is opened. + * @param closedCallback The callback function to be called when the menu is closed. + * + * @return WUPSConfigAPIStatus WUPSCONFIG_API_RESULT_SUCCESS if initialization is successful, + * otherwise an appropriate error code. + * - WUPSCONFIG_API_RESULT_SUCCESS: The initialization was successful. + * - WUPSCONFIG_API_RESULT_INVALID_ARGUMENT: The `openedCallback` or `closedCallback` parameter is nullptr. + * - WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION: The specified `options.version` is not supported. + * - WUPSCONFIG_API_RESULT_NOT_FOUND: The plugin with the given identifier was not found + * - WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED: The API has not been initialized. + * - WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND: The command is not supported. + */ WUPSConfigAPIStatus WUPSConfigAPI_Init(WUPSConfigAPIOptionsV1 optionsV1, WUPSConfigAPI_MenuOpenedCallback openedCallback, WUPSConfigAPI_MenuClosedCallback closedCallback); +/** + * @brief Retrieves the version of the WUPSConfigAPI library. + * + * This function retrieves the version of the WUPSConfigAPI library and stores it in the provided output variable. + * + * @param[out] outVariable Pointer to a WUPSConfigAPIVersion variable to store the library version. + * @return Returns the status of the API call. + * - WUPSCONFIG_API_RESULT_SUCCESS: The version was retrieved successfully. + * - WUPSCONFIG_API_RESULT_MODULE_NOT_FOUND: The module containing the WUPSConfigAPI_GetVersion function was not found. + * - WUPSCONFIG_API_RESULT_MODULE_MISSING_EXPORT: The WUPSConfigAPI_GetVersion function was not found in the module. + */ WUPSConfigAPIStatus WUPSConfigAPI_GetVersion(WUPSConfigAPIVersion *outVariable); +/** + * @brief Create a new category with extended options. Internal use. + * @see WUPSConfigAPI_Category_Create + **/ WUPSConfigAPIStatus WUPSConfigAPI_Category_CreateEx(WUPSConfigAPICreateCategoryOptions options, WUPSConfigCategoryHandle *out); +/** + * @brief Create a new category. + * + * This function creates a new category using the given options. The options struct contains the category name. + * If the category creation is successful, the category handle is returned through the *out parameter. + * + * @param options The options for creating the category. + * @param[out] out A pointer to a WUPSConfigCategoryHandle variable that will receive the category handle. + * @return WUPSConfigAPIStatus The status of the category creation operation. + * - WUPSCONFIG_API_RESULT_SUCCESS: Success. + * - WUPSCONFIG_API_RESULT_INVALID_ARGUMENT: Invalid parameter, `out` or `name` is NULL. + * - WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED: The API has not been initialized. + * - WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND: The command is not supported. + * + * @note The function internally calls WUPSConfigAPI_Category_CreateEx(). + * @note The caller is responsible for deleting the WUPSConfigCategoryHandle instance unless it has been transferred to + * a different category + */ static inline WUPSConfigAPIStatus WUPSConfigAPI_Category_Create(WUPSConfigAPICreateCategoryOptionsV1 options, WUPSConfigCategoryHandle *out) { WUPSConfigAPICreateCategoryOptions optionsWrapper = { .version = WUPS_API_CATEGORY_OPTION_VERSION_V1, @@ -27,24 +86,126 @@ static inline WUPSConfigAPIStatus WUPSConfigAPI_Category_Create(WUPSConfigAPICre return WUPSConfigAPI_Category_CreateEx(optionsWrapper, out); } +/** + * @brief Destroys a WUPSConfigCategoryHandle. + * + * This function is used to destroy a WUPSConfigCategoryHandle object. + * + * @param handle The WUPSConfigCategoryHandle to be destroyed. + * @return WUPSConfigAPIStatus Returns the status of the API call: + * - WUPSCONFIG_API_RESULT_SUCCESS: The WUPSConfigCategoryHandle was successfully destroyed. + * - WUPSCONFIG_API_RESULT_INVALID_ARGUMENT: The handle is nullptr. + * - WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED: The API has not been initialized. + * - WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND: The command is not supported. + * + * @note The caller is responsible for deleting the WUPSConfigCategoryHandle instance unless it has been transferred to + * a different category + */ WUPSConfigAPIStatus WUPSConfigAPI_Category_Destroy(WUPSConfigCategoryHandle handle); +/** + * @brief Adds a category to the parent category. + * + * This function is used to add a category to an existing parent category. + * + * @param parentHandle The handle to the parent category. + * @param categoryHandle The handle to the category to be added. + * + * @return WUPSConfigAPIStatus The status code indicating the result of the operation. + * Possible values are: + * - WUPSCONFIG_API_RESULT_SUCCESS: The category was added successfully. + * - WUPSCONFIG_API_RESULT_INVALID_ARGUMENT: The parentHandle or categoryHandle is null. + * - WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED: The library is not initialized. + * - WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND: The command is not supported. + * - WUPSCONFIG_API_RESULT_UNKNOWN_ERROR: An unknown error occurred. + * + * @note On success the ownership of the category will be transferred to the Category and the categoryHandle WUPSConfigCategoryHandle + * will be invalid. + */ WUPSConfigAPIStatus WUPSConfigAPI_Category_AddCategory(WUPSConfigCategoryHandle parentHandle, WUPSConfigCategoryHandle categoryHandle); +/** + * @brief Adds an item to the given category. + * + * This function adds the specified item to the parent category. The parent + * category and item handles must be valid and non-zero. + * + * @param parentHandle The handle of the parent category. + * @param[out] itemHandle The handle of the item to be added. + * @return WUPSConfigAPIStatus The status code indicating the result of the operation. + * - WUPSCONFIG_API_RESULT_SUCCESS: If the item was added successfully. + * - WUPSCONFIG_API_RESULT_INVALID_ARGUMENT: If either the parentHandle or itemHandle is invalid. + * - WUPSCONFIG_API_RESULT_NOT_FOUND: If the parent category was not found. + * - WUPSCONFIG_API_RESULT_UNKNOWN_ERROR: If an unknown error occurred while adding the item. + * - WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND: The provided command is not supported. + * - WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED: The library is not initialized properly. + * @see WUPSConfigCategoryHandle + * @see WUPSConfigItemHandle + * @see WUPSConfigAPIStatus + * + * @note On success the ownership of the item will be transferred to the Category and the itemHandle WUPSConfigItemHandle + * will be invalid. + */ WUPSConfigAPIStatus WUPSConfigAPI_Category_AddItem(WUPSConfigCategoryHandle parentHandle, WUPSConfigItemHandle itemHandle); +/** + * @brief Create a WUPSConfigAPI item with extended options. Internal use. + * @see WUPSConfigAPI_Item_Create + **/ WUPSConfigAPIStatus WUPSConfigAPI_Item_CreateEx(WUPSConfigAPICreateItemOptions options, WUPSConfigItemHandle *out); -static inline WUPSConfigAPIStatus WUPSConfigAPI_Item_Create(WUPSConfigAPIItemOptionsV1 options, WUPSConfigItemHandle *out) { +/** + * @brief Creates a new configuration item using the provided options. + * + * This function creates a new configuration item using the provided options. + * + * @param options The options for creating the configuration item. + * @param[out] out The handle to the created configuration item. + * @return The status of the API call. Possible values are: + * - WUPSCONFIG_API_RESULT_SUCCESS if the item was created and added successfully. + * - WUPSCONFIG_API_RESULT_INVALID_ARGUMENT if the 'out' parameter is nullptr. + * - WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION if the options version is invalid. + * - WUPSCONFIG_API_RESULT_OUT_OF_MEMORY if memory allocation failed. + * - WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND: The provided command is not supported. + * - WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED: The library is not initialized properly. + * + * @note The caller is responsible for deleting the WUPSConfigItem instance unless it has been transferred to + * a category + */ +static inline WUPSConfigAPIStatus WUPSConfigAPI_Item_Create(WUPSConfigAPIItemOptionsV2 options, WUPSConfigItemHandle *out) { WUPSConfigAPICreateItemOptions itemOptions = { - .version = WUPS_API_ITEM_OPTION_VERSION_V1, - .data = {.v1 = options}, + .version = WUPS_API_ITEM_OPTION_VERSION_V2, + .data = {.v2 = options}, }; return WUPSConfigAPI_Item_CreateEx(itemOptions, out); } +/** + * @brief Destroy a WUPSConfigItemHandle. + * + * This function destroys a WUPSConfigItemHandle. It can only be called if the WUPSConfig API is initialized and the handle is valid. + * A item must not be destroyed if it's added to a WUPSConfigCategory + * + * @param handle The handle to be destroyed. + * @return WUPSConfigAPIStatus The status code indicating the result of the operation: + * - WUPSCONFIG_API_RESULT_SUCCESS: If the handle was successfully destroyed. + * - WUPSCONFIG_API_RESULT_NOT_FOUND: The WUPSConfigItem with the given handle was not found. + * - WUPSCONFIG_API_RESULT_INVALID_ARGUMENT: If the handle is invalid. + * - WUPSCONFIG_API_RESULT_LIB_UNINITIALIZED: If the WUPSConfig API is not initialized. + * - WUPSCONFIG_API_RESULT_UNSUPPORTED_COMMAND: If the destroy command is not supported by the API or the API version is too low. + */ WUPSConfigAPIStatus WUPSConfigAPI_Item_Destroy(WUPSConfigItemHandle handle); +/** + * @brief Converts a WUPSConfigAPIStatus value to a corresponding string representation. + * + * This function takes a WUPSConfigAPIStatus value and returns a string representation of the value. + * The string representation is determined based on the given status value using a switch statement. + * If the status value is not recognized, a default string "WUPSCONFIG_API_RESULT_UNKNOWN_ERROR" is returned. + * + * @param status The WUPSConfigAPIStatus value to convert to string. + * @return The string representation of the given WUPSConfigAPIStatus value. + */ const char *WUPSConfigAPI_GetStatusStr(WUPSConfigAPIStatus status); #ifdef __cplusplus diff --git a/include/wups/hooks.h b/include/wups/hooks.h index 68752df..8484254 100644 --- a/include/wups/hooks.h +++ b/include/wups/hooks.h @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . ****************************************************************************/ - #pragma once #include "common.h" diff --git a/include/wups/storage.h b/include/wups/storage.h index 996863a..587ea3d 100644 --- a/include/wups/storage.h +++ b/include/wups/storage.h @@ -102,9 +102,6 @@ WUPSStorageError WUPS_GetFloat(wups_storage_item parent, const char *key, float WUPSStorageError WUPS_GetDouble(wups_storage_item parent, const char *key, double *outValue); WUPSStorageError WUPS_GetBinary(wups_storage_item parent, const char *key, void *outData, uint32_t maxSize, uint32_t *outSize); -/** - * Return the size of a stored string or binary item. - */ WUPSStorageError WUPS_GetItemSize(wups_storage_item parent, const char *key, uint32_t *outSize); #ifdef __cplusplus diff --git a/include/wups/wups_debug.h b/include/wups/wups_debug.h new file mode 100644 index 0000000..c966fa8 --- /dev/null +++ b/include/wups/wups_debug.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef DEBUG +#include +#endif + +#ifdef DEBUG +#define WUPS_DEBUG_REPORT(fmt, ...) OSReport(fmt, ##__VA_ARGS__) +#else +#define WUPS_DEBUG_REPORT(fmt, ...) +#endif \ No newline at end of file diff --git a/libraries/libwups/WUPSConfigCategory.cpp b/libraries/libwups/WUPSConfigCategory.cpp new file mode 100644 index 0000000..896338a --- /dev/null +++ b/libraries/libwups/WUPSConfigCategory.cpp @@ -0,0 +1,67 @@ +#include +#include + +WUPSConfigCategory::WUPSConfigCategory(WUPSConfigCategoryHandle handle) noexcept : mHandle(handle) { +} + +WUPSConfigCategory::~WUPSConfigCategory() { + if (mHandle.handle != nullptr) { + WUPSConfigAPI_Category_Destroy(mHandle); + } +} + +std::optional WUPSConfigCategory::Create(std::string_view name, WUPSConfigAPIStatus &error) noexcept { + WUPSConfigCategoryHandle catHandle; + if ((error = WUPSConfigAPI_Category_Create({.name = name.data()}, &catHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + return std::nullopt; + } + return WUPSConfigCategory(catHandle); +} + +WUPSConfigCategory WUPSConfigCategory::Create(std::string_view name) { + WUPSConfigAPIStatus error; + auto res = Create(name, error); + if (!res) { + throw std::runtime_error{std::string("Failed to create category: ").append(name)}; + } + return std::move(*res); +} + +bool WUPSConfigCategory::add(WUPSConfigCategory &&cat, WUPSConfigAPIStatus &error) noexcept { + if (mHandle.handle == nullptr || cat.getHandle().handle == nullptr) { + OSReport("mHandle %08X item %08X\n", mHandle.handle, cat.getHandle().handle); + return false; + } + if ((error = WUPSConfigAPI_Category_AddCategory(mHandle, cat.getHandle())) != WUPSCONFIG_API_RESULT_SUCCESS) { + return false; + } + cat.release(); + return true; +} + +void WUPSConfigCategory::add(WUPSConfigCategory &&cat) { + WUPSConfigAPIStatus err; + if (!add(std::move(cat), err)) { + throw std::runtime_error{"Failed to add category to category"}; + } +} + +bool WUPSConfigCategory::add(WUPSConfigItem &&item, WUPSConfigAPIStatus &error) noexcept { + if (mHandle.handle == nullptr || item.getHandle().handle == nullptr) { + OSReport("mHandle %08X item %08X\n", mHandle.handle, item.getHandle().handle); + error = WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; + return false; + } + if ((error = WUPSConfigAPI_Category_AddItem(mHandle, item.getHandle())) != WUPSCONFIG_API_RESULT_SUCCESS) { + return false; + } + item.release(); + return true; +} + +void WUPSConfigCategory::add(WUPSConfigItem &&item) { + WUPSConfigAPIStatus err; + if (!add(std::move(item), err)) { + throw std::runtime_error{"Failed to add item to category"}; + } +} \ No newline at end of file diff --git a/libraries/libwups/WUPSConfigItem.cpp b/libraries/libwups/WUPSConfigItem.cpp new file mode 100644 index 0000000..33272a5 --- /dev/null +++ b/libraries/libwups/WUPSConfigItem.cpp @@ -0,0 +1,8 @@ +#include +#include + +WUPSConfigItem::~WUPSConfigItem() { + if (mHandle.handle != nullptr) { + WUPSConfigAPI_Item_Destroy(mHandle); + } +} \ No newline at end of file diff --git a/libraries/libwups/WUPSConfigItemBoolean.cpp b/libraries/libwups/WUPSConfigItemBoolean.cpp index f24637c..fec1675 100644 --- a/libraries/libwups/WUPSConfigItemBoolean.cpp +++ b/libraries/libwups/WUPSConfigItemBoolean.cpp @@ -2,43 +2,36 @@ #include #include #include -#include +#include -int32_t WUPSConfigItemBoolean_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) { +static void WUPSConfigItemBoolean_onCloseCallback(void *context) { + auto *item = (ConfigItemBoolean *) context; + if (item->valueAtCreation != item->value && item->valueChangedCallback != nullptr) { + ((BooleanValueChangedCallback) (item->valueChangedCallback))(item, item->value); + } +} + +static inline void toggleValue(ConfigItemBoolean *item) { + item->value = !item->value; +} + +static void WUPSConfigItemBoolean_onInput(void *context, WUPSConfigSimplePadData input) { + auto *item = (ConfigItemBoolean *) context; + if ((input.buttons_d & WUPS_CONFIG_BUTTON_A) == WUPS_CONFIG_BUTTON_A) { + toggleValue(item); + } else if (input.buttons_d & WUPS_CONFIG_BUTTON_LEFT && !item->value) { + toggleValue(item); + } else if ((input.buttons_d & WUPS_CONFIG_BUTTON_RIGHT) && item->value) { + toggleValue(item); + } +} +static 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); return 0; } -void toggleValue(ConfigItemBoolean *item) { - item->value = !item->value; -} - -bool WUPSConfigItemBoolean_callCallback(void *context) { - auto *item = (ConfigItemBoolean *) context; - if (item->callback != nullptr) { - ((BooleanValueChangedCallback) (item->callback))(item, item->value); - return true; - } - return false; -} - -void WUPSConfigItemBoolean_onButtonPressed(void *context, WUPSConfigButtons buttons) { - auto *item = (ConfigItemBoolean *) context; - if ((buttons & WUPS_CONFIG_BUTTON_A) == WUPS_CONFIG_BUTTON_A) { - toggleValue(item); - } else if (buttons & WUPS_CONFIG_BUTTON_LEFT && !item->value) { - toggleValue(item); - } else if ((buttons & WUPS_CONFIG_BUTTON_RIGHT) && item->value) { - toggleValue(item); - } -} - -bool WUPSConfigItemBoolean_isMovementAllowed(void *context) { - return true; -} - -int32_t WUPSConfigItemBoolean_getCurrentValueSelectedDisplay(void *context, char *out_buf, int32_t out_size) { +static int32_t WUPSConfigItemBoolean_getCurrentValueSelectedDisplay(void *context, char *out_buf, int32_t out_size) { auto *item = (ConfigItemBoolean *) context; if (item->value) { snprintf(out_buf, out_size, " %s >", item->trueValue); @@ -48,77 +41,114 @@ int32_t WUPSConfigItemBoolean_getCurrentValueSelectedDisplay(void *context, char return 0; } -void WUPSConfigItemBoolean_restoreDefault(void *context) { +static void WUPSConfigItemBoolean_restoreDefault(void *context) { auto *item = (ConfigItemBoolean *) context; item->value = item->defaultValue; } -void WUPSConfigItemBoolean_onSelected(void *context, bool isSelected) { -} - static void WUPSConfigItemBoolean_Cleanup(ConfigItemBoolean *item) { if (!item) { return; } - free(item->configId); + free((void *) item->identifier); free(item); } -void WUPSConfigItemBoolean_onDelete(void *context) { +static 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 == nullptr) { - return false; +extern "C" WUPSConfigAPIStatus +WUPSConfigItemBoolean_CreateEx(const char *identifier, + const char *displayName, + bool defaultValue, + bool currentValue, + BooleanValueChangedCallback callback, + const char *trueValue, + const char *falseValue, + WUPSConfigItemHandle *outHandle) { + if (outHandle == nullptr) { + return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; } auto *item = (ConfigItemBoolean *) malloc(sizeof(ConfigItemBoolean)); if (item == nullptr) { - return false; + return WUPSCONFIG_API_RESULT_OUT_OF_MEMORY; } - if (configId != nullptr) { - item->configId = strdup(configId); + if (identifier != nullptr) { + item->identifier = strdup(identifier); } else { - item->configId = nullptr; + item->identifier = nullptr; } - item->defaultValue = defaultValue; - item->value = defaultValue; - item->callback = (void *) callback; + item->defaultValue = defaultValue; + item->value = currentValue; + item->valueAtCreation = currentValue; + item->valueChangedCallback = (void *) callback; snprintf(item->trueValue, sizeof(item->trueValue), "%s", trueValue); snprintf(item->falseValue, sizeof(item->falseValue), "%s", falseValue); - WUPSConfigAPIItemCallbacksV1 callbacks = { + WUPSConfigAPIItemCallbacksV2 callbacks = { .getCurrentValueDisplay = &WUPSConfigItemBoolean_getCurrentValueDisplay, .getCurrentValueSelectedDisplay = &WUPSConfigItemBoolean_getCurrentValueSelectedDisplay, - .onSelected = &WUPSConfigItemBoolean_onSelected, + .onSelected = nullptr, .restoreDefault = &WUPSConfigItemBoolean_restoreDefault, - .isMovementAllowed = &WUPSConfigItemBoolean_isMovementAllowed, - .callCallback = &WUPSConfigItemBoolean_callCallback, - .onButtonPressed = &WUPSConfigItemBoolean_onButtonPressed, + .isMovementAllowed = nullptr, + .onCloseCallback = &WUPSConfigItemBoolean_onCloseCallback, + .onInput = &WUPSConfigItemBoolean_onInput, + .onInputEx = nullptr, .onDelete = &WUPSConfigItemBoolean_onDelete}; - WUPSConfigAPIItemOptionsV1 options = { + WUPSConfigAPIItemOptionsV2 options = { .displayName = displayName, .context = item, .callbacks = callbacks, }; - if (WUPSConfigAPI_Item_Create(options, &item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigAPIStatus err; + if ((err = WUPSConfigAPI_Item_Create(options, &item->handle)) != WUPSCONFIG_API_RESULT_SUCCESS) { WUPSConfigItemBoolean_Cleanup(item); - return false; + return err; } - if (WUPSConfigAPI_Category_AddItem(cat, item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { - WUPSConfigAPI_Item_Destroy(item->handle); - return false; - } - return true; + *outHandle = item->handle; + return WUPSCONFIG_API_RESULT_SUCCESS; } -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"); +extern "C" WUPSConfigAPIStatus +WUPSConfigItemBoolean_AddToCategoryEx(WUPSConfigCategoryHandle cat, + const char *identifier, + const char *displayName, + bool defaultValue, + bool currentValue, + BooleanValueChangedCallback callback, + const char *trueValue, + const char *falseValue) { + WUPSConfigItemHandle itemHandle; + WUPSConfigAPIStatus res; + if ((res = WUPSConfigItemBoolean_CreateEx(identifier, + displayName, + defaultValue, currentValue, + callback, + trueValue, falseValue, + &itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + return res; + } + + if ((res = WUPSConfigAPI_Category_AddItem(cat, itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + + WUPSConfigAPI_Item_Destroy(itemHandle); + return res; + } + return WUPSCONFIG_API_RESULT_SUCCESS; +} + +extern "C" WUPSConfigAPIStatus +WUPSConfigItemBoolean_AddToCategory(WUPSConfigCategoryHandle cat, + const char *identifier, + const char *displayName, + bool defaultValue, + bool currentValue, + BooleanValueChangedCallback callback) { + return WUPSConfigItemBoolean_AddToCategoryEx(cat, identifier, displayName, defaultValue, currentValue, callback, "true", "false"); } diff --git a/libraries/libwups/WUPSConfigItemBooleanCpp.cpp b/libraries/libwups/WUPSConfigItemBooleanCpp.cpp new file mode 100644 index 0000000..654c830 --- /dev/null +++ b/libraries/libwups/WUPSConfigItemBooleanCpp.cpp @@ -0,0 +1,36 @@ +#include "wups/config/WUPSConfigItemBoolean.h" + +std::optional WUPSConfigItemBoolean::CreateEx(std::optional identifier, std::string_view displayName, bool defaultValue, bool currentValue, BooleanValueChangedCallback callback, std::string_view trueValue, std::string_view falseValue, WUPSConfigAPIStatus &err) noexcept { + WUPSConfigItemHandle itemHandle; + if ((err = WUPSConfigItemBoolean_CreateEx(identifier ? identifier->data() : nullptr, + displayName.data(), + defaultValue, currentValue, + callback, + trueValue.data(), + falseValue.data(), + &itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + return std::nullopt; + } + return WUPSConfigItemBoolean(itemHandle); +} +WUPSConfigItemBoolean WUPSConfigItemBoolean::CreateEx(std::optional identifier, std::string_view displayName, bool defaultValue, bool currentValue, BooleanValueChangedCallback callback, std::string_view trueValue, std::string_view falseValue) { + WUPSConfigAPIStatus err; + auto result = CreateEx(std::move(identifier), displayName, defaultValue, currentValue, callback, trueValue, falseValue, err); + if (!result) { + throw std::runtime_error(std::string("Failed to create WUPSConfigItemBoolean: ").append(WUPSConfigAPI_GetStatusStr(err))); + } + return std::move(*result); +} + +std::optional WUPSConfigItemBoolean::Create(std::optional identifier, std::string_view displayName, bool defaultValue, bool currentValue, BooleanValueChangedCallback callback, WUPSConfigAPIStatus &err) noexcept { + return CreateEx(std::move(identifier), displayName, defaultValue, currentValue, callback, "true", "false", err); +} + +WUPSConfigItemBoolean WUPSConfigItemBoolean::Create(std::optional identifier, std::string_view displayName, bool defaultValue, bool currentValue, BooleanValueChangedCallback callback) { + WUPSConfigAPIStatus err = WUPSCONFIG_API_RESULT_UNKNOWN_ERROR; + auto res = Create(std::move(identifier), displayName, defaultValue, currentValue, callback, err); + if (!res) { + throw std::runtime_error(std::string("Failed to create WUPSConfigItemBoolean: ").append(WUPSConfigAPI_GetStatusStr(err))); + } + return std::move(*res); +} diff --git a/libraries/libwups/WUPSConfigItemIntegerRange.cpp b/libraries/libwups/WUPSConfigItemIntegerRange.cpp index e6ff09c..6ee95e1 100644 --- a/libraries/libwups/WUPSConfigItemIntegerRange.cpp +++ b/libraries/libwups/WUPSConfigItemIntegerRange.cpp @@ -2,32 +2,25 @@ #include #include #include -#include +#include -int32_t WUPSConfigItemIntegerRange_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) { +void WUPSConfigItemIntegerRange_onCloseCallback(void *context) { auto *item = (ConfigItemIntegerRange *) context; - snprintf(out_buf, out_size, "%d", item->value); - return 0; -} - -bool WUPSConfigItemIntegerRange_callCallback(void *context) { - auto *item = (ConfigItemIntegerRange *) context; - if (item->callback != nullptr) { - ((IntegerRangeValueChangedCallback) item->callback)(item, item->value); - return true; + if (item->valueAtCreation != item->value && item->valueChangedCallback != nullptr) { + ((IntegerRangeValueChangedCallback) item->valueChangedCallback)(item, item->value); } - return false; } -void WUPSConfigItemIntegerRange_onButtonPressed(void *context, WUPSConfigButtons buttons) { +void WUPSConfigItemIntegerRange_onInput(void *context, WUPSConfigSimplePadData input) { auto *item = (ConfigItemIntegerRange *) context; - if (buttons & WUPS_CONFIG_BUTTON_LEFT) { + + if (input.buttons_d & WUPS_CONFIG_BUTTON_LEFT) { item->value--; - } else if ((buttons & WUPS_CONFIG_BUTTON_RIGHT)) { + } else if ((input.buttons_d & WUPS_CONFIG_BUTTON_RIGHT)) { item->value++; - } else if ((buttons & WUPS_CONFIG_BUTTON_L)) { + } else if ((input.buttons_d & WUPS_CONFIG_BUTTON_L)) { item->value = item->value - 50; - } else if ((buttons & WUPS_CONFIG_BUTTON_R)) { + } else if ((input.buttons_d & WUPS_CONFIG_BUTTON_R)) { item->value = item->value + 50; } @@ -38,8 +31,10 @@ void WUPSConfigItemIntegerRange_onButtonPressed(void *context, WUPSConfigButtons } } -bool WUPSConfigItemIntegerRange_isMovementAllowed(void *context) { - return true; +int32_t WUPSConfigItemIntegerRange_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) { + auto *item = (ConfigItemIntegerRange *) context; + snprintf(out_buf, out_size, " %d", item->value); + return 0; } int32_t WUPSConfigItemIntegerRange_getCurrentValueSelectedDisplay(void *context, char *out_buf, int32_t out_size) { @@ -59,14 +54,11 @@ void WUPSConfigItemIntegerRange_restoreDefault(void *context) { item->value = item->defaultValue; } -void WUPSConfigItemIntegerRange_onSelected(void *context, bool isSelected) { -} - static void WUPSConfigItemIntegerRange_Cleanup(ConfigItemIntegerRange *item) { if (!item) { return; } - free(item->configId); + free((void *) item->identifier); free(item); } @@ -74,52 +66,87 @@ 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, - IntegerRangeValueChangedCallback callback) { - if (cat == 0) { - return false; +extern "C" WUPSConfigAPIStatus +WUPSConfigItemIntegerRange_Create(const char *identifier, + const char *displayName, + int32_t defaultValue, int32_t currentValue, + int32_t minValue, int32_t maxValue, + IntegerRangeValueChangedCallback callback, + WUPSConfigItemHandle *outHandle) { + if (outHandle == nullptr) { + return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; } + if (maxValue < minValue || defaultValue < minValue || defaultValue > maxValue || currentValue < minValue || currentValue > maxValue) { + return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; + } + *outHandle = {}; auto *item = (ConfigItemIntegerRange *) malloc(sizeof(ConfigItemIntegerRange)); if (item == nullptr) { - return false; + return WUPSCONFIG_API_RESULT_OUT_OF_MEMORY; } - if (configId != nullptr) { - item->configId = strdup(configId); + if (identifier != nullptr) { + item->identifier = strdup(identifier); } else { - item->configId = nullptr; + item->identifier = nullptr; } - item->defaultValue = defaultValue; - item->value = defaultValue; - item->minValue = minValue; - item->maxValue = maxValue; - item->callback = (void *) callback; + item->defaultValue = defaultValue; + item->value = currentValue; + item->valueAtCreation = currentValue; + item->minValue = minValue; + item->maxValue = maxValue; + item->valueChangedCallback = (void *) callback; - WUPSConfigAPIItemCallbacksV1 callbacks = { + WUPSConfigAPIItemCallbacksV2 callbacks = { .getCurrentValueDisplay = &WUPSConfigItemIntegerRange_getCurrentValueDisplay, .getCurrentValueSelectedDisplay = &WUPSConfigItemIntegerRange_getCurrentValueSelectedDisplay, - .onSelected = &WUPSConfigItemIntegerRange_onSelected, + .onSelected = nullptr, .restoreDefault = &WUPSConfigItemIntegerRange_restoreDefault, - .isMovementAllowed = &WUPSConfigItemIntegerRange_isMovementAllowed, - .callCallback = &WUPSConfigItemIntegerRange_callCallback, - .onButtonPressed = &WUPSConfigItemIntegerRange_onButtonPressed, - .onDelete = &WUPSConfigItemIntegerRange_onDelete}; + .isMovementAllowed = nullptr, + .onCloseCallback = &WUPSConfigItemIntegerRange_onCloseCallback, + .onInput = &WUPSConfigItemIntegerRange_onInput, + .onInputEx = nullptr, + .onDelete = &WUPSConfigItemIntegerRange_onDelete, + }; - WUPSConfigAPIItemOptionsV1 options = { + WUPSConfigAPIItemOptionsV2 options = { .displayName = displayName, .context = item, .callbacks = callbacks, }; - if (WUPSConfigAPI_Item_Create(options, &(item->handle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigAPIStatus err; + if ((err = WUPSConfigAPI_Item_Create(options, &(item->handle))) != WUPSCONFIG_API_RESULT_SUCCESS) { WUPSConfigItemIntegerRange_Cleanup(item); - return false; - }; - - if (WUPSConfigAPI_Category_AddItem(cat, item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { - WUPSConfigAPI_Item_Destroy(item->handle); - return false; + return err; } - return true; -} \ No newline at end of file + *outHandle = item->handle; + + return WUPSCONFIG_API_RESULT_SUCCESS; +} + +extern "C" WUPSConfigAPIStatus +WUPSConfigItemIntegerRange_AddToCategory(WUPSConfigCategoryHandle cat, + const char *identifier, + const char *displayName, + int32_t defaultValue, int32_t currentValue, + int32_t minValue, int32_t maxValue, + IntegerRangeValueChangedCallback callback) { + WUPSConfigItemHandle itemHandle; + WUPSConfigAPIStatus res; + if ((res = WUPSConfigItemIntegerRange_Create(identifier, + displayName, + defaultValue, currentValue, + minValue, maxValue, + callback, + &itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + return res; + } + + if ((res = WUPSConfigAPI_Category_AddItem(cat, itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigAPI_Item_Destroy(itemHandle); + return res; + } + return WUPSCONFIG_API_RESULT_SUCCESS; +} diff --git a/libraries/libwups/WUPSConfigItemIntegerRangeCpp.cpp b/libraries/libwups/WUPSConfigItemIntegerRangeCpp.cpp new file mode 100644 index 0000000..cfe1bfc --- /dev/null +++ b/libraries/libwups/WUPSConfigItemIntegerRangeCpp.cpp @@ -0,0 +1,34 @@ +#include "wups/config/WUPSConfigItemIntegerRange.h" + +std::optional WUPSConfigItemIntegerRange::Create( + std::optional identifier, + std::string_view displayName, + int32_t defaultValue, int32_t currentValue, + int32_t minValue, int32_t maxValue, + IntegerRangeValueChangedCallback valuesChangedCallback, + WUPSConfigAPIStatus &err) noexcept { + WUPSConfigItemHandle itemHandle; + if ((err = WUPSConfigItemIntegerRange_Create(identifier ? identifier->c_str() : nullptr, + displayName.data(), + defaultValue, currentValue, + minValue, maxValue, + valuesChangedCallback, + &itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + return std::nullopt; + } + return WUPSConfigItemIntegerRange(itemHandle); +} + +WUPSConfigItemIntegerRange WUPSConfigItemIntegerRange::Create( + std::optional identifier, + std::string_view displayName, + int32_t defaultValue, int32_t currentValue, + int32_t minValue, int32_t maxValue, + IntegerRangeValueChangedCallback valuesChangedCallback) { + WUPSConfigAPIStatus err = WUPSCONFIG_API_RESULT_UNKNOWN_ERROR; + auto result = Create(std::move(identifier), displayName, defaultValue, currentValue, minValue, maxValue, valuesChangedCallback, err); + if (!result) { + throw std::runtime_error(std::string("Failed to create WUPSConfigItemIntegerRange: ").append(WUPSConfigAPI_GetStatusStr(err))); + } + return std::move(*result); +} \ No newline at end of file diff --git a/libraries/libwups/WUPSConfigItemMultipleValues.cpp b/libraries/libwups/WUPSConfigItemMultipleValues.cpp index 0683928..7d51806 100644 --- a/libraries/libwups/WUPSConfigItemMultipleValues.cpp +++ b/libraries/libwups/WUPSConfigItemMultipleValues.cpp @@ -2,9 +2,9 @@ #include #include #include -#include +#include -int32_t WUPSConfigItemMultipleValues_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) { +static int32_t WUPSConfigItemMultipleValues_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) { auto *item = (ConfigItemMultipleValues *) context; if (item->values && item->valueIndex >= 0 && item->valueIndex < item->valueCount) { @@ -17,20 +17,20 @@ int32_t WUPSConfigItemMultipleValues_getCurrentValueDisplay(void *context, char return -1; } -bool WUPSConfigItemMultipleValues_callCallback(void *context) { +static void WUPSConfigItemMultipleValues_onCloseCallback(void *context) { auto *item = (ConfigItemMultipleValues *) context; - if (item->callback != nullptr && item->values && item->valueIndex >= 0 && item->valueIndex < item->valueCount) { - ((MultipleValuesChangedCallback) (item->callback))(item, item->values[item->valueIndex].value); - return true; + if (item->valueIndexAtCreation != item->valueIndex && item->valueChangedCallback != nullptr) { + if (item->values && item->valueIndex >= 0 && item->valueIndex < item->valueCount) { + ((MultipleValuesChangedCallback) (item->valueChangedCallback))(item, item->values[item->valueIndex].value); + } } - return false; } -void WUPSConfigItemMultipleValues_onButtonPressed(void *context, WUPSConfigButtons buttons) { +static void WUPSConfigItemMultipleValues_onInput(void *context, WUPSConfigSimplePadData input) { auto *item = (ConfigItemMultipleValues *) context; - if (buttons & WUPS_CONFIG_BUTTON_LEFT) { + if (input.buttons_d & WUPS_CONFIG_BUTTON_LEFT) { item->valueIndex--; - } else if (buttons & WUPS_CONFIG_BUTTON_RIGHT) { + } else if (input.buttons_d & WUPS_CONFIG_BUTTON_RIGHT) { item->valueIndex++; } if (item->valueIndex < 0) { @@ -40,11 +40,7 @@ void WUPSConfigItemMultipleValues_onButtonPressed(void *context, WUPSConfigButto } } -bool WUPSConfigItemMultipleValues_isMovementAllowed(void *context) { - return true; -} - -int32_t WUPSConfigItemMultipleValues_getCurrentValueSelectedDisplay(void *context, char *out_buf, int32_t out_size) { +static int32_t WUPSConfigItemMultipleValues_getCurrentValueSelectedDisplay(void *context, char *out_buf, int32_t out_size) { auto *item = (ConfigItemMultipleValues *) context; if (item->values && item->valueIndex >= 0 && item->valueIndex < item->valueCount) { if (item->valueCount == 1) { @@ -62,94 +58,119 @@ int32_t WUPSConfigItemMultipleValues_getCurrentValueSelectedDisplay(void *contex return 0; } -void WUPSConfigItemMultipleValues_restoreDefault(void *context) { +static void WUPSConfigItemMultipleValues_restoreDefault(void *context) { auto *item = (ConfigItemMultipleValues *) context; item->valueIndex = item->defaultValueIndex; } -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((void *) item->values[i].valueName); } - free(item->configId); - free(item->values); + free((void *) item->identifier); + free(item->values); free(item); } -void WUPSConfigItemMultipleValues_onDelete(void *context) { +static 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, - int pairCount, MultipleValuesChangedCallback callback) { - if (cat == 0 || displayName == nullptr || possibleValues == nullptr || pairCount < 0) { - return false; +extern "C" WUPSConfigAPIStatus +WUPSConfigItemMultipleValues_Create(const char *identifier, const char *displayName, + int32_t defaultValueIndex, int currentValueIndex, + ConfigItemMultipleValuesPair *possibleValues, + int pairCount, MultipleValuesChangedCallback callback, + WUPSConfigItemHandle *outHandle) { + if (outHandle == nullptr || displayName == nullptr || possibleValues == nullptr || pairCount < 0 || + defaultValueIndex >= pairCount || currentValueIndex >= pairCount) { + return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; } + *outHandle = {}; auto *item = (ConfigItemMultipleValues *) malloc(sizeof(ConfigItemMultipleValues)); if (item == nullptr) { - return false; + return WUPSCONFIG_API_RESULT_OUT_OF_MEMORY; + } + *item = {}; + + item->values = (ConfigItemMultipleValuesPair *) malloc(sizeof(ConfigItemMultipleValuesPair) * pairCount); + if (!item->values) { + WUPSConfigItemMultipleValues_Cleanup(item); + return WUPSCONFIG_API_RESULT_OUT_OF_MEMORY; } - auto *values = (ConfigItemMultipleValuesPair *) malloc(sizeof(ConfigItemMultipleValuesPair) * pairCount); + if (identifier != nullptr) { + item->identifier = strdup(identifier); + } else { + item->identifier = nullptr; + } for (int i = 0; i < pairCount; ++i) { - values[i].value = possibleValues[i].value; + item->values[i].value = possibleValues[i].value; if (possibleValues[i].valueName == nullptr) { - values[i].valueName = nullptr; + item->values[i].valueName = nullptr; continue; } - values[i].valueName = strdup(possibleValues[i].valueName); + item->values[i].valueName = strdup(possibleValues[i].valueName); } - item->valueCount = pairCount; - item->values = values; - item->valueIndex = defaultValueIndex; - item->defaultValueIndex = defaultValueIndex; - item->callback = (void *) callback; + item->valueCount = pairCount; + item->defaultValueIndex = defaultValueIndex; + item->valueIndex = currentValueIndex; + item->valueIndexAtCreation = currentValueIndex; + item->valueChangedCallback = (void *) callback; - if (configId != nullptr) { - item->configId = strdup(configId); - } else { - item->configId = nullptr; - } - - WUPSConfigAPIItemCallbacksV1 callbacks = { + WUPSConfigAPIItemCallbacksV2 callbacks = { .getCurrentValueDisplay = &WUPSConfigItemMultipleValues_getCurrentValueDisplay, .getCurrentValueSelectedDisplay = &WUPSConfigItemMultipleValues_getCurrentValueSelectedDisplay, - .onSelected = &WUPSConfigItemMultipleValues_onSelected, + .onSelected = nullptr, .restoreDefault = &WUPSConfigItemMultipleValues_restoreDefault, - .isMovementAllowed = &WUPSConfigItemMultipleValues_isMovementAllowed, - .callCallback = &WUPSConfigItemMultipleValues_callCallback, - .onButtonPressed = &WUPSConfigItemMultipleValues_onButtonPressed, + .isMovementAllowed = nullptr, + .onCloseCallback = &WUPSConfigItemMultipleValues_onCloseCallback, + .onInput = &WUPSConfigItemMultipleValues_onInput, + .onInputEx = nullptr, .onDelete = &WUPSConfigItemMultipleValues_onDelete}; - WUPSConfigAPIItemOptionsV1 options = { + WUPSConfigAPIItemOptionsV2 options = { .displayName = displayName, .context = item, .callbacks = callbacks, }; - if (WUPSConfigAPI_Item_Create(options, &item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigAPIStatus err; + if ((err = WUPSConfigAPI_Item_Create(options, &item->handle)) != WUPSCONFIG_API_RESULT_SUCCESS) { WUPSConfigItemMultipleValues_Cleanup(item); - return false; + return err; } + *outHandle = item->handle; + return WUPSCONFIG_API_RESULT_SUCCESS; +} - if (WUPSConfigAPI_Category_AddItem(cat, item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { - WUPSConfigAPI_Item_Destroy(item->handle); - return false; +extern "C" WUPSConfigAPIStatus +WUPSConfigItemMultipleValues_AddToCategory(WUPSConfigCategoryHandle cat, const char *identifier, const char *displayName, + int32_t defaultValueIndex, int currentValueIndex, + ConfigItemMultipleValuesPair *possibleValues, int pairCount, + MultipleValuesChangedCallback callback) { + WUPSConfigItemHandle itemHandle; + WUPSConfigAPIStatus res; + if ((res = WUPSConfigItemMultipleValues_Create(identifier, + displayName, + defaultValueIndex, currentValueIndex, + possibleValues, pairCount, + callback, + &itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + return res; } - return true; -} \ No newline at end of file + if ((res = WUPSConfigAPI_Category_AddItem(cat, itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigAPI_Item_Destroy(itemHandle); + return res; + } + return WUPSCONFIG_API_RESULT_SUCCESS; +} diff --git a/libraries/libwups/WUPSConfigItemMultipleValuesCpp.cpp b/libraries/libwups/WUPSConfigItemMultipleValuesCpp.cpp new file mode 100644 index 0000000..3ef19d1 --- /dev/null +++ b/libraries/libwups/WUPSConfigItemMultipleValuesCpp.cpp @@ -0,0 +1,102 @@ +#include "wups/config/WUPSConfigItemMultipleValues.h" + + +std::optional WUPSConfigItemMultipleValues::CreateFromIndex( + std::optional identifier, + std::string_view displayName, + int defaultValueIndex, int currentValueIndex, + const std::span &possibleValues, + MultipleValuesChangedCallback valuesChangedCallback, + WUPSConfigAPIStatus &err) noexcept { + auto *values = (ConfigItemMultipleValuesPair *) malloc(possibleValues.size_bytes()); + if (!values) { + err = WUPSCONFIG_API_RESULT_OUT_OF_MEMORY; + return std::nullopt; + } + int i = 0; + for (const auto &cur : possibleValues) { + values[i].value = cur.value; + values[i].valueName = cur.name.data(); + i++; + } + WUPSConfigItemHandle itemHandle; + err = WUPSConfigItemMultipleValues_Create( + identifier ? identifier->c_str() : nullptr, + displayName.data(), + defaultValueIndex, currentValueIndex, + values, (int32_t) possibleValues.size(), + valuesChangedCallback, + &itemHandle); + free(values); + if (err != WUPSCONFIG_API_RESULT_SUCCESS) { + return std::nullopt; + } + return WUPSConfigItemMultipleValues(itemHandle); +} + +WUPSConfigItemMultipleValues WUPSConfigItemMultipleValues::CreateFromIndex( + std::optional identifier, + std::string_view displayName, + int defaultValueIndex, int currentValueIndex, + const std::span &possibleValues, + MultipleValuesChangedCallback valuesChangedCallback) { + WUPSConfigAPIStatus err = WUPSCONFIG_API_RESULT_UNKNOWN_ERROR; + auto result = CreateFromIndex(std::move(identifier), displayName, defaultValueIndex, currentValueIndex, possibleValues, valuesChangedCallback, err); + if (!result) { + throw std::runtime_error(std::string("Failed to create WUPSConfigItemMultipleValues: ").append(WUPSConfigAPI_GetStatusStr(err))); + } + return std::move(*result); +} + +std::optional WUPSConfigItemMultipleValues::CreateFromValue( + std::optional identifier, + std::string_view displayName, + uint32_t defaultValue, uint32_t currentValue, + const std::span &possibleValues, + MultipleValuesChangedCallback valuesChangedCallback, + WUPSConfigAPIStatus &err) noexcept { + int defaultIndex = -1; + int currentValueIndex = -1; + int i = 0; + for (const auto &cur : possibleValues) { + if (defaultIndex != -1 && currentValueIndex != -1) { + break; + } + if (cur.value == defaultValue) { + currentValueIndex = i; + } + if (cur.value == currentValue) { + defaultIndex = i; + } + i++; + } + if (defaultIndex == -1 || currentValueIndex == -1) { + err = WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; + return std::nullopt; + } + + return WUPSConfigItemMultipleValues::CreateFromIndex(std::move(identifier), + displayName, + defaultIndex, currentValueIndex, + possibleValues, + valuesChangedCallback, + err); +} + +WUPSConfigItemMultipleValues WUPSConfigItemMultipleValues::CreateFromValue( + std::optional identifier, std::string_view displayName, + int32_t defaultValue, int32_t currentValue, + const std::span &possibleValues, + MultipleValuesChangedCallback valuesChangedCallback) { + WUPSConfigAPIStatus err = WUPSCONFIG_API_RESULT_UNKNOWN_ERROR; + auto result = CreateFromValue(std::move(identifier), + displayName, + defaultValue, currentValue, + possibleValues, + valuesChangedCallback, + err); + if (!result) { + throw std::runtime_error(std::string("Failed to create WUPSConfigItemMultipleValues (\"").append(displayName).append("\":").append(WUPSConfigAPI_GetStatusStr(err))); + } + return std::move(*result); +} diff --git a/libraries/libwups/WUPSConfigItemStub.cpp b/libraries/libwups/WUPSConfigItemStub.cpp index cef399e..c8f977d 100644 --- a/libraries/libwups/WUPSConfigItemStub.cpp +++ b/libraries/libwups/WUPSConfigItemStub.cpp @@ -1,84 +1,67 @@ #include "wups/config/WUPSConfigItemStub.h" -#include #include #include -#include -int32_t WUPSConfigItemStub_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) { +static int32_t WUPSConfigItemStub_getEmptyTextValue(void *context, char *out_buf, int32_t out_size) { memset(out_buf, 0, out_size); return 0; } -bool WUPSConfigItemStub_callCallback(void *context) { - return false; -} - -void WUPSConfigItemStub_onButtonPressed(void *context, WUPSConfigButtons buttons) { -} - -bool WUPSConfigItemStub_isMovementAllowed(void *context) { - return true; -} - -int32_t WUPSConfigItemStub_getCurrentValueSelectedDisplay(void *context, char *out_buf, int32_t out_size) { - memset(out_buf, 0, out_size); - return 0; -} - -void WUPSConfigItemStub_restoreDefault(void *context) { -} - -void WUPSConfigItemStub_onSelected(void *context, bool isSelected) { -} - -static void WUPSConfigItemStub_Cleanup(ConfigItemStub *item) { +static void WUPSConfigItemStub_Cleanup(void *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) { - return false; +extern "C" WUPSConfigAPIStatus +WUPSConfigItemStub_Create(const char *displayName, WUPSConfigItemHandle *outHandle) { + if (displayName == nullptr || outHandle == nullptr) { + return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; } auto *item = (ConfigItemStub *) malloc(sizeof(ConfigItemStub)); if (item == nullptr) { - return false; + return WUPSCONFIG_API_RESULT_OUT_OF_MEMORY; } - WUPSConfigAPIItemCallbacksV1 callbacks = { - .getCurrentValueDisplay = &WUPSConfigItemStub_getCurrentValueDisplay, - .getCurrentValueSelectedDisplay = &WUPSConfigItemStub_getCurrentValueSelectedDisplay, - .onSelected = &WUPSConfigItemStub_onSelected, - .restoreDefault = &WUPSConfigItemStub_restoreDefault, - .isMovementAllowed = &WUPSConfigItemStub_isMovementAllowed, - .callCallback = &WUPSConfigItemStub_callCallback, - .onButtonPressed = &WUPSConfigItemStub_onButtonPressed, - .onDelete = &WUPSConfigItemStub_onDelete}; + WUPSConfigAPIItemCallbacksV2 callbacks = { + .getCurrentValueDisplay = &WUPSConfigItemStub_getEmptyTextValue, + .getCurrentValueSelectedDisplay = &WUPSConfigItemStub_getEmptyTextValue, + .onSelected = nullptr, + .restoreDefault = nullptr, + .isMovementAllowed = nullptr, + .onCloseCallback = nullptr, + .onInput = nullptr, + .onInputEx = nullptr, + .onDelete = &WUPSConfigItemStub_Cleanup, + }; - WUPSConfigAPIItemOptionsV1 options = { + WUPSConfigAPIItemOptionsV2 options = { .displayName = displayName, .context = item, .callbacks = callbacks, }; - if (WUPSConfigAPI_Item_Create(options, &item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigAPIStatus err; + if ((err = WUPSConfigAPI_Item_Create(options, &item->handle)) != WUPSCONFIG_API_RESULT_SUCCESS) { WUPSConfigItemStub_Cleanup(item); - return false; + return err; } - if (WUPSConfigAPI_Category_AddItem(cat, item->handle) != WUPSCONFIG_API_RESULT_SUCCESS) { - WUPSConfigAPI_Item_Destroy(item->handle); - return false; - } - return true; + *outHandle = item->handle; + + return WUPSCONFIG_API_RESULT_SUCCESS; } -extern "C" bool WUPSConfigItemStub_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName) { - return WUPSConfigItemStub_AddToCategoryEx(cat, configID, displayName); -} +extern "C" WUPSConfigAPIStatus +WUPSConfigItemStub_AddToCategory(WUPSConfigCategoryHandle cat, const char *displayName) { + WUPSConfigItemHandle itemHandle; + WUPSConfigAPIStatus res; + if ((res = WUPSConfigItemStub_Create(displayName, + &itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + return res; + } + if ((res = WUPSConfigAPI_Category_AddItem(cat, itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + WUPSConfigAPI_Item_Destroy(itemHandle); + return res; + } + return WUPSCONFIG_API_RESULT_SUCCESS; +} \ No newline at end of file diff --git a/libraries/libwups/WUPSConfigItemStubCpp.cpp b/libraries/libwups/WUPSConfigItemStubCpp.cpp new file mode 100644 index 0000000..1279712 --- /dev/null +++ b/libraries/libwups/WUPSConfigItemStubCpp.cpp @@ -0,0 +1,20 @@ +#include "wups/config/WUPSConfigItemStub.h" + +std::optional WUPSConfigItemStub::Create(std::string_view displayName, + WUPSConfigAPIStatus &err) noexcept { + WUPSConfigItemHandle itemHandle; + if ((err = WUPSConfigItemStub_Create(displayName.data(), + &itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) { + return std::nullopt; + } + return WUPSConfigItemStub(itemHandle); +} + +WUPSConfigItemStub WUPSConfigItemStub::Create(std::string_view displayName) { + WUPSConfigAPIStatus err = WUPSCONFIG_API_RESULT_UNKNOWN_ERROR; + auto result = Create(displayName, err); + if (!result) { + throw std::runtime_error(std::string("Failed to create WUPSConfigItemStub: ").append(WUPSConfigAPI_GetStatusStr(err))); + } + return std::move(*result); +} diff --git a/libraries/libwups/config_api.cpp b/libraries/libwups/config_api.cpp index d5c5c25..1fdbc76 100644 --- a/libraries/libwups/config_api.cpp +++ b/libraries/libwups/config_api.cpp @@ -1,5 +1,5 @@ #include "wups/config_api.h" -#include "wups.h" +#include "wups/wups_debug.h" #include #include