mirror of
https://github.com/wiiu-env/WiiUPluginLoaderBackend.git
synced 2025-01-10 11:39:23 +01:00
203 lines
11 KiB
C++
203 lines
11 KiB
C++
#include "ButtonComboUtils.h"
|
|
|
|
#include "plugin/ButtonComboManager.h"
|
|
#include "plugin/PluginContainer.h"
|
|
#include "utils/logger.h"
|
|
#include "utils/utils.h"
|
|
|
|
#include <forward_list>
|
|
#include <mutex>
|
|
|
|
namespace ButtonComboUtils::API {
|
|
static std::forward_list<ButtonComboManager> sButtonComboManager;
|
|
static std::mutex sButtonComboMutex;
|
|
|
|
namespace Internal {
|
|
uint32_t CreateButtonComboData() {
|
|
std::lock_guard lock(sButtonComboMutex);
|
|
sButtonComboManager.emplace_front();
|
|
return sButtonComboManager.front().getHandle();
|
|
}
|
|
|
|
void RemoveButtonComboData(uint32_t buttonComboManagerHandle) {
|
|
if (!remove_locked_first_if(sButtonComboMutex, sButtonComboManager, [buttonComboManagerHandle](const ButtonComboManager &buttonComboData) { return buttonComboData.getHandle() == buttonComboManagerHandle; })) {
|
|
DEBUG_FUNCTION_LINE_WARN("Tried to remove ButtonComboManager by invalid handle: %08X", buttonComboManagerHandle);
|
|
}
|
|
}
|
|
} // namespace Internal
|
|
|
|
namespace {
|
|
WUPSButtonCombo_Error ExecuteForIdentifierLocked(void *identifier, const std::function<WUPSButtonCombo_Error(ButtonComboManager &)> &callback) {
|
|
if (identifier == nullptr) {
|
|
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
|
|
}
|
|
std::lock_guard lock(sButtonComboMutex);
|
|
for (auto &manager : sButtonComboManager) {
|
|
if (manager.getHandle() == reinterpret_cast<uint32_t>(identifier)) {
|
|
return callback(manager);
|
|
}
|
|
}
|
|
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
|
|
}
|
|
} // namespace
|
|
|
|
WUPSButtonCombo_Error AddButtonCombo(void *identifier,
|
|
const WUPSButtonCombo_ComboOptions *options,
|
|
WUPSButtonCombo_ComboHandle *outHandle,
|
|
WUPSButtonCombo_ComboStatus *outStatus) {
|
|
if (options == nullptr || outHandle == nullptr) {
|
|
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
|
|
}
|
|
WUPSButtonCombo_ComboStatus tmpStatus;
|
|
const auto res = ExecuteForIdentifierLocked(identifier,
|
|
[&](ButtonComboManager &manager) {
|
|
return manager.AddButtonComboHandle(*options, *outHandle, tmpStatus);
|
|
});
|
|
if (outStatus) { *outStatus = tmpStatus; }
|
|
return res;
|
|
}
|
|
|
|
WUPSButtonCombo_Error RemoveButtonCombo(void *identifier,
|
|
const WUPSButtonCombo_ComboHandle handle) {
|
|
if (identifier == nullptr || handle == nullptr) {
|
|
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
|
|
}
|
|
return ExecuteForIdentifierLocked(identifier,
|
|
[&](ButtonComboManager &manager) {
|
|
return manager.RemoveButtonCombo(handle);
|
|
});
|
|
}
|
|
|
|
WUPSButtonCombo_Error GetButtonComboStatus(void *identifier,
|
|
const WUPSButtonCombo_ComboHandle handle,
|
|
WUPSButtonCombo_ComboStatus *outStatus) {
|
|
if (identifier == nullptr || handle == nullptr || outStatus == nullptr) {
|
|
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
|
|
}
|
|
return ExecuteForIdentifierLocked(identifier,
|
|
[&](ButtonComboManager &manager) {
|
|
return manager.GetButtonComboStatus(handle, *outStatus);
|
|
});
|
|
}
|
|
|
|
WUPSButtonCombo_Error UpdateButtonComboMeta(void *identifier,
|
|
const WUPSButtonCombo_ComboHandle handle,
|
|
const WUPSButtonCombo_MetaOptions *metaOptions) {
|
|
if (metaOptions == nullptr) {
|
|
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
|
|
}
|
|
return ExecuteForIdentifierLocked(identifier,
|
|
[&](ButtonComboManager &manager) {
|
|
return manager.UpdateButtonComboMeta(handle, *metaOptions);
|
|
});
|
|
}
|
|
|
|
WUPSButtonCombo_Error UpdateButtonComboCallback(void *identifier,
|
|
const WUPSButtonCombo_ComboHandle handle,
|
|
const WUPSButtonCombo_CallbackOptions *callbackOptions) {
|
|
if (callbackOptions == nullptr) {
|
|
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
|
|
}
|
|
return ExecuteForIdentifierLocked(identifier,
|
|
[&](ButtonComboManager &manager) {
|
|
return manager.UpdateButtonComboCallback(handle, *callbackOptions);
|
|
});
|
|
}
|
|
|
|
WUPSButtonCombo_Error UpdateControllerMask(void *identifier,
|
|
const WUPSButtonCombo_ComboHandle handle,
|
|
const WUPSButtonCombo_ControllerTypes controllerMask,
|
|
WUPSButtonCombo_ComboStatus *outStatus) {
|
|
WUPSButtonCombo_ComboStatus tmpStatus;
|
|
const auto res = ExecuteForIdentifierLocked(identifier,
|
|
[&](ButtonComboManager &manager) {
|
|
return manager.UpdateControllerMask(handle, controllerMask, tmpStatus);
|
|
});
|
|
if (outStatus) { *outStatus = tmpStatus; }
|
|
return res;
|
|
}
|
|
|
|
WUPSButtonCombo_Error UpdateButtonCombo(void *identifier,
|
|
const WUPSButtonCombo_ComboHandle handle,
|
|
const WUPSButtonCombo_Buttons combo,
|
|
WUPSButtonCombo_ComboStatus *outStatus) {
|
|
WUPSButtonCombo_ComboStatus tmpStatus;
|
|
const auto res = ExecuteForIdentifierLocked(identifier,
|
|
[&](ButtonComboManager &manager) {
|
|
return manager.UpdateButtonCombo(handle, combo, tmpStatus);
|
|
});
|
|
if (outStatus) { *outStatus = tmpStatus; }
|
|
return res;
|
|
}
|
|
|
|
WUPSButtonCombo_Error UpdateHoldDuration(void *identifier,
|
|
const WUPSButtonCombo_ComboHandle handle,
|
|
const uint32_t holdDurationInMs) {
|
|
const auto res = ExecuteForIdentifierLocked(identifier,
|
|
[&](ButtonComboManager &manager) {
|
|
return manager.UpdateHoldDuration(handle, holdDurationInMs);
|
|
});
|
|
return res;
|
|
}
|
|
|
|
WUPSButtonCombo_Error GetButtonComboMeta(void *identifier,
|
|
const WUPSButtonCombo_ComboHandle handle,
|
|
WUPSButtonCombo_MetaOptionsOut *outOptions) {
|
|
if (outOptions == nullptr) {
|
|
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
|
|
}
|
|
return ExecuteForIdentifierLocked(identifier,
|
|
[&](ButtonComboManager &manager) {
|
|
return manager.GetButtonComboMeta(handle, *outOptions);
|
|
});
|
|
}
|
|
WUPSButtonCombo_Error GetButtonComboCallback(void *identifier,
|
|
const WUPSButtonCombo_ComboHandle handle,
|
|
WUPSButtonCombo_CallbackOptions *outOptions) {
|
|
|
|
if (outOptions == nullptr) {
|
|
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
|
|
}
|
|
return ExecuteForIdentifierLocked(identifier,
|
|
[&](ButtonComboManager &manager) {
|
|
return manager.GetButtonComboCallback(handle, *outOptions);
|
|
});
|
|
}
|
|
|
|
WUPSButtonCombo_Error GetButtonComboInfoEx(void *identifier,
|
|
const WUPSButtonCombo_ComboHandle handle,
|
|
WUPSButtonCombo_ButtonComboInfoEx *outOptions) {
|
|
if (outOptions == nullptr) {
|
|
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
|
|
}
|
|
return ExecuteForIdentifierLocked(identifier,
|
|
[&](ButtonComboManager &manager) {
|
|
return manager.GetButtonComboInfoEx(handle, *outOptions);
|
|
});
|
|
}
|
|
|
|
WUPSButtonCombo_Error CheckComboAvailable(void *identifier,
|
|
const WUPSButtonCombo_ButtonComboOptions *options,
|
|
WUPSButtonCombo_ComboStatus *outStatus) {
|
|
if (outStatus == nullptr) {
|
|
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,
|
|
[&](ButtonComboManager &) {
|
|
return ButtonComboManager::CheckComboAvailable(*options, *outStatus);
|
|
});
|
|
}
|
|
WUPSButtonCombo_Error DetectButtonCombo_Blocking(void *identifier,
|
|
const WUPSButtonCombo_DetectButtonComboOptions *options,
|
|
WUPSButtonCombo_Buttons *outButtonCombo) {
|
|
if (options == nullptr || outButtonCombo == nullptr) {
|
|
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,
|
|
[&](ButtonComboManager &) {
|
|
return ButtonComboManager::DetectButtonCombo_Blocking(*options, *outButtonCombo);
|
|
});
|
|
}
|
|
} // namespace ButtonComboUtils::API
|