mirror of
https://github.com/wiiu-env/WiiUPluginLoaderBackend.git
synced 2026-08-23 11:24:34 -05:00
Rewrite the plugin backend, use smart pointers is possible, don't persist in structs and simplify code
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include "../config/WUPSConfig.h"
|
||||
#include "../globals.h"
|
||||
#include "DrawUtils.h"
|
||||
#include "hooks.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <coreinit/screen.h>
|
||||
@@ -118,24 +119,20 @@ static uint32_t remapClassicButtons(uint32_t buttons) {
|
||||
|
||||
void ConfigUtils::displayMenu() {
|
||||
std::vector<ConfigDisplayItem> configs;
|
||||
for (int32_t plugin_index = 0; plugin_index < gPluginInformation->number_used_plugins; plugin_index++) {
|
||||
plugin_information_single_t *plugin_data = &gPluginInformation->plugin_data[plugin_index];
|
||||
if (plugin_data == nullptr) {
|
||||
continue;
|
||||
}
|
||||
for (auto &plugin : gLoadedPlugins) {
|
||||
ConfigDisplayItem cfg;
|
||||
cfg.name = std::string(plugin_data->meta.name);
|
||||
cfg.author = std::string(plugin_data->meta.author);
|
||||
cfg.version = std::string(plugin_data->meta.version);
|
||||
cfg.name = plugin->metaInformation->getName();
|
||||
cfg.author = plugin->metaInformation->getAuthor();
|
||||
cfg.version = plugin->metaInformation->getVersion();
|
||||
cfg.enabled = true;
|
||||
|
||||
for (uint32_t j = 0; j < plugin_data->info.number_used_hooks; j++) {
|
||||
replacement_data_hook_t *hook_data = &plugin_data->info.hooks[j];
|
||||
if (hook_data->type == WUPS_LOADER_HOOK_GET_CONFIG /*WUPS_LOADER_HOOK_GET_CONFIG*/) {
|
||||
if (hook_data->func_pointer == nullptr) {
|
||||
for (auto &hook : plugin->getPluginInformation()->getHookDataList()) {
|
||||
|
||||
if (hook->getType() == WUPS_LOADER_HOOK_GET_CONFIG /*WUPS_LOADER_HOOK_GET_CONFIG*/) {
|
||||
if (hook->getFunctionPointer() == nullptr) {
|
||||
break;
|
||||
}
|
||||
auto *cur_config = reinterpret_cast<WUPSConfig *>(((WUPSConfigHandle(*)())((uint32_t *) hook_data->func_pointer))());
|
||||
auto *cur_config = reinterpret_cast<WUPSConfig *>(((WUPSConfigHandle(*)())((uint32_t *) hook->getFunctionPointer()))());
|
||||
if (cur_config == nullptr) {
|
||||
break;
|
||||
}
|
||||
@@ -509,8 +506,7 @@ void ConfigUtils::displayMenu() {
|
||||
|
||||
DrawUtils::setFontColor(COLOR_TEXT);
|
||||
|
||||
std::string headline;
|
||||
StringTools::strprintf(headline, "%s - %s", currentConfig->config->getName().c_str(), currentCategory->getName().c_str());
|
||||
auto headline = string_format("%s - %s", currentConfig->config->getName().c_str(), currentCategory->getName().c_str());
|
||||
// draw top bar
|
||||
DrawUtils::setFontSize(24);
|
||||
DrawUtils::print(16, 6 + 24, headline.c_str());
|
||||
@@ -553,25 +549,7 @@ void ConfigUtils::displayMenu() {
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t plugin_index = 0; plugin_index < gPluginInformation->number_used_plugins; plugin_index++) {
|
||||
plugin_information_single_t *plugin_data = &gPluginInformation->plugin_data[plugin_index];
|
||||
if (plugin_data == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (uint32_t j = 0; j < plugin_data->info.number_used_hooks; j++) {
|
||||
replacement_data_hook_t *hook_data = &plugin_data->info.hooks[j];
|
||||
if (hook_data->type == WUPS_LOADER_HOOK_CONFIG_CLOSED) {
|
||||
if (hook_data->func_pointer == nullptr) {
|
||||
break;
|
||||
}
|
||||
// clang-format off
|
||||
((void(*)())((uint32_t *) hook_data->func_pointer))();
|
||||
// clang-format on
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
CallHook(gLoadedPlugins, WUPS_LOADER_HOOK_CONFIG_CLOSED);
|
||||
|
||||
for (const auto &element : configs) {
|
||||
DEBUG_FUNCTION_LINE("Delete %08X", element.config);
|
||||
@@ -594,15 +572,15 @@ void ConfigUtils::openConfigMenu() {
|
||||
|
||||
if (!screenbuffer0 || !screenbuffer1) {
|
||||
if (screenbuffer0 == nullptr) {
|
||||
if (storedTVBuffer.buffer_size >= screen_buf0_size) {
|
||||
screenbuffer0 = storedTVBuffer.buffer;
|
||||
if (gStoredTVBuffer.buffer_size >= screen_buf0_size) {
|
||||
screenbuffer0 = gStoredTVBuffer.buffer;
|
||||
skipScreen0Free = true;
|
||||
DEBUG_FUNCTION_LINE_VERBOSE("Use storedTVBuffer");
|
||||
}
|
||||
}
|
||||
if (screenbuffer1 == nullptr) {
|
||||
if (storedDRCBuffer.buffer_size >= screen_buf1_size) {
|
||||
screenbuffer1 = storedDRCBuffer.buffer;
|
||||
if (gStoredDRCBuffer.buffer_size >= screen_buf1_size) {
|
||||
screenbuffer1 = gStoredDRCBuffer.buffer;
|
||||
skipScreen1Free = true;
|
||||
DEBUG_FUNCTION_LINE_VERBOSE("Use storedDRCBuffer");
|
||||
}
|
||||
@@ -641,14 +619,14 @@ void ConfigUtils::openConfigMenu() {
|
||||
|
||||
error_exit:
|
||||
|
||||
if (storedTVBuffer.buffer != nullptr) {
|
||||
GX2SetTVBuffer(storedTVBuffer.buffer, storedTVBuffer.buffer_size, static_cast<GX2TVRenderMode>(storedTVBuffer.mode),
|
||||
storedTVBuffer.surface_format, storedTVBuffer.buffering_mode);
|
||||
if (gStoredTVBuffer.buffer != nullptr) {
|
||||
GX2SetTVBuffer(gStoredTVBuffer.buffer, gStoredTVBuffer.buffer_size, static_cast<GX2TVRenderMode>(gStoredTVBuffer.mode),
|
||||
gStoredTVBuffer.surface_format, gStoredTVBuffer.buffering_mode);
|
||||
}
|
||||
|
||||
if (storedDRCBuffer.buffer != nullptr) {
|
||||
GX2SetDRCBuffer(storedDRCBuffer.buffer, storedDRCBuffer.buffer_size, static_cast<GX2DrcRenderMode>(storedDRCBuffer.mode),
|
||||
storedDRCBuffer.surface_format, storedDRCBuffer.buffering_mode);
|
||||
if (gStoredDRCBuffer.buffer != nullptr) {
|
||||
GX2SetDRCBuffer(gStoredDRCBuffer.buffer, gStoredDRCBuffer.buffer_size, static_cast<GX2DrcRenderMode>(gStoredDRCBuffer.mode),
|
||||
gStoredDRCBuffer.surface_format, gStoredDRCBuffer.buffering_mode);
|
||||
}
|
||||
if (!skipScreen0Free && screenbuffer0) {
|
||||
MEMFreeToMappedMemory(screenbuffer0);
|
||||
|
||||
@@ -1,157 +1,35 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2010
|
||||
* by Dimok
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any
|
||||
* damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any
|
||||
* purpose, including commercial applications, and to alter it and
|
||||
* redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you
|
||||
* must not claim that you wrote the original software. If you use
|
||||
* this software in a product, an acknowledgment in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and
|
||||
* must not be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
* for WiiXplorer 2010
|
||||
***************************************************************************/
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <string.h>
|
||||
* Copyright (C) 2010
|
||||
* by Dimok
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any
|
||||
* damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any
|
||||
* purpose, including commercial applications, and to alter it and
|
||||
* redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you
|
||||
* must not claim that you wrote the original software. If you use
|
||||
* this software in a product, an acknowledgment in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and
|
||||
* must not be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
* for WiiXplorer 2010
|
||||
***************************************************************************/
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <strings.h>
|
||||
#include <utils/StringTools.h>
|
||||
#include <vector>
|
||||
#include <wut_types.h>
|
||||
|
||||
|
||||
BOOL StringTools::EndsWith(const std::string &a, const std::string &b) {
|
||||
if (b.size() > a.size())
|
||||
return false;
|
||||
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin());
|
||||
}
|
||||
|
||||
const char *StringTools::byte_to_binary(int32_t x) {
|
||||
static char b[9];
|
||||
b[0] = '\0';
|
||||
|
||||
int32_t z;
|
||||
for (z = 128; z > 0; z >>= 1) {
|
||||
strcat(b, ((x & z) == z) ? "1" : "0");
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
std::string StringTools::removeCharFromString(std::string &input, char toBeRemoved) {
|
||||
std::string output = input;
|
||||
size_t position;
|
||||
while (1) {
|
||||
position = output.find(toBeRemoved);
|
||||
if (position == std::string::npos)
|
||||
break;
|
||||
output.erase(position, 1);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
const char *StringTools::fmt(const char *format, ...) {
|
||||
static char strChar[512];
|
||||
strChar[0] = 0;
|
||||
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
if ((vsprintf(strChar, format, va) >= 0)) {
|
||||
va_end(va);
|
||||
return (const char *) strChar;
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const wchar_t *StringTools::wfmt(const char *format, ...) {
|
||||
static char tmp[512];
|
||||
static wchar_t strWChar[512];
|
||||
strWChar[0] = 0;
|
||||
tmp[0] = 0;
|
||||
|
||||
if (!format)
|
||||
return (const wchar_t *) strWChar;
|
||||
|
||||
if (strcmp(format, "") == 0)
|
||||
return (const wchar_t *) strWChar;
|
||||
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
if ((vsprintf(tmp, format, va) >= 0)) {
|
||||
int bt;
|
||||
int32_t strlength = strlen(tmp);
|
||||
bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512);
|
||||
|
||||
if (bt > 0) {
|
||||
strWChar[bt] = 0;
|
||||
return (const wchar_t *) strWChar;
|
||||
}
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t StringTools::strprintf(std::string &str, const char *format, ...) {
|
||||
static char tmp[512];
|
||||
tmp[0] = 0;
|
||||
int32_t result = 0;
|
||||
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
if ((vsprintf(tmp, format, va) >= 0)) {
|
||||
str = tmp;
|
||||
result = str.size();
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string StringTools::strfmt(const char *format, ...) {
|
||||
std::string str;
|
||||
static char tmp[512];
|
||||
tmp[0] = 0;
|
||||
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
if ((vsprintf(tmp, format, va) >= 0)) {
|
||||
str = tmp;
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
BOOL StringTools::char2wchar_t(const char *strChar, wchar_t *dest) {
|
||||
if (!strChar || !dest)
|
||||
return false;
|
||||
|
||||
int bt;
|
||||
bt = mbstowcs(dest, strChar, strlen(strChar));
|
||||
if (bt > 0) {
|
||||
dest[bt] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t StringTools::strtokcmp(const char *string, const char *compare, const char *separator) {
|
||||
if (!string || !compare)
|
||||
return -1;
|
||||
@@ -171,38 +49,3 @@ int32_t StringTools::strtokcmp(const char *string, const char *compare, const ch
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t StringTools::strextcmp(const char *string, const char *extension, char seperator) {
|
||||
if (!string || !extension)
|
||||
return -1;
|
||||
|
||||
char *ptr = strrchr(string, seperator);
|
||||
if (!ptr)
|
||||
return -1;
|
||||
|
||||
return strcasecmp(ptr + 1, extension);
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> StringTools::stringSplit(const std::string &inValue, const std::string &splitter) {
|
||||
std::string value = inValue;
|
||||
std::vector<std::string> result;
|
||||
while (true) {
|
||||
uint32_t index = value.find(splitter);
|
||||
if (index == std::string::npos) {
|
||||
result.push_back(value);
|
||||
break;
|
||||
}
|
||||
std::string first = value.substr(0, index);
|
||||
result.push_back(first);
|
||||
if (index + splitter.size() == value.length()) {
|
||||
result.push_back("");
|
||||
break;
|
||||
}
|
||||
if (index + splitter.size() > value.length()) {
|
||||
break;
|
||||
}
|
||||
value = value.substr(index + splitter.size(), value.length());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -23,34 +23,35 @@
|
||||
*
|
||||
* for WiiXplorer 2010
|
||||
***************************************************************************/
|
||||
#ifndef __STRING_TOOLS_H
|
||||
#define __STRING_TOOLS_H
|
||||
#pragma once
|
||||
|
||||
#include "logger.h"
|
||||
#include "utils.h"
|
||||
#include <coreinit/debug.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <wut_types.h>
|
||||
|
||||
template<typename... Args>
|
||||
std::string string_format(const std::string &format, Args... args) {
|
||||
int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0'
|
||||
auto size = static_cast<size_t>(size_s);
|
||||
auto buf = make_unique_nothrow<char[]>(size);
|
||||
if (!buf) {
|
||||
DEBUG_FUNCTION_LINE_ERR("string_format failed, not enough memory");
|
||||
OSFatal("string_format failed, not enough memory");
|
||||
return std::string("");
|
||||
}
|
||||
std::snprintf(buf.get(), size, format.c_str(), args...);
|
||||
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
||||
}
|
||||
|
||||
|
||||
class StringTools {
|
||||
public:
|
||||
static BOOL EndsWith(const std::string &a, const std::string &b);
|
||||
|
||||
static const char *byte_to_binary(int32_t x);
|
||||
|
||||
static std::string removeCharFromString(std::string &input, char toBeRemoved);
|
||||
|
||||
static const char *fmt(const char *format, ...);
|
||||
|
||||
static const wchar_t *wfmt(const char *format, ...);
|
||||
|
||||
static int32_t strprintf(std::string &str, const char *format, ...);
|
||||
|
||||
static std::string strfmt(const char *format, ...);
|
||||
|
||||
static BOOL char2wchar_t(const char *src, wchar_t *dest);
|
||||
|
||||
static int32_t strtokcmp(const char *string, const char *compare, const char *separator);
|
||||
|
||||
static int32_t strextcmp(const char *string, const char *extension, char seperator);
|
||||
|
||||
static const char *FullpathToFilename(const char *path) {
|
||||
if (!path)
|
||||
@@ -81,8 +82,4 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<std::string> stringSplit(const std::string &value, const std::string &splitter);
|
||||
};
|
||||
|
||||
#endif /* __STRING_TOOLS_H */
|
||||
};
|
||||
@@ -1,15 +1,12 @@
|
||||
#include "exports.h"
|
||||
#include "../PluginManagement.h"
|
||||
#include "../globals.h"
|
||||
#include "../plugin/PluginContainer.h"
|
||||
#include "../plugin/PluginContainerPersistence.h"
|
||||
#include "../plugin/PluginDataFactory.h"
|
||||
#include "../plugin/PluginDataPersistence.h"
|
||||
#include "../plugin/PluginMetaInformationFactory.h"
|
||||
#include <coreinit/cache.h>
|
||||
#include "utils.h"
|
||||
#include <wums.h>
|
||||
|
||||
static void fillPluginInformation(plugin_information *out, const std::shared_ptr<PluginMetaInformation> &metaInformation) {
|
||||
static void fillPluginInformation(plugin_information *out, const std::unique_ptr<PluginMetaInformation> &metaInformation) {
|
||||
out->plugin_information_version = PLUGIN_INFORMATION_VERSION;
|
||||
strncpy(out->author, metaInformation->getAuthor().c_str(), sizeof(out->author) - 1);
|
||||
strncpy(out->buildTimestamp, metaInformation->getBuildTimestamp().c_str(), sizeof(out->buildTimestamp) - 1);
|
||||
@@ -22,56 +19,55 @@ static void fillPluginInformation(plugin_information *out, const std::shared_ptr
|
||||
}
|
||||
|
||||
extern "C" PluginBackendApiErrorType WUPSLoadAndLinkByDataHandle(const plugin_data_handle *plugin_data_handle_list, uint32_t plugin_data_handle_list_size) {
|
||||
gLinkOnReload.number_used_plugins = 0;
|
||||
if (plugin_data_handle_list != nullptr && plugin_data_handle_list_size != 0) {
|
||||
for (uint32_t i = 0; i < plugin_data_handle_list_size; i++) {
|
||||
plugin_data_handle handle = plugin_data_handle_list[i];
|
||||
auto *pluginData = (PluginData *) handle;
|
||||
PluginDataPersistence::save(&gLinkOnReload.plugin_data[gLinkOnReload.number_used_plugins], pluginData);
|
||||
if (plugin_data_handle_list == nullptr || plugin_data_handle_list_size == 0) {
|
||||
|
||||
gLinkOnReload.number_used_plugins++;
|
||||
}
|
||||
if (gLinkOnReload.number_used_plugins > 0) {
|
||||
gLinkOnReload.loadOnReload = true;
|
||||
}
|
||||
DCFlushRange(&gLinkOnReload, sizeof(gLinkOnReload));
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE_ERR("PLUGIN_BACKEND_API_ERROR_INVALID_ARG");
|
||||
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
||||
}
|
||||
return PLUGIN_BACKEND_API_ERROR_NONE;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(gLoadedDataMutex);
|
||||
for (uint32_t i = 0; i < plugin_data_handle_list_size; i++) {
|
||||
auto handle = plugin_data_handle_list[i];
|
||||
bool found = false;
|
||||
|
||||
extern "C" PluginBackendApiErrorType WUPSDeletePluginContainer(const plugin_container_handle *handle_list, uint32_t handle_list_size) {
|
||||
if (handle_list != nullptr && handle_list_size != 0) {
|
||||
for (uint32_t i = 0; i < handle_list_size; i++) {
|
||||
auto handle = handle_list[i];
|
||||
auto *pluginContainer = (PluginContainer *) handle;
|
||||
delete pluginContainer;
|
||||
for (auto &pluginData : gLoadedData) {
|
||||
if (pluginData->getHandle() == handle) {
|
||||
gLoadOnNextLaunch.push_front(pluginData);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to get plugin data for handle %08X. Skipping it.", handle);
|
||||
}
|
||||
}
|
||||
|
||||
return PLUGIN_BACKEND_API_ERROR_NONE;
|
||||
}
|
||||
|
||||
extern "C" PluginBackendApiErrorType WUPSDeletePluginData(const plugin_data_handle *plugin_data_handle_list, uint32_t plugin_data_handle_list_size) {
|
||||
if (plugin_data_handle_list != nullptr && plugin_data_handle_list_size != 0) {
|
||||
for (uint32_t i = 0; i < plugin_data_handle_list_size; i++) {
|
||||
auto handle = plugin_data_handle_list[i];
|
||||
auto *pluginData = (PluginData *) handle;
|
||||
delete pluginData;
|
||||
auto handle = plugin_data_handle_list[i];
|
||||
|
||||
if (!remove_locked_first_if(gLoadedDataMutex, gLoadedData, [handle](auto &cur) { return cur->getHandle() == handle; })) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to delete plugin data by handle %08X", handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
return PLUGIN_BACKEND_API_ERROR_NONE;
|
||||
}
|
||||
|
||||
extern "C" PluginBackendApiErrorType WUPSLoadPluginAsData(GetPluginInformationInputType inputType, const char *path, char *buffer, size_t size, plugin_data_handle *out) {
|
||||
std::optional<std::shared_ptr<PluginData>> pluginData;
|
||||
if (out == nullptr) {
|
||||
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
std::optional<std::unique_ptr<PluginData>> pluginData;
|
||||
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
|
||||
pluginData = PluginDataFactory::load(path, gPluginDataHeap);
|
||||
pluginData = PluginDataFactory::load(path);
|
||||
} else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) {
|
||||
std::vector<uint8_t> data(size);
|
||||
memcpy(&data[0], buffer, size);
|
||||
pluginData = PluginDataFactory::load(data, gPluginDataHeap);
|
||||
pluginData = PluginDataFactory::load(data);
|
||||
} else {
|
||||
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
||||
}
|
||||
@@ -81,12 +77,9 @@ extern "C" PluginBackendApiErrorType WUPSLoadPluginAsData(GetPluginInformationIn
|
||||
return PLUGIN_BACKEND_API_ERROR_FAILED_ALLOC;
|
||||
}
|
||||
|
||||
if (out == nullptr) {
|
||||
DEBUG_FUNCTION_LINE_ERR("PLUGIN_BACKEND_API_ERROR_INVALID_ARG");
|
||||
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
||||
} else {
|
||||
auto *pluginDataHandle = new PluginData(*pluginData.value());
|
||||
*out = (uint32_t) pluginDataHandle;
|
||||
else {
|
||||
*out = pluginData.value()->getHandle();
|
||||
gLoadedData.push_front(std::move(pluginData.value()));
|
||||
}
|
||||
|
||||
return PLUGIN_BACKEND_API_ERROR_NONE;
|
||||
@@ -101,7 +94,7 @@ extern "C" PluginBackendApiErrorType WUPSLoadPluginAsDataByBuffer(plugin_data_ha
|
||||
}
|
||||
|
||||
extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformation(GetPluginInformationInputType inputType, const char *path, char *buffer, size_t size, plugin_information *output) {
|
||||
std::optional<std::shared_ptr<PluginMetaInformation>> pluginInfo;
|
||||
std::optional<std::unique_ptr<PluginMetaInformation>> pluginInfo;
|
||||
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
|
||||
std::string pathStr(path);
|
||||
pluginInfo = PluginMetaInformationFactory::loadPlugin(pathStr);
|
||||
@@ -136,17 +129,29 @@ extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformationByBuffer(plugin
|
||||
|
||||
extern "C" PluginBackendApiErrorType WUPSGetPluginDataForContainerHandles(const plugin_container_handle *plugin_container_handle_list, plugin_data_handle *plugin_data_list, uint32_t buffer_size) {
|
||||
PluginBackendApiErrorType res = PLUGIN_BACKEND_API_ERROR_NONE;
|
||||
if (plugin_container_handle_list != nullptr && buffer_size != 0) {
|
||||
for (uint32_t i = 0; i < buffer_size; i++) {
|
||||
auto handle = plugin_container_handle_list[i];
|
||||
auto *container = (PluginContainer *) handle;
|
||||
auto *pluginData = new PluginData(*container->getPluginData());
|
||||
plugin_data_list[i] = (uint32_t) pluginData;
|
||||
}
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE_ERR("PLUGIN_BACKEND_API_ERROR_INVALID_ARG");
|
||||
res = PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
||||
if (plugin_container_handle_list == nullptr || buffer_size == 0) {
|
||||
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(gLoadedDataMutex);
|
||||
for (uint32_t i = 0; i < buffer_size; /* only increase on success*/) {
|
||||
auto handle = plugin_container_handle_list[i];
|
||||
bool found = false;
|
||||
for (auto &curContainer : gLoadedPlugins) {
|
||||
if (curContainer->getHandle() == handle) {
|
||||
auto &pluginData = curContainer->getPluginData();
|
||||
plugin_data_list[i] = (uint32_t) pluginData->getHandle();
|
||||
gLoadedData.push_front(pluginData);
|
||||
found = true;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
DEBUG_FUNCTION_LINE_ERR("Failed to get container for handle %08X", handle);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -154,18 +159,29 @@ extern "C" PluginBackendApiErrorType WUPSGetMetaInformation(const plugin_contain
|
||||
PluginBackendApiErrorType res = PLUGIN_BACKEND_API_ERROR_NONE;
|
||||
if (plugin_container_handle_list != nullptr && buffer_size != 0) {
|
||||
for (uint32_t i = 0; i < buffer_size; i++) {
|
||||
auto handle = plugin_container_handle_list[i];
|
||||
auto *container = (PluginContainer *) handle;
|
||||
auto handle = plugin_container_handle_list[i];
|
||||
bool found = false;
|
||||
for (auto &curContainer : gLoadedPlugins) {
|
||||
if (curContainer->getHandle() == handle) {
|
||||
auto &metaInfo = curContainer->getMetaInformation();
|
||||
|
||||
plugin_information_list[i].plugin_information_version = PLUGIN_INFORMATION_VERSION;
|
||||
strncpy(plugin_information_list[i].storageId, container->metaInformation->getStorageId().c_str(), sizeof(plugin_information_list[i].storageId) - 1);
|
||||
strncpy(plugin_information_list[i].author, container->metaInformation->getAuthor().c_str(), sizeof(plugin_information_list[i].author) - 1);
|
||||
strncpy(plugin_information_list[i].buildTimestamp, container->metaInformation->getBuildTimestamp().c_str(), sizeof(plugin_information_list[i].buildTimestamp) - 1);
|
||||
strncpy(plugin_information_list[i].description, container->metaInformation->getDescription().c_str(), sizeof(plugin_information_list[i].description) - 1);
|
||||
strncpy(plugin_information_list[i].name, container->metaInformation->getName().c_str(), sizeof(plugin_information_list[i].name) - 1);
|
||||
strncpy(plugin_information_list[i].license, container->metaInformation->getLicense().c_str(), sizeof(plugin_information_list[i].license) - 1);
|
||||
strncpy(plugin_information_list[i].version, container->metaInformation->getVersion().c_str(), sizeof(plugin_information_list[i].version) - 1);
|
||||
plugin_information_list[i].size = container->metaInformation->getSize();
|
||||
plugin_information_list[i].plugin_information_version = PLUGIN_INFORMATION_VERSION;
|
||||
strncpy(plugin_information_list[i].storageId, metaInfo->getStorageId().c_str(), sizeof(plugin_information_list[i].storageId) - 1);
|
||||
strncpy(plugin_information_list[i].author, metaInfo->getAuthor().c_str(), sizeof(plugin_information_list[i].author) - 1);
|
||||
strncpy(plugin_information_list[i].buildTimestamp, metaInfo->getBuildTimestamp().c_str(), sizeof(plugin_information_list[i].buildTimestamp) - 1);
|
||||
strncpy(plugin_information_list[i].description, metaInfo->getDescription().c_str(), sizeof(plugin_information_list[i].description) - 1);
|
||||
strncpy(plugin_information_list[i].name, metaInfo->getName().c_str(), sizeof(plugin_information_list[i].name) - 1);
|
||||
strncpy(plugin_information_list[i].license, metaInfo->getLicense().c_str(), sizeof(plugin_information_list[i].license) - 1);
|
||||
strncpy(plugin_information_list[i].version, metaInfo->getVersion().c_str(), sizeof(plugin_information_list[i].version) - 1);
|
||||
plugin_information_list[i].size = metaInfo->getSize();
|
||||
found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
DEBUG_FUNCTION_LINE_ERR("FAILED TO FIND CONTAINER FOR HANDLE %08X", handle);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE_ERR("PLUGIN_BACKEND_API_ERROR_INVALID_ARG");
|
||||
@@ -175,17 +191,15 @@ extern "C" PluginBackendApiErrorType WUPSGetMetaInformation(const plugin_contain
|
||||
}
|
||||
|
||||
extern "C" PluginBackendApiErrorType WUPSGetLoadedPlugins(plugin_container_handle *io_handles, uint32_t buffer_size, uint32_t *outSize, uint32_t *plugin_information_version) {
|
||||
DEBUG_FUNCTION_LINE();
|
||||
if (plugin_information_version == nullptr) {
|
||||
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
||||
}
|
||||
*plugin_information_version = PLUGIN_INFORMATION_VERSION;
|
||||
auto plugins = PluginContainerPersistence::loadPlugins(gPluginInformation);
|
||||
auto &plugins = gLoadedPlugins;
|
||||
uint32_t counter = 0;
|
||||
for (auto &plugin : plugins) {
|
||||
if (counter < buffer_size) {
|
||||
auto *container = new PluginContainer(*plugin);
|
||||
io_handles[counter] = (uint32_t) container;
|
||||
io_handles[counter] = plugin->getHandle();
|
||||
counter++;
|
||||
} else {
|
||||
break;
|
||||
@@ -201,7 +215,6 @@ WUMS_EXPORT_FUNCTION(WUPSLoadPluginAsDataByPath);
|
||||
WUMS_EXPORT_FUNCTION(WUPSLoadPluginAsDataByBuffer);
|
||||
WUMS_EXPORT_FUNCTION(WUPSLoadPluginAsData);
|
||||
WUMS_EXPORT_FUNCTION(WUPSLoadAndLinkByDataHandle);
|
||||
WUMS_EXPORT_FUNCTION(WUPSDeletePluginContainer);
|
||||
WUMS_EXPORT_FUNCTION(WUPSDeletePluginData);
|
||||
WUMS_EXPORT_FUNCTION(WUPSGetPluginMetaInformation);
|
||||
WUMS_EXPORT_FUNCTION(WUPSGetPluginMetaInformationByPath);
|
||||
|
||||
@@ -17,7 +17,7 @@ std::string getPluginPath() {
|
||||
|
||||
IOS_Close(handle);
|
||||
}
|
||||
return std::string(environmentPath) + "/plugins";
|
||||
return std::string(environmentPath).append("/plugins");
|
||||
}
|
||||
|
||||
// https://gist.github.com/ccbrown/9722406
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <forward_list>
|
||||
#include <malloc.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -41,4 +44,33 @@ void dumpHex(const void *data, size_t size);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class T, class... Args>
|
||||
std::unique_ptr<T> make_unique_nothrow(Args &&...args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
|
||||
return std::unique_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline typename std::_MakeUniq<T>::__array make_unique_nothrow(size_t num) noexcept {
|
||||
return std::unique_ptr<T>(new (std::nothrow) std::remove_extent_t<T>[num]());
|
||||
}
|
||||
|
||||
template<class T, class... Args>
|
||||
std::shared_ptr<T> make_shared_nothrow(Args &&...args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
|
||||
return std::shared_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template<typename T, class Allocator, class Predicate>
|
||||
bool remove_locked_first_if(std::mutex &mutex, std::forward_list<T, Allocator> &list, Predicate pred) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
auto oit = list.before_begin(), it = std::next(oit);
|
||||
while (it != list.end()) {
|
||||
if (pred(*it)) {
|
||||
list.erase_after(oit);
|
||||
return true;
|
||||
}
|
||||
oit = it++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string getPluginPath();
|
||||
Reference in New Issue
Block a user