From c6dac5567918eafdb5dc012fe468ab3bd1e78d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucca=20Jim=C3=A9nez=20K=C3=B6nings?= Date: Tue, 7 May 2024 17:24:45 +0200 Subject: [PATCH] Wrap Settings into synchronization primitives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lucca Jiménez Könings --- include/TSettings.h | 96 +++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/include/TSettings.h b/include/TSettings.h index 263ba2a..aec0b79 100644 --- a/include/TSettings.h +++ b/include/TSettings.h @@ -24,6 +24,7 @@ #include #include #include +#include "Sync.h" struct ComposedKey { std::string Category; @@ -82,7 +83,7 @@ struct Settings { General_Debug }; - std::unordered_map SettingsMap { + Sync> SettingsMap = std::unordered_map{ { General_Description, "BeamMP Default Description" }, { General_Tags, "Freeroam" }, { General_MaxPlayers, 8 }, @@ -111,7 +112,7 @@ struct Settings { SettingsAccessMask // Console read/write permissions >; - std::unordered_map InputAccessMapping { + Sync> InputAccessMapping = std::unordered_map{ { { "General", "Description" }, { General_Description, write } }, { { "General", "Tags" }, { General_Tags, write } }, { { "General", "MaxPlayers" }, { General_MaxPlayers, write } }, @@ -149,125 +150,136 @@ struct Settings { } */ std::string getAsString(Key key) { - if (!SettingsMap.contains(key)) { + auto map = SettingsMap.synchronize(); + if (!map->contains(key)) { throw std::logic_error { "Undefined key accessed in Settings::getAsString" }; } - return std::get(SettingsMap.at(key)); + return std::get(map->at(key)); } int getAsInt(Key key) { - if (!SettingsMap.contains(key)) { + auto map = SettingsMap.synchronize(); + if (!map->contains(key)) { throw std::logic_error { "Undefined key accessed in Settings::getAsInt" }; } - return std::get(SettingsMap.at(key)); + return std::get(map->at(key)); } bool getAsBool(Key key) { - if (!SettingsMap.contains(key)) { + auto map = SettingsMap.synchronize(); + if (!map->contains(key)) { throw std::logic_error { "Undefined key accessed in Settings::getAsBool" }; } - return std::get(SettingsMap.at(key)); + return std::get(map->at(key)); } SettingsTypeVariant get(Key key) { - if (!SettingsMap.contains(key)) { + auto map = SettingsMap.synchronize(); + if (!map->contains(key)) { throw std::logic_error { "Undefined setting key accessed in Settings::get" }; } - return SettingsMap.at(key); + return map->at(key); } void set(Key key, std::string value) { - if (!SettingsMap.contains(key)) { + auto map = SettingsMap.synchronize(); + if (!map->contains(key)) { throw std::logic_error { "Undefined setting key accessed in Settings::getAsString" }; } - if (!std::holds_alternative(SettingsMap.at(key))) { + if (!std::holds_alternative(map->at(key))) { throw std::logic_error { "Wrong value type in Settings::get: std::string" }; } - SettingsMap.at(key) = value; + map->at(key) = value; } void set(Key key, int value) { - if (!SettingsMap.contains(key)) { + auto map = SettingsMap.synchronize(); + if (!map->contains(key)) { throw std::logic_error { "Undefined setting key accessed in Settings::getAsString" }; } - if (!std::holds_alternative(SettingsMap.at(key))) { + if (!std::holds_alternative(map->at(key))) { throw std::logic_error { "Wrong value type in Settings::get: std::string" }; } - SettingsMap.at(key) = value; + map->at(key) = value; } void set(Key key, bool value) { - if (!SettingsMap.contains(key)) { + auto map = SettingsMap.synchronize(); + if (!map->contains(key)) { throw std::logic_error { "Undefined setting key accessed in Settings::getAsString" }; } - if (!std::holds_alternative(SettingsMap.at(key))) { + if (!std::holds_alternative(map->at(key))) { throw std::logic_error { "Wrong value type in Settings::get: std::string" }; } - SettingsMap.at(key) = value; + map->at(key) = value; } - const std::unordered_map& getACLMap() const { - return InputAccessMapping; + const std::unordered_map getACLMap() const { + return *InputAccessMapping; } SettingsAccessControl getConsoleInputAccessMapping(const ComposedKey& keyName) { - if (!InputAccessMapping.contains(keyName)) { + auto acl_map = InputAccessMapping.synchronize(); + if (!acl_map->contains(keyName)) { throw std::logic_error { "Unknown key name accessed in Settings::getConsoleInputAccessMapping" }; - } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::noaccess) { + } else if (acl_map->at(keyName).second == SettingsAccessMask::noaccess) { throw std::logic_error { "Setting '" + keyName.Category + " > " + keyName.Key + "' is not accessible from within the runtime!" }; } - return InputAccessMapping.at(keyName); + return acl_map->at(keyName); } void setConsoleInputAccessMapping(const ComposedKey& keyName, std::string value) { - if (!InputAccessMapping.contains(keyName)) { + auto [map, acl_map] = boost::synchronize(SettingsMap, InputAccessMapping); + if (!acl_map->contains(keyName)) { throw std::logic_error { "Unknown key name accessed in Settings::setConsoleInputAccessMapping" }; - } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::noaccess) { + } else if (acl_map->at(keyName).second == SettingsAccessMask::noaccess) { throw std::logic_error { "Setting '" + keyName.Category + " > " + keyName.Key + "' is not accessible from within the runtime!" }; - } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::read) { + } else if (acl_map->at(keyName).second == SettingsAccessMask::read) { throw std::logic_error { "Setting '" + keyName.Category + " > " + keyName.Key + "' is not writeable from within the runtime!" }; } - Key key = InputAccessMapping.at(keyName).first; + Key key = acl_map->at(keyName).first; - if (!std::holds_alternative(SettingsMap.at(key))) { + if (!std::holds_alternative(map->at(key))) { throw std::logic_error { "Wrong value type in Settings::setConsoleInputAccessMapping: expected std::string" }; } - SettingsMap.at(key) = value; + map->at(key) = value; } void setConsoleInputAccessMapping(const ComposedKey& keyName, int value) { - if (!InputAccessMapping.contains(keyName)) { + auto [map, acl_map] = boost::synchronize(SettingsMap, InputAccessMapping); + if (!acl_map->contains(keyName)) { throw std::logic_error { "Unknown key name accessed in Settings::setConsoleInputAccessMapping" }; - } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::noaccess) { + } else if (acl_map->at(keyName).second == SettingsAccessMask::noaccess) { throw std::logic_error { "Key '" + keyName.Category + " > " + keyName.Key + "' is not accessible from within the runtime!" }; - } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::read) { + } else if (acl_map->at(keyName).second == SettingsAccessMask::read) { throw std::logic_error { "Key '" + keyName.Category + " > " + keyName.Key + "' is not writeable from within the runtime!" }; } - Key key = InputAccessMapping.at(keyName).first; + Key key = acl_map->at(keyName).first; - if (!std::holds_alternative(SettingsMap.at(key))) { + if (!std::holds_alternative(map->at(key))) { throw std::logic_error { "Wrong value type in Settings::setConsoleInputAccessMapping: expected int" }; } - SettingsMap.at(key) = value; + map->at(key) = value; } void setConsoleInputAccessMapping(const ComposedKey& keyName, bool value) { - if (!InputAccessMapping.contains(keyName)) { + auto [map, acl_map] = boost::synchronize(SettingsMap, InputAccessMapping); + if (!acl_map->contains(keyName)) { throw std::logic_error { "Unknown key name accessed in Settings::setConsoleInputAccessMapping" }; - } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::noaccess) { + } else if (acl_map->at(keyName).second == SettingsAccessMask::noaccess) { throw std::logic_error { "Key '" + keyName.Category + " > " + keyName.Key + "' is not accessible from within the runtime!" }; - } else if (InputAccessMapping.at(keyName).second == SettingsAccessMask::read) { + } else if (acl_map->at(keyName).second == SettingsAccessMask::read) { throw std::logic_error { "Key '" + keyName.Category + " > " + keyName.Key + "' is not writeable from within the runtime!" }; } - Key key = InputAccessMapping.at(keyName).first; + Key key = acl_map->at(keyName).first; - if (!std::holds_alternative(SettingsMap.at(key))) { + if (!std::holds_alternative(map->at(key))) { throw std::logic_error { "Wrong value type in Settings::setConsoleInputAccessMapping: expected bool" }; } - SettingsMap.at(key) = value; + map->at(key) = value; } };