From cf51ab71a25cbb60ebcf13edd4b7413c23264128 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Thu, 17 Mar 2022 15:53:45 +0100 Subject: input basics --- src/config/ConfigManager.cpp | 201 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 src/config/ConfigManager.cpp (limited to 'src/config/ConfigManager.cpp') diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp new file mode 100644 index 00000000..eccad341 --- /dev/null +++ b/src/config/ConfigManager.cpp @@ -0,0 +1,201 @@ +#include "ConfigManager.hpp" + +#include +#include +#include +#include + +#include +#include +#include + +CConfigManager::CConfigManager() { + configValues["general:max_fps"].intValue = 240; + + configValues["general:border_size"].intValue = 1; + configValues["general:gaps_in"].intValue = 5; + configValues["general:gaps_out"].intValue = 20; + + loadConfigLoadVars(); + + isFirstLaunch = false; +} + +void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::string& VALUE) { + if (configValues.find(COMMAND) == configValues.end()) { + parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field."; + return; + } + + auto& CONFIGENTRY = configValues.at(COMMAND); + if (CONFIGENTRY.intValue != -1) { + try { + if (VALUE.find("0x") == 0) { + // Values with 0x are hex + const auto VALUEWITHOUTHEX = VALUE.substr(2); + CONFIGENTRY.intValue = stol(VALUEWITHOUTHEX, nullptr, 16); + } else + CONFIGENTRY.intValue = stol(VALUE); + } catch (...) { + Debug::log(WARN, "Error reading value of %s", COMMAND.c_str()); + parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">."; + } + } else if (CONFIGENTRY.floatValue != -1) { + try { + CONFIGENTRY.floatValue = stof(VALUE); + } catch (...) { + Debug::log(WARN, "Error reading value of %s", COMMAND.c_str()); + parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">."; + } + } else if (CONFIGENTRY.strValue != "") { + try { + CONFIGENTRY.strValue = VALUE; + } catch (...) { + Debug::log(WARN, "Error reading value of %s", COMMAND.c_str()); + parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">."; + } + } +} + +void CConfigManager::handleRawExec(const std::string& command, const std::string& args) { + // Exec in the background dont wait for it. + if (fork() == 0) { + execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr); + + _exit(0); + } +} + +void CConfigManager::parseLine(std::string& line) { + // first check if its not a comment + const auto COMMENTSTART = line.find_first_of('#'); + if (COMMENTSTART == 0) + return; + + // now, cut the comment off + if (COMMENTSTART != std::string::npos) + line = line.substr(0, COMMENTSTART); + + // remove shit at the beginning + while (line[0] == ' ' || line[0] == '\t') { + line = line.substr(1); + } + + if (line.find(" {") != std::string::npos) { + auto cat = line.substr(0, line.find(" {")); + transform(cat.begin(), cat.end(), cat.begin(), ::tolower); + currentCategory = cat; + return; + } + + if (line.find("}") != std::string::npos && currentCategory != "") { + currentCategory = ""; + return; + } + + // And parse + // check if command + const auto EQUALSPLACE = line.find_first_of('='); + + if (EQUALSPLACE == std::string::npos) + return; + + const auto COMMAND = line.substr(0, EQUALSPLACE); + const auto VALUE = line.substr(EQUALSPLACE + 1); + + if (COMMAND == "exec") { + handleRawExec(COMMAND, VALUE); + return; + } else if (COMMAND == "exec-once") { + if (isFirstLaunch) { + handleRawExec(COMMAND, VALUE); + return; + } + } + + configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE); +} + +void CConfigManager::loadConfigLoadVars() { + Debug::log(LOG, "Reloading the config!"); + parseError = ""; // reset the error + currentCategory = ""; // reset the category + + const char* const ENVHOME = getenv("HOME"); + const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf"); + + std::ifstream ifs; + ifs.open(CONFIGPATH.c_str()); + + if (!ifs.good()) { + Debug::log(WARN, "Config reading error. (No file?)"); + parseError = "The config could not be read. (No file?)"; + + ifs.close(); + return; + } + + std::string line = ""; + int linenum = 1; + if (ifs.is_open()) { + while (std::getline(ifs, line)) { + // Read line by line. + try { + parseLine(line); + } catch (...) { + Debug::log(ERR, "Error reading line from config. Line:"); + Debug::log(NONE, "%s", line.c_str()); + + parseError = "Config error at line " + std::to_string(linenum) + ": Line parsing error."; + } + + if (parseError != "" && parseError.find("Config error at line") != 0) { + parseError = "Config error at line " + std::to_string(linenum) + ": " + parseError; + } + + ++linenum; + } + + ifs.close(); + } +} + +void CConfigManager::tick() { + const char* const ENVHOME = getenv("HOME"); + + const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprd.conf" : (std::string) "/.config/hypr/hypr.conf"); + + struct stat fileStat; + int err = stat(CONFIGPATH.c_str(), &fileStat); + if (err != 0) { + Debug::log(WARN, "Error at ticking config, error %i", errno); + } + + // check if we need to reload cfg + if (fileStat.st_mtime != lastModifyTime) { + lastModifyTime = fileStat.st_mtime; + + loadConfigLoadVars(); + } +} + +std::mutex configmtx; +SConfigValue CConfigManager::getConfigValueSafe(std::string val) { + std::lock_guard lg(configmtx); + + SConfigValue copy = configValues[val]; + + return copy; +} + +int CConfigManager::getInt(std::string v) { + return getConfigValueSafe(v).intValue; +} + +float CConfigManager::getFloat(std::string v) { + return getConfigValueSafe(v).floatValue; +} + +std::string CConfigManager::getString(std::string v) { + return getConfigValueSafe(v).strValue; +} -- cgit v1.2.3