ButtonComboApi: Use C++ APIs where possible

This commit is contained in:
Maschell 2025-01-01 15:04:42 +01:00
parent bebae31682
commit d0be5e4b88
6 changed files with 59 additions and 75 deletions

View File

@ -9,7 +9,7 @@
#include "utils/logger.h" #include "utils/logger.h"
#include "utils/storage/StorageUtils.h" #include "utils/storage/StorageUtils.h"
#include <wups/button_combo.h> #include <wups/button_combo/api.h>
#include <wups/button_combo_internal.h> #include <wups/button_combo_internal.h>
#include <wups/storage.h> #include <wups/storage.h>
@ -159,7 +159,7 @@ void CallHook(const PluginContainer &plugin, wups_loader_hook_type_t hook_type)
// clang-format on // clang-format on
if (res != WUPS_BUTTON_COMBO_ERROR_SUCCESS) { if (res != WUPS_BUTTON_COMBO_ERROR_SUCCESS) {
// TODO: More error handling? Notification? // TODO: More error handling? Notification?
DEBUG_FUNCTION_LINE_ERR("WUPS_LOADER_HOOK_INIT_BUTTON_COMBO failed for plugin %s: %s", plugin.getMetaInformation().getName().c_str(), WUPSButtonComboAPI_GetStatusStr(res)); DEBUG_FUNCTION_LINE_ERR("WUPS_LOADER_HOOK_INIT_BUTTON_COMBO failed for plugin %s: %s", plugin.getMetaInformation().getName().c_str(), WUPSButtonComboAPI::GetStatusStr(res));
} }
break; break;
} }

View File

@ -17,7 +17,7 @@
#include "utils/logger.h" #include "utils/logger.h"
#include "utils/utils.h" #include "utils/utils.h"
#include <buttoncombo/manager.h> #include <buttoncombo/api.h>
#include <function_patcher/function_patching.h> #include <function_patcher/function_patching.h>
#include <notifications/notification_defines.h> #include <notifications/notification_defines.h>
#include <notifications/notifications.h> #include <notifications/notifications.h>

View File

@ -2,10 +2,13 @@
#include "utils/logger.h" #include "utils/logger.h"
#include "utils/utils.h" #include "utils/utils.h"
#include <buttoncombo/manager.h> #include <buttoncombo/api.h>
#include <buttoncombo/defines.h>
#include <wups/button_combo_internal.h> #include <wups/button_combo_internal.h>
#include <optional>
namespace { namespace {
WUPSButtonCombo_Error convertError(const ButtonComboModule_Error other) { WUPSButtonCombo_Error convertError(const ButtonComboModule_Error other) {
switch (other) { switch (other) {
@ -304,66 +307,49 @@ namespace {
void *context = nullptr; void *context = nullptr;
}; };
void ButtonComboCallbackWrapper(const ButtonComboModule_ComboHandle handle, void *context) { void ButtonComboCallbackWrapper(const ButtonComboModule_ControllerTypes triggeredBy, const ButtonComboModule_ComboHandle handle, void *context) {
const auto *data = static_cast<ComboCallbackWrapperData *>(context); const auto *data = static_cast<ComboCallbackWrapperData *>(context);
data->callback(WUPSButtonCombo_ComboHandle(handle.handle), data->context); data->callback(convert(triggeredBy), WUPSButtonCombo_ComboHandle(handle.handle), data->context);
} }
} // namespace } // namespace
class ButtonComboWrapper { class ButtonComboWrapper {
public: public:
ButtonComboWrapper(const WUPSButtonCombo_ComboOptions &otherOptions, WUPSButtonCombo_ComboStatus &outStatus) { static std::optional<ButtonComboWrapper> Create(const WUPSButtonCombo_ComboOptions &otherOptions, WUPSButtonCombo_ComboStatus &outStatus, WUPSButtonCombo_Error &outError) {
// Abuse this as a stable handle that references itself and survives std::move
*mHandle = reinterpret_cast<uint32_t>(mHandle.get());
ButtonComboModule_ComboStatus status = BUTTON_COMBO_MODULE_COMBO_STATUS_INVALID_STATUS; ButtonComboModule_ComboStatus status = BUTTON_COMBO_MODULE_COMBO_STATUS_INVALID_STATUS;
mContextData = std::make_unique<ComboCallbackWrapperData>(otherOptions.callbackOptions.callback, otherOptions.callbackOptions.context); auto contextData = std::make_unique<ComboCallbackWrapperData>(otherOptions.callbackOptions.callback, otherOptions.callbackOptions.context);
ButtonComboModule_ComboOptions convertedOptions; ButtonComboModule_ComboOptions convertedOptions;
convertedOptions.version = BUTTON_COMBO_MODULE_COMBO_OPTIONS_VERSION; convertedOptions.version = BUTTON_COMBO_MODULE_COMBO_OPTIONS_VERSION;
convertedOptions.metaOptions = convert(otherOptions.metaOptions); convertedOptions.metaOptions = convert(otherOptions.metaOptions);
convertedOptions.callbackOptions = {.callback = ButtonComboCallbackWrapper, .context = mContextData.get()}; convertedOptions.callbackOptions = {.callback = ButtonComboCallbackWrapper, .context = contextData.get()};
convertedOptions.buttonComboOptions = convert(otherOptions.buttonComboOptions); convertedOptions.buttonComboOptions = convert(otherOptions.buttonComboOptions);
mCreationError = ButtonComboModule_AddButtonCombo(&convertedOptions, &mButtonComboHandle, &status);
outStatus = convertStatus(status);
}
~ButtonComboWrapper() { ButtonComboModule_Error err;
ReleaseButtonComboHandle(); auto res = ButtonComboModule::ButtonCombo::Create(convertedOptions, status, err);
}
void ReleaseButtonComboHandle() { outError = convertError(err);
if (mButtonComboHandle != nullptr) { outStatus = convertStatus(status);
if (const auto res = ButtonComboModule_RemoveButtonCombo(mButtonComboHandle); res != BUTTON_COMBO_MODULE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_WARN("ButtonComboModule_RemoveButtonCombo for %08X returned: %s", mButtonComboHandle, ButtonComboModule_GetStatusStr(res)); if (!res || err != BUTTON_COMBO_MODULE_ERROR_SUCCESS) {
} return {};
mButtonComboHandle = ButtonComboModule_ComboHandle(nullptr);
} }
return ButtonComboWrapper(std::move(*res), std::move(contextData));
} }
ButtonComboWrapper(const ButtonComboWrapper &) = delete; ButtonComboWrapper(const ButtonComboWrapper &) = delete;
ButtonComboWrapper &operator=(ButtonComboWrapper &src) = delete; ButtonComboWrapper &operator=(ButtonComboWrapper &src) = delete;
ButtonComboWrapper(ButtonComboWrapper &&src) noexcept : mCreationError(src.mCreationError), ButtonComboWrapper(ButtonComboWrapper &&src) noexcept : mButtonComboModuleCombo(std::move(src.mButtonComboModuleCombo)),
mContextData(std::move(src.mContextData)), mContextData(std::move(src.mContextData)),
mHandle(std::move(src.mHandle)) { mHandle(std::move(src.mHandle)) {
ReleaseButtonComboHandle();
mButtonComboHandle = ButtonComboModule_ComboHandle(src.mButtonComboHandle.handle);
src.mCreationError = BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR;
src.mButtonComboHandle = ButtonComboModule_ComboHandle(nullptr);
} }
ButtonComboWrapper &operator=(ButtonComboWrapper &&src) noexcept { ButtonComboWrapper &operator=(ButtonComboWrapper &&src) noexcept {
if (this != &src) { if (this != &src) {
ReleaseButtonComboHandle(); this->mButtonComboModuleCombo = std::move(src.mButtonComboModuleCombo);
this->mCreationError = src.mCreationError; this->mContextData = std::move(src.mContextData);
this->mButtonComboHandle = ButtonComboModule_ComboHandle(src.mButtonComboHandle.handle); this->mHandle = std::move(src.mHandle);
this->mContextData = std::move(src.mContextData);
this->mHandle = std::move(src.mHandle);
src.mCreationError = BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR;
src.mButtonComboHandle = ButtonComboModule_ComboHandle(nullptr);
} }
return *this; return *this;
} }
@ -374,7 +360,7 @@ public:
WUPSButtonCombo_Error GetButtonComboStatus(WUPSButtonCombo_ComboStatus &outStatus) const { WUPSButtonCombo_Error GetButtonComboStatus(WUPSButtonCombo_ComboStatus &outStatus) const {
ButtonComboModule_ComboStatus status = BUTTON_COMBO_MODULE_COMBO_STATUS_INVALID_STATUS; ButtonComboModule_ComboStatus status = BUTTON_COMBO_MODULE_COMBO_STATUS_INVALID_STATUS;
const auto res = ButtonComboModule_GetButtonComboStatus(mButtonComboHandle, &status); const auto res = mButtonComboModuleCombo.GetButtonComboStatus(status);
if (res == BUTTON_COMBO_MODULE_ERROR_SUCCESS) { if (res == BUTTON_COMBO_MODULE_ERROR_SUCCESS) {
outStatus = convertStatus(status); outStatus = convertStatus(status);
} }
@ -383,7 +369,7 @@ public:
[[nodiscard]] WUPSButtonCombo_Error UpdateButtonComboMeta(const WUPSButtonCombo_MetaOptions &metaOptions) const { [[nodiscard]] WUPSButtonCombo_Error UpdateButtonComboMeta(const WUPSButtonCombo_MetaOptions &metaOptions) const {
const auto convertedOptions = convert(metaOptions); const auto convertedOptions = convert(metaOptions);
return convertError(ButtonComboModule_UpdateButtonComboMeta(mButtonComboHandle, &convertedOptions)); return convertError(mButtonComboModuleCombo.UpdateButtonComboMeta(convertedOptions));
} }
[[nodiscard]] WUPSButtonCombo_Error UpdateButtonComboCallback(const WUPSButtonCombo_CallbackOptions &callbackOptions) const { [[nodiscard]] WUPSButtonCombo_Error UpdateButtonComboCallback(const WUPSButtonCombo_CallbackOptions &callbackOptions) const {
@ -395,7 +381,7 @@ public:
[[nodiscard]] WUPSButtonCombo_Error UpdateControllerMask(const WUPSButtonCombo_ControllerTypes controllerMask, [[nodiscard]] WUPSButtonCombo_Error UpdateControllerMask(const WUPSButtonCombo_ControllerTypes controllerMask,
WUPSButtonCombo_ComboStatus &outStatus) const { WUPSButtonCombo_ComboStatus &outStatus) const {
ButtonComboModule_ComboStatus comboStatus = BUTTON_COMBO_MODULE_COMBO_STATUS_INVALID_STATUS; ButtonComboModule_ComboStatus comboStatus = BUTTON_COMBO_MODULE_COMBO_STATUS_INVALID_STATUS;
const auto res = convertError(ButtonComboModule_UpdateControllerMask(mButtonComboHandle, convert(controllerMask), &comboStatus)); const auto res = convertError(mButtonComboModuleCombo.UpdateControllerMask(convert(controllerMask), comboStatus));
outStatus = convertStatus(comboStatus); outStatus = convertStatus(comboStatus);
return res; return res;
} }
@ -403,18 +389,18 @@ public:
[[nodiscard]] WUPSButtonCombo_Error UpdateButtonCombo(const WUPSButtonCombo_Buttons combo, [[nodiscard]] WUPSButtonCombo_Error UpdateButtonCombo(const WUPSButtonCombo_Buttons combo,
WUPSButtonCombo_ComboStatus &outStatus) const { WUPSButtonCombo_ComboStatus &outStatus) const {
ButtonComboModule_ComboStatus comboStatus = BUTTON_COMBO_MODULE_COMBO_STATUS_INVALID_STATUS; ButtonComboModule_ComboStatus comboStatus = BUTTON_COMBO_MODULE_COMBO_STATUS_INVALID_STATUS;
const auto res = convertError(ButtonComboModule_UpdateButtonCombo(mButtonComboHandle, convert(combo), &comboStatus)); const auto res = convertError(mButtonComboModuleCombo.UpdateButtonCombo(convert(combo), comboStatus));
outStatus = convertStatus(comboStatus); outStatus = convertStatus(comboStatus);
return res; return res;
} }
[[nodiscard]] WUPSButtonCombo_Error UpdateHoldDuration(const uint32_t holdDurationInMs) const { [[nodiscard]] WUPSButtonCombo_Error UpdateHoldDuration(const uint32_t holdDurationInMs) const {
return convertError(ButtonComboModule_UpdateHoldDuration(mButtonComboHandle, holdDurationInMs)); return convertError(mButtonComboModuleCombo.UpdateHoldDuration(holdDurationInMs));
} }
[[nodiscard]] WUPSButtonCombo_Error GetButtonComboMeta(WUPSButtonCombo_MetaOptionsOut &outOptions) const { [[nodiscard]] WUPSButtonCombo_Error GetButtonComboMeta(WUPSButtonCombo_MetaOptionsOut &outOptions) const {
ButtonComboModule_MetaOptionsOut options = {.labelBuffer = outOptions.labelBuffer, .labelBufferLength = outOptions.labelBufferLength}; ButtonComboModule_MetaOptionsOut options = {.labelBuffer = outOptions.labelBuffer, .labelBufferLength = outOptions.labelBufferLength};
return convertError(ButtonComboModule_GetButtonComboMeta(mButtonComboHandle, &options)); return convertError(mButtonComboModuleCombo.GetButtonComboMeta(options));
} }
WUPSButtonCombo_Error GetButtonComboCallback(WUPSButtonCombo_CallbackOptions &outOptions) const { WUPSButtonCombo_Error GetButtonComboCallback(WUPSButtonCombo_CallbackOptions &outOptions) const {
@ -426,18 +412,19 @@ public:
WUPSButtonCombo_Error GetButtonComboInfoEx(WUPSButtonCombo_ButtonComboInfoEx &outOptions) const { WUPSButtonCombo_Error GetButtonComboInfoEx(WUPSButtonCombo_ButtonComboInfoEx &outOptions) const {
ButtonComboModule_ButtonComboInfoEx tmpOptions; ButtonComboModule_ButtonComboInfoEx tmpOptions;
const auto res = convertError(ButtonComboModule_GetButtonComboInfoEx(mButtonComboHandle, &tmpOptions)); const auto res = convertError(mButtonComboModuleCombo.GetButtonComboInfoEx(tmpOptions));
outOptions = convert(tmpOptions); outOptions = convert(tmpOptions);
return res; return res;
} }
WUPSButtonCombo_Error GetCreationError() const { private:
return convertError(mCreationError); ButtonComboWrapper(ButtonComboModule::ButtonCombo combo, std::unique_ptr<ComboCallbackWrapperData> contextData) : mButtonComboModuleCombo(std::move(combo)),
mContextData(std::move(contextData)) {
// Abuse this as a stable handle that references itself and survives std::move
*mHandle = reinterpret_cast<uint32_t>(mHandle.get());
} }
private: ButtonComboModule::ButtonCombo mButtonComboModuleCombo;
ButtonComboModule_Error mCreationError;
ButtonComboModule_ComboHandle mButtonComboHandle;
std::unique_ptr<ComboCallbackWrapperData> mContextData; std::unique_ptr<ComboCallbackWrapperData> mContextData;
std::unique_ptr<uint32_t> mHandle = std::make_unique<uint32_t>(); std::unique_ptr<uint32_t> mHandle = std::make_unique<uint32_t>();
}; };
@ -463,17 +450,15 @@ ButtonComboManager &ButtonComboManager::operator=(ButtonComboManager &&src) {
WUPSButtonCombo_Error ButtonComboManager::AddButtonComboHandle(const WUPSButtonCombo_ComboOptions &options, WUPSButtonCombo_Error ButtonComboManager::AddButtonComboHandle(const WUPSButtonCombo_ComboOptions &options,
WUPSButtonCombo_ComboHandle &outHandle, WUPSButtonCombo_ComboHandle &outHandle,
WUPSButtonCombo_ComboStatus &outStatus) { WUPSButtonCombo_ComboStatus &outStatus) {
mComboWrappers.emplace_front(options, outStatus); WUPSButtonCombo_Error err = WUPS_BUTTON_COMBO_ERROR_UNKNOWN_ERROR;
const auto &addedItem = mComboWrappers.front(); auto comboOpt = ButtonComboWrapper::Create(options, outStatus, err);
const auto handle = addedItem.getHandle(); if (!comboOpt || err != WUPS_BUTTON_COMBO_ERROR_SUCCESS) {
if (const auto res = addedItem.GetCreationError(); res != WUPS_BUTTON_COMBO_ERROR_SUCCESS) { return err;
if (!remove_first_if(mComboWrappers, [&handle](const auto &comboWrapper) { return comboWrapper.getHandle() == handle; })) {
DEBUG_FUNCTION_LINE_INFO("Failed to re removed from mComboWrappers");
}
return res;
} }
outHandle = handle; outHandle = comboOpt->getHandle();
mComboWrappers.emplace_front(std::move(*comboOpt));
return WUPS_BUTTON_COMBO_ERROR_SUCCESS; return WUPS_BUTTON_COMBO_ERROR_SUCCESS;
} }
@ -557,7 +542,7 @@ WUPSButtonCombo_Error ButtonComboManager::CheckComboAvailable(const WUPSButtonCo
WUPSButtonCombo_ComboStatus &outStatus) { WUPSButtonCombo_ComboStatus &outStatus) {
const auto convertedOptions = convert(options); const auto convertedOptions = convert(options);
ButtonComboModule_ComboStatus status = BUTTON_COMBO_MODULE_COMBO_STATUS_INVALID_STATUS; ButtonComboModule_ComboStatus status = BUTTON_COMBO_MODULE_COMBO_STATUS_INVALID_STATUS;
const auto res = convertError(ButtonComboModule_CheckComboAvailable(&convertedOptions, &status)); const auto res = convertError(ButtonComboModule::CheckComboAvailable(convertedOptions, status));
outStatus = convertStatus(status); outStatus = convertStatus(status);
return res; return res;
} }
@ -565,7 +550,7 @@ WUPSButtonCombo_Error ButtonComboManager::CheckComboAvailable(const WUPSButtonCo
WUPSButtonCombo_Error ButtonComboManager::DetectButtonCombo_Blocking(const WUPSButtonCombo_DetectButtonComboOptions &options, WUPSButtonCombo_Buttons &outButtonCombo) { WUPSButtonCombo_Error ButtonComboManager::DetectButtonCombo_Blocking(const WUPSButtonCombo_DetectButtonComboOptions &options, WUPSButtonCombo_Buttons &outButtonCombo) {
const auto convertedOptions = convert(options); const auto convertedOptions = convert(options);
auto combo = static_cast<ButtonComboModule_Buttons>(0); auto combo = static_cast<ButtonComboModule_Buttons>(0);
const auto res = convertError(ButtonComboModule_DetectButtonCombo_Blocking(&convertedOptions, &combo)); const auto res = convertError(ButtonComboModule::DetectButtonCombo_Blocking(convertedOptions, combo));
outButtonCombo = convert(combo); outButtonCombo = convert(combo);
return res; return res;
} }

View File

@ -1,8 +1,6 @@
#pragma once #pragma once
#include <buttoncombo/defines.h> #include <wups/button_combo/defines.h>
#include <wups/button_combo.h>
#include <functional> #include <functional>
#include <memory> #include <memory>
@ -10,7 +8,6 @@
#include <cstdint> #include <cstdint>
#include <forward_list> #include <forward_list>
class ButtonComboWrapper; class ButtonComboWrapper;
class ButtonComboManager { class ButtonComboManager {
@ -60,11 +57,11 @@ public:
WUPSButtonCombo_Error GetButtonComboInfoEx(WUPSButtonCombo_ComboHandle handle, WUPSButtonCombo_Error GetButtonComboInfoEx(WUPSButtonCombo_ComboHandle handle,
WUPSButtonCombo_ButtonComboInfoEx &outOptions); WUPSButtonCombo_ButtonComboInfoEx &outOptions);
WUPSButtonCombo_Error CheckComboAvailable(const WUPSButtonCombo_ButtonComboOptions &options, static WUPSButtonCombo_Error CheckComboAvailable(const WUPSButtonCombo_ButtonComboOptions &options,
WUPSButtonCombo_ComboStatus &outStatus); WUPSButtonCombo_ComboStatus &outStatus);
WUPSButtonCombo_Error DetectButtonCombo_Blocking(const WUPSButtonCombo_DetectButtonComboOptions &options, static WUPSButtonCombo_Error DetectButtonCombo_Blocking(const WUPSButtonCombo_DetectButtonComboOptions &options,
WUPSButtonCombo_Buttons &outButtonCombo); WUPSButtonCombo_Buttons &outButtonCombo);
WUPSButtonCombo_Error ExecuteForWrapper(const WUPSButtonCombo_ComboHandle &handle, const std::function<WUPSButtonCombo_Error(ButtonComboWrapper &)> &callback); WUPSButtonCombo_Error ExecuteForWrapper(const WUPSButtonCombo_ComboHandle &handle, const std::function<WUPSButtonCombo_Error(ButtonComboWrapper &)> &callback);

View File

@ -182,9 +182,10 @@ namespace ButtonComboUtils::API {
if (outStatus == nullptr) { if (outStatus == nullptr) {
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS; return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
} }
// CheckComboAvailable is a static function, but we still want to make sure the identifier is valid
return ExecuteForIdentifierLocked(identifier, return ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) { [&](ButtonComboManager &) {
return manager.CheckComboAvailable(*options, *outStatus); return ButtonComboManager::CheckComboAvailable(*options, *outStatus);
}); });
} }
WUPSButtonCombo_Error DetectButtonCombo_Blocking(void *identifier, WUPSButtonCombo_Error DetectButtonCombo_Blocking(void *identifier,
@ -193,9 +194,10 @@ namespace ButtonComboUtils::API {
if (options == nullptr || outButtonCombo == nullptr) { if (options == nullptr || outButtonCombo == nullptr) {
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS; return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
} }
// DetectButtonCombo_Blocking is a static function, but we still want to make sure the identifier is valid
return ExecuteForIdentifierLocked(identifier, return ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) { [&](ButtonComboManager &) {
return manager.DetectButtonCombo_Blocking(*options, *outButtonCombo); return ButtonComboManager::DetectButtonCombo_Blocking(*options, *outButtonCombo);
}); });
} }
} // namespace ButtonComboUtils::API } // namespace ButtonComboUtils::API

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <wups/button_combo.h> #include <wups/button_combo/defines.h>
#include <cstdint> #include <cstdint>