From bfbbeffcfdd47c2bedd843889f5175a3d238d5e7 Mon Sep 17 00:00:00 2001 From: Torrie Fischer Date: Sun, 19 Feb 2023 18:41:55 +0100 Subject: [PATCH] config: fix crashes, implement fallback profiles --- src/Config.cpp | 62 ++++++++++++++++++++++++++++++++++---------------- src/Config.h | 4 ++-- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/Config.cpp b/src/Config.cpp index a8b6907..faa18a6 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -9,7 +9,7 @@ #include #include -StaticJsonDocument<256> jsonConfig; +StaticJsonDocument<1024> jsonConfig; constexpr uint16_t HardwareConfig::MAX_LED_NUM; @@ -77,14 +77,20 @@ ConfigService::onStart() m_config = HardwareConfig{}; m_config.save(); } - if (strlen(m_config.data.loadedProfile) == 0) { - strcpy(m_config.data.loadedProfile, "default"); - } + + bool loaded = false; if (m_overrideProfile != nullptr) { - loadProfile(m_overrideProfile); - } else { - loadProfile(m_config.data.loadedProfile); + loaded = loadProfile(m_overrideProfile); + } + + if (!loaded && strlen(m_config.data.loadedProfile) > 0) { + loaded = loadProfile(m_config.data.loadedProfile); + } + + if (!loaded && !loadProfile("default")) { + Log.fatal("Could not load default fallback profile! No tasks will be started."); + m_jsonMap.loadDefault(); } } @@ -94,24 +100,24 @@ ConfigService::overrideProfile(const char* profileName) m_overrideProfile = profileName; } -void +bool ConfigService::loadMap(const String& mapName) { String fname = String("/maps/") + mapName + ".json"; if (LittleFS.exists(fname)) { File configFile = LittleFS.open(fname, "r"); - Log.notice("config: Loading coordinate map %s", mapName.c_str()); + Log.notice("config: Loading coordinate map from %s", fname.c_str()); deserializeJson(jsonConfig, configFile); configFile.close(); JsonArray strideList = jsonConfig["strides"]; m_jsonMap.load(strideList); + return true; } else { - Log.warning("config: Couldn't load coordinate map %s!!! Defaulting to linear mapping.", mapName.c_str()); - m_jsonMap.loadDefault(); + return false; } } -void +bool ConfigService::loadProfile(const char* profileName) { Log.notice("config: Loading profile %s...", profileName); @@ -119,11 +125,16 @@ ConfigService::loadProfile(const char* profileName) LittleFS.begin(); if (LittleFS.exists(fname)) { + strncpy(m_config.data.loadedProfile, fname.c_str(), sizeof(m_config.data.loadedProfile)); File configFile = LittleFS.open(fname, "r"); jsonConfig.clear(); deserializeJson(jsonConfig, configFile); configFile.close(); + //int profileLogLevel = max(0, min(6, jsonConfig["logLevel"])); + //Log.setLevel(profileLogLevel); + //Log.trace("config: \t %d logging level"); + JsonObject sceneList = jsonConfig["scenes"]; std::vector scenes; for(JsonPair pair : sceneList) { @@ -139,25 +150,37 @@ ConfigService::loadProfile(const char* profileName) JsonArray taskList = jsonConfig["tasks"]; Log.notice("config: Starting %d tasks", taskList.size()); for(int i = 0; i < taskList.size();i++) { - MainLoop::instance()->dispatch(InputEvent{InputEvent::StartThing, taskList[i].as()}); + MainLoop::instance()->dispatchSync(InputEvent{InputEvent::StartThing, taskList[i].as()}); + } + + JsonObject defaults = jsonConfig["defaults"]; + Log.notice("config: Loading %d app configurations", defaults.size()); + MainLoop::instance()->dispatchSync(InputEvent{InputEvent::ConfigurationChanged, &defaults}); + + String mapName = jsonConfig["surfaceMap"]; + + jsonConfig.clear(); + + if (mapName.isEmpty()) { + Log.warning("config: No coordinate map defined! Defaulting to linear mapping.", mapName.c_str()); + m_jsonMap.loadDefault(); + } else if (!loadMap(mapName)) { + Log.warning("config: Couldn't load coordinate map %s!!! Defaulting to linear mapping.", mapName.c_str()); + m_jsonMap.loadDefault(); } Log.notice("config: Loaded!"); } else { Log.warning("config: Could not load profile %s!", profileName); + return false; } - JsonObject defaults = jsonConfig["defaults"]; - MainLoop::instance()->dispatch(InputEvent{InputEvent::ConfigurationChanged, &defaults}); - - String configName = jsonConfig["surfaceMap"]; - jsonConfig.clear(); - loadMap(configName); LittleFS.end(); Log.notice("config: Configured to use %d pixels", m_jsonMap.physicalPixelCount()); PhysicalCoordinates topLeft = m_jsonMap.virtualToPhysicalCoords({0, 0}); PhysicalCoordinates bottomRight = m_jsonMap.virtualToPhysicalCoords({255, 255}); Log.verbose(" (0,0) -> (%d, %d) -> %d", topLeft.x, topLeft.y, m_jsonMap.physicalCoordsToIndex(topLeft)); Log.verbose(" (255,255) -> (%d, %d) -> %d", bottomRight.x, bottomRight.y, m_jsonMap.physicalCoordsToIndex(bottomRight)); + return true; } void @@ -177,7 +200,6 @@ ConfigService::handleEvent(const InputEvent &evt) switch(evt.intent) { case InputEvent::LoadConfigurationByName: Log.notice("Reloading configuration %s", evt.asString()); - strcpy(m_config.data.loadedProfile, evt.asString()); loadProfile(evt.asString()); case InputEvent::SaveConfigurationRequest: Log.notice("Saving configuration"); diff --git a/src/Config.h b/src/Config.h index 058f59a..2a36d69 100644 --- a/src/Config.h +++ b/src/Config.h @@ -44,6 +44,6 @@ private: JsonCoordinateMapping m_jsonMap; const char* m_overrideProfile = nullptr; - void loadProfile(const char* name); - void loadMap(const String& mapName); + bool loadProfile(const char* name); + bool loadMap(const String& mapName); };