diff --git a/src/patrix/core/Config.h b/src/patrix/core/Config.h index b60e853..d15a746 100644 --- a/src/patrix/core/Config.h +++ b/src/patrix/core/Config.h @@ -15,14 +15,14 @@ class Config final { const String path; - JsonDocument config; - unsigned long dirty = 0; bool doForceNextHexBuffer = true; public: + JsonDocument json; + explicit Config(String path) : path(std::move(path)) { // } @@ -37,8 +37,8 @@ public: return; } if (!deserialize(file)) { - config.clear(); - config = config.to(); + json.clear(); + json = json.to(); } file.close(); } @@ -50,10 +50,10 @@ public: error("Failed to open file for config write: %s", path.c_str()); return; } - const auto size = measureJson(config); - if (serializeJson(config, write) == size) { + const auto size = measureJson(json); + if (serializeJson(json, write) == size) { char buffer[256]; - serializeJson(config, buffer, sizeof buffer); + serializeJson(json, buffer, sizeof buffer); info("Config written: %s => %s", path.c_str(), buffer); } else { error("Failed to write config: %s", path.c_str()); @@ -68,19 +68,24 @@ public: } } + template + bool has(const char *key) { + return json[key].is(); + } + template T get(const char *key, T fallback) { - if (config[key].is()) { - return config[key].as(); + if (json[key].is()) { + return json[key].as(); } warn("Config key \"%s\" not found!", key); return fallback; } bool setIfNot(const char *key, const int value) { - auto changed = !config[key].is(); + auto changed = !json[key].is(); if (!changed) { - changed = config[key].as() != value; + changed = json[key].as() != value; } if (changed) { set(key, value); @@ -90,9 +95,9 @@ public: } bool setIfNot(const char *key, const double value) { - auto changed = !config[key].is(); + auto changed = !json[key].is(); if (!changed) { - changed = config[key].as() != value; + changed = json[key].as() != value; } if (changed) { set(key, value); @@ -102,26 +107,44 @@ public: } template - void set(const char *key, T value) { - config[key] = value; - dirty = max(1UL, millis()); // avoid special value zero (=> not dirty) + void set(const String& key, T value) { + json[key] = value; + dirty = millis(); + if (dirty == 0) { + // avoid special value zero (=> not dirty) + dirty--; + } + } + + unsigned long getAutoWriteInMillis() const { + if (dirty == 0) { + return 0; + } + return CONFIG_WRITE_DELAY_MILLIS - (millis() - dirty); + } + + time_t getAutoWriteAtEpoch() const { + if (dirty == 0) { + return 0; + } + return time(nullptr) + static_cast(getAutoWriteInMillis() / 1000); } private: bool deserialize(File file) { - if (deserializeJson(config, file) != DeserializationError::Ok) { + if (deserializeJson(json, file) != DeserializationError::Ok) { error("Failed to deserialize config: %s", file.path()); return false; } - if (!config.is()) { + if (!json.is()) { error("Config not a json-object: %s", file.path()); return false; } char buffer[256]; - serializeJson(config, buffer, sizeof buffer); + serializeJson(json, buffer, sizeof buffer); info("Config loaded: %s => %s", path.c_str(), buffer); - config = config.as(); + json = json.as(); return true; }