2021-01-13 17:28:27 +01:00
|
|
|
#include <hex/api/content_registry.hpp>
|
2021-01-11 20:31:40 +01:00
|
|
|
|
2021-01-13 17:28:27 +01:00
|
|
|
#include <hex/helpers/shared_data.hpp>
|
2021-09-03 02:33:15 +02:00
|
|
|
#include <hex/helpers/paths.hpp>
|
2021-01-11 20:31:40 +01:00
|
|
|
|
|
|
|
#include <filesystem>
|
|
|
|
#include <fstream>
|
|
|
|
|
2021-08-29 14:18:45 +02:00
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
|
2021-01-11 20:31:40 +01:00
|
|
|
namespace hex {
|
|
|
|
|
|
|
|
/* Settings */
|
|
|
|
|
|
|
|
void ContentRegistry::Settings::load() {
|
2021-07-31 17:11:10 +02:00
|
|
|
bool loaded = false;
|
2021-03-01 08:56:49 +01:00
|
|
|
for (const auto &dir : hex::getPath(ImHexPath::Config)) {
|
|
|
|
std::ifstream settingsFile(dir + "/settings.json");
|
|
|
|
|
|
|
|
if (settingsFile.good()) {
|
|
|
|
settingsFile >> getSettingsData();
|
2021-07-31 17:11:10 +02:00
|
|
|
loaded = true;
|
2021-03-01 08:56:49 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-07-31 17:11:10 +02:00
|
|
|
|
|
|
|
if (!loaded)
|
|
|
|
ContentRegistry::Settings::store();
|
2021-01-11 20:31:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void ContentRegistry::Settings::store() {
|
2021-03-01 08:56:49 +01:00
|
|
|
for (const auto &dir : hex::getPath(ImHexPath::Config)) {
|
|
|
|
std::ofstream settingsFile(dir + "/settings.json", std::ios::trunc);
|
|
|
|
|
|
|
|
if (settingsFile.good()) {
|
|
|
|
settingsFile << getSettingsData();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-01-11 20:31:40 +01:00
|
|
|
}
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
void ContentRegistry::Settings::add(const std::string &unlocalizedCategory, const std::string &unlocalizedName, s64 defaultValue, const ContentRegistry::Settings::Callback &callback) {
|
|
|
|
ContentRegistry::Settings::getEntries()[unlocalizedCategory.c_str()].emplace_back(Entry{ unlocalizedName.c_str(), callback });
|
2021-01-11 20:31:40 +01:00
|
|
|
|
2021-01-12 16:50:15 +01:00
|
|
|
auto &json = getSettingsData();
|
2021-01-11 20:31:40 +01:00
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
if (!json.contains(unlocalizedCategory))
|
|
|
|
json[unlocalizedCategory] = nlohmann::json::object();
|
|
|
|
if (!json[unlocalizedCategory].contains(unlocalizedName) || !json[unlocalizedCategory][unlocalizedName].is_number())
|
|
|
|
json[unlocalizedCategory][unlocalizedName] = int(defaultValue);
|
2021-01-11 20:31:40 +01:00
|
|
|
}
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
void ContentRegistry::Settings::add(const std::string &unlocalizedCategory, const std::string &unlocalizedName, const std::string &defaultValue, const ContentRegistry::Settings::Callback &callback) {
|
|
|
|
ContentRegistry::Settings::getEntries()[unlocalizedCategory].emplace_back(Entry{ unlocalizedName, callback });
|
2021-02-13 15:15:32 +01:00
|
|
|
|
|
|
|
auto &json = getSettingsData();
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
if (!json.contains(unlocalizedCategory))
|
|
|
|
json[unlocalizedCategory] = nlohmann::json::object();
|
|
|
|
if (!json[unlocalizedCategory].contains(unlocalizedName) || !json[unlocalizedCategory][unlocalizedName].is_string())
|
|
|
|
json[unlocalizedCategory][unlocalizedName] = std::string(defaultValue);
|
2021-01-11 20:31:40 +01:00
|
|
|
}
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
void ContentRegistry::Settings::write(const std::string &unlocalizedCategory, const std::string &unlocalizedName, s64 value) {
|
2021-02-01 19:03:28 +01:00
|
|
|
auto &json = getSettingsData();
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
if (!json.contains(unlocalizedCategory))
|
|
|
|
json[unlocalizedCategory] = nlohmann::json::object();
|
2021-02-01 19:03:28 +01:00
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
json[unlocalizedCategory][unlocalizedName] = value;
|
2021-02-01 19:03:28 +01:00
|
|
|
}
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
void ContentRegistry::Settings::write(const std::string &unlocalizedCategory, const std::string &unlocalizedName, const std::string &value) {
|
2021-02-01 19:03:28 +01:00
|
|
|
auto &json = getSettingsData();
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
if (!json.contains(unlocalizedCategory))
|
|
|
|
json[unlocalizedCategory] = nlohmann::json::object();
|
2021-02-01 19:03:28 +01:00
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
json[unlocalizedCategory][unlocalizedName] = value;
|
2021-02-01 19:03:28 +01:00
|
|
|
}
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
void ContentRegistry::Settings::write(const std::string &unlocalizedCategory, const std::string &unlocalizedName, const std::vector<std::string>& value) {
|
2021-02-01 19:03:28 +01:00
|
|
|
auto &json = getSettingsData();
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
if (!json.contains(unlocalizedCategory))
|
|
|
|
json[unlocalizedCategory] = nlohmann::json::object();
|
2021-02-01 19:03:28 +01:00
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
json[unlocalizedCategory][unlocalizedName] = value;
|
2021-02-01 19:03:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
s64 ContentRegistry::Settings::read(const std::string &unlocalizedCategory, const std::string &unlocalizedName, s64 defaultValue) {
|
2021-02-01 19:03:28 +01:00
|
|
|
auto &json = getSettingsData();
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
if (!json.contains(unlocalizedCategory))
|
2021-02-01 19:03:28 +01:00
|
|
|
return defaultValue;
|
2021-09-08 15:18:24 +02:00
|
|
|
if (!json[unlocalizedCategory].contains(unlocalizedName))
|
2021-02-01 19:03:28 +01:00
|
|
|
return defaultValue;
|
|
|
|
|
2021-09-12 13:59:23 +02:00
|
|
|
if (!json[unlocalizedCategory][unlocalizedName].is_number())
|
|
|
|
json[unlocalizedCategory][unlocalizedName] = defaultValue;
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
return json[unlocalizedCategory][unlocalizedName].get<s64>();
|
2021-02-01 19:03:28 +01:00
|
|
|
}
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
std::string ContentRegistry::Settings::read(const std::string &unlocalizedCategory, const std::string &unlocalizedName, const std::string &defaultValue) {
|
2021-02-01 19:03:28 +01:00
|
|
|
auto &json = getSettingsData();
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
if (!json.contains(unlocalizedCategory))
|
|
|
|
return defaultValue;
|
|
|
|
if (!json[unlocalizedCategory].contains(unlocalizedName))
|
|
|
|
return defaultValue;
|
2021-02-01 19:03:28 +01:00
|
|
|
|
2021-09-12 13:59:23 +02:00
|
|
|
if (!json[unlocalizedCategory][unlocalizedName].is_string())
|
|
|
|
json[unlocalizedCategory][unlocalizedName] = defaultValue;
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
return json[unlocalizedCategory][unlocalizedName].get<std::string>();
|
2021-02-01 19:03:28 +01:00
|
|
|
}
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
std::vector<std::string> ContentRegistry::Settings::read(const std::string &unlocalizedCategory, const std::string &unlocalizedName, const std::vector<std::string>& defaultValue) {
|
2021-02-01 19:03:28 +01:00
|
|
|
auto &json = getSettingsData();
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
if (!json.contains(unlocalizedCategory))
|
2021-02-01 19:03:28 +01:00
|
|
|
return defaultValue;
|
2021-09-08 15:18:24 +02:00
|
|
|
if (!json[unlocalizedCategory].contains(unlocalizedName))
|
2021-02-01 19:03:28 +01:00
|
|
|
return defaultValue;
|
|
|
|
|
2021-09-12 20:27:56 +02:00
|
|
|
if (!json[unlocalizedCategory][unlocalizedName].is_array())
|
|
|
|
json[unlocalizedCategory][unlocalizedName] = defaultValue;
|
|
|
|
|
|
|
|
if (!json[unlocalizedCategory][unlocalizedName].array().empty() && !json[unlocalizedCategory][unlocalizedName][0].is_string())
|
2021-09-12 13:59:23 +02:00
|
|
|
json[unlocalizedCategory][unlocalizedName] = defaultValue;
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
return json[unlocalizedCategory][unlocalizedName].get<std::vector<std::string>>();
|
2021-02-01 19:03:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-11 20:31:40 +01:00
|
|
|
std::map<std::string, std::vector<ContentRegistry::Settings::Entry>>& ContentRegistry::Settings::getEntries() {
|
2021-01-12 23:28:41 +01:00
|
|
|
return SharedData::settingsEntries;
|
2021-01-11 20:31:40 +01:00
|
|
|
}
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
nlohmann::json ContentRegistry::Settings::getSetting(const std::string &unlocalizedCategory, const std::string &unlocalizedName) {
|
2021-02-16 23:42:35 +01:00
|
|
|
auto &settings = getSettingsData();
|
|
|
|
|
|
|
|
if (!settings.contains(unlocalizedCategory)) return { };
|
2021-09-08 15:18:24 +02:00
|
|
|
if (!settings[unlocalizedCategory].contains(unlocalizedName)) return { };
|
2021-02-16 23:42:35 +01:00
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
return settings[unlocalizedCategory][unlocalizedName];
|
2021-02-16 23:42:35 +01:00
|
|
|
}
|
|
|
|
|
2021-01-11 20:31:40 +01:00
|
|
|
nlohmann::json& ContentRegistry::Settings::getSettingsData() {
|
2021-01-12 23:28:41 +01:00
|
|
|
return SharedData::settingsJson;
|
2021-01-11 20:31:40 +01:00
|
|
|
}
|
|
|
|
|
2021-01-11 21:11:03 +01:00
|
|
|
|
2021-01-11 23:02:55 +01:00
|
|
|
/* Command Palette Commands */
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
void ContentRegistry::CommandPaletteCommands::add(ContentRegistry::CommandPaletteCommands::Type type, const std::string &command, const std::string &unlocalizedDescription, const std::function<std::string(std::string)> &displayCallback, const std::function<void(std::string)> &executeCallback) {
|
|
|
|
getEntries().push_back(ContentRegistry::CommandPaletteCommands::Entry{ type, command, unlocalizedDescription, displayCallback, executeCallback });
|
2021-01-11 23:02:55 +01:00
|
|
|
}
|
|
|
|
|
2021-01-12 16:50:15 +01:00
|
|
|
std::vector<ContentRegistry::CommandPaletteCommands::Entry>& ContentRegistry::CommandPaletteCommands::getEntries() {
|
2021-01-12 23:28:41 +01:00
|
|
|
return SharedData::commandPaletteCommands;
|
2021-01-11 23:02:55 +01:00
|
|
|
}
|
|
|
|
|
2021-01-11 23:54:12 +01:00
|
|
|
|
|
|
|
/* Pattern Language Functions */
|
|
|
|
|
2021-08-27 09:56:20 +02:00
|
|
|
|
2021-12-19 12:32:15 +01:00
|
|
|
void ContentRegistry::PatternLanguageFunctions::add(const Namespace &ns, const std::string &name, u32 parameterCount, const ContentRegistry::PatternLanguageFunctions::Callback &func, bool dangerous) {
|
2021-08-27 09:56:20 +02:00
|
|
|
std::string functionName;
|
|
|
|
for (auto &scope : ns)
|
|
|
|
functionName += scope + "::";
|
|
|
|
|
|
|
|
functionName += name;
|
|
|
|
|
2021-12-19 12:32:15 +01:00
|
|
|
getEntries()[functionName] = Function { parameterCount, func, dangerous };
|
2021-01-11 23:54:12 +01:00
|
|
|
}
|
|
|
|
|
2021-01-12 16:50:15 +01:00
|
|
|
std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function>& ContentRegistry::PatternLanguageFunctions::getEntries() {
|
2021-01-12 23:28:41 +01:00
|
|
|
return SharedData::patternLanguageFunctions;
|
2021-01-11 23:54:12 +01:00
|
|
|
}
|
|
|
|
|
2021-01-12 16:50:15 +01:00
|
|
|
|
|
|
|
/* Views */
|
|
|
|
|
2021-12-12 11:52:58 +01:00
|
|
|
void ContentRegistry::Views::impl::add(View *view) {
|
2021-03-16 22:44:37 +01:00
|
|
|
getEntries().emplace_back(view);
|
2021-01-12 16:50:15 +01:00
|
|
|
}
|
|
|
|
|
2021-03-16 22:44:37 +01:00
|
|
|
std::vector<View*>& ContentRegistry::Views::getEntries() {
|
2021-01-12 23:28:41 +01:00
|
|
|
return SharedData::views;
|
2021-01-12 16:50:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Tools */
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
void ContentRegistry::Tools:: add(const std::string &unlocalizedName, const std::function<void()> &function) {
|
2021-12-12 11:52:58 +01:00
|
|
|
getEntries().emplace_back(impl::Entry{ unlocalizedName, function });
|
2021-01-12 16:50:15 +01:00
|
|
|
}
|
|
|
|
|
2021-12-12 11:52:58 +01:00
|
|
|
std::vector<ContentRegistry::Tools::impl::Entry>& ContentRegistry::Tools::getEntries() {
|
2021-01-13 01:24:27 +01:00
|
|
|
return SharedData::toolsEntries;
|
2021-01-12 16:50:15 +01:00
|
|
|
}
|
|
|
|
|
2021-01-13 01:24:27 +01:00
|
|
|
|
|
|
|
/* Data Inspector */
|
|
|
|
|
2021-12-12 11:52:58 +01:00
|
|
|
void ContentRegistry::DataInspector::add(const std::string &unlocalizedName, size_t requiredSize, ContentRegistry::DataInspector::impl::GeneratorFunction function) {
|
2021-09-08 15:18:24 +02:00
|
|
|
getEntries().push_back({ unlocalizedName, requiredSize, std::move(function) });
|
2021-01-13 01:24:27 +01:00
|
|
|
}
|
|
|
|
|
2021-12-12 11:52:58 +01:00
|
|
|
std::vector<ContentRegistry::DataInspector::impl::Entry>& ContentRegistry::DataInspector::getEntries() {
|
2021-01-13 01:24:27 +01:00
|
|
|
return SharedData::dataInspectorEntries;
|
|
|
|
}
|
2021-01-30 22:39:06 +01:00
|
|
|
|
|
|
|
/* Data Processor Nodes */
|
|
|
|
|
2021-12-12 11:52:58 +01:00
|
|
|
void ContentRegistry::DataProcessorNode::impl::add(const impl::Entry &entry) {
|
2021-01-30 22:39:06 +01:00
|
|
|
getEntries().push_back(entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentRegistry::DataProcessorNode::addSeparator() {
|
|
|
|
getEntries().push_back({ "", "", []{ return nullptr; } });
|
|
|
|
}
|
|
|
|
|
2021-12-12 11:52:58 +01:00
|
|
|
std::vector<ContentRegistry::DataProcessorNode::impl::Entry>& ContentRegistry::DataProcessorNode::getEntries() {
|
2021-01-30 22:39:06 +01:00
|
|
|
return SharedData::dataProcessorNodes;
|
|
|
|
}
|
2021-02-11 00:35:30 +01:00
|
|
|
|
|
|
|
/* Languages */
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
void ContentRegistry::Language::registerLanguage(const std::string &name, const std::string &languageCode) {
|
|
|
|
getLanguages().insert({ languageCode, name });
|
2021-02-11 00:35:30 +01:00
|
|
|
}
|
|
|
|
|
2021-09-08 15:18:24 +02:00
|
|
|
void ContentRegistry::Language::addLocalizations(const std::string &languageCode, const LanguageDefinition &definition) {
|
|
|
|
getLanguageDefinitions()[languageCode].push_back(definition);
|
2021-02-11 00:35:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
std::map<std::string, std::string>& ContentRegistry::Language::getLanguages() {
|
|
|
|
return SharedData::languageNames;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::map<std::string, std::vector<LanguageDefinition>>& ContentRegistry::Language::getLanguageDefinitions() {
|
|
|
|
return SharedData::languageDefinitions;
|
|
|
|
}
|
2021-02-18 12:09:19 +01:00
|
|
|
|
|
|
|
|
|
|
|
void ContentRegistry::Interface::addWelcomeScreenEntry(const ContentRegistry::Interface::DrawCallback &function) {
|
|
|
|
getWelcomeScreenEntries().push_back(function);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentRegistry::Interface::addFooterItem(const ContentRegistry::Interface::DrawCallback &function){
|
|
|
|
getFooterItems().push_back(function);
|
|
|
|
}
|
|
|
|
|
2021-08-21 00:52:11 +02:00
|
|
|
void ContentRegistry::Interface::addToolbarItem(const ContentRegistry::Interface::DrawCallback &function){
|
|
|
|
getToolbarItems().push_back(function);
|
|
|
|
}
|
|
|
|
|
2021-02-18 12:09:19 +01:00
|
|
|
|
|
|
|
std::vector<ContentRegistry::Interface::DrawCallback>& ContentRegistry::Interface::getWelcomeScreenEntries() {
|
|
|
|
return SharedData::welcomeScreenEntries;
|
|
|
|
}
|
|
|
|
std::vector<ContentRegistry::Interface::DrawCallback>& ContentRegistry::Interface::getFooterItems() {
|
|
|
|
return SharedData::footerItems;
|
|
|
|
}
|
2021-08-21 00:52:11 +02:00
|
|
|
std::vector<ContentRegistry::Interface::DrawCallback>& ContentRegistry::Interface::getToolbarItems() {
|
|
|
|
return SharedData::toolbarItems;
|
|
|
|
}
|
2021-12-07 22:47:41 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* Providers */
|
|
|
|
|
2021-12-12 11:52:58 +01:00
|
|
|
void ContentRegistry::Provider::impl::addProviderName(const std::string &unlocalizedName) {
|
2021-12-07 22:47:41 +01:00
|
|
|
SharedData::providerNames.push_back(unlocalizedName);
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::vector<std::string> &ContentRegistry::Provider::getEntries() {
|
|
|
|
return SharedData::providerNames;
|
|
|
|
}
|
2021-01-11 20:31:40 +01:00
|
|
|
}
|