From f164bf86528c185d611b17f14799c13a26ccf013 Mon Sep 17 00:00:00 2001
From: Jochen Vothknecht <jochen3120@gmail.com>
Date: Sun, 19 Jun 2022 00:34:33 +0200
Subject: [PATCH] ST: Add service listing

---
 CLC-qthing/SiliconTorch/Service/Service.cpp   |  6 +-
 CLC-qthing/SiliconTorch/Service/Service.hpp   |  2 +
 .../SiliconTorch/Service/ServiceManager.cpp   | 92 ++++++++++++++++++-
 .../SiliconTorch/Service/ServiceManager.hpp   |  6 ++
 4 files changed, 98 insertions(+), 8 deletions(-)

diff --git a/CLC-qthing/SiliconTorch/Service/Service.cpp b/CLC-qthing/SiliconTorch/Service/Service.cpp
index ea39bed..d42151a 100644
--- a/CLC-qthing/SiliconTorch/Service/Service.cpp
+++ b/CLC-qthing/SiliconTorch/Service/Service.cpp
@@ -69,10 +69,6 @@ namespace SiliconTorch {
       }
     }
 
-    // u16 Service::startOrder() {
-    //   return 1337;  // actually a sane default 😏
-    // }
-
 
     void Service::setName(const str& name) {
       if (!attrsLocked) {
@@ -92,7 +88,7 @@ namespace SiliconTorch {
 
     void Service::setStartOrder(u16 startOrder) {
       if (!attrsLocked) {
-      this->startOrder = startOrder;
+        this->startOrder = startOrder;
       } else {
         // TODO: report error somehow?
       }
diff --git a/CLC-qthing/SiliconTorch/Service/Service.hpp b/CLC-qthing/SiliconTorch/Service/Service.hpp
index 668c194..c134212 100644
--- a/CLC-qthing/SiliconTorch/Service/Service.hpp
+++ b/CLC-qthing/SiliconTorch/Service/Service.hpp
@@ -38,6 +38,8 @@ namespace SiliconTorch {
         // internal stuff, only to be called by ServiceManager!
         void postInit();
 
+
+        // To be implemented by user!
         virtual void start()     = 0;
         virtual void stop()      = 0;
 
diff --git a/CLC-qthing/SiliconTorch/Service/ServiceManager.cpp b/CLC-qthing/SiliconTorch/Service/ServiceManager.cpp
index dc47dc3..ec5fe5b 100644
--- a/CLC-qthing/SiliconTorch/Service/ServiceManager.cpp
+++ b/CLC-qthing/SiliconTorch/Service/ServiceManager.cpp
@@ -9,6 +9,8 @@
 
 // ESP32 specific
 #include "esp_log.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
 
 // project specific
 #include <Types.hpp>
@@ -35,24 +37,108 @@ namespace SiliconTorch {
 
       registrationLocked = true;
 
+      // TODO: start services!
+
+      printServiceTable();
 
     }
 
-    void ServiceManager::startEnabledServices() {
+    std::vector<Service*> ServiceManager::getServicesInStartOrder() {
       std::vector<Service*> services;
 
-      for (const auto& [key, value] : serviceMap)
-        services.push_back(value);
+      for (const auto& [_, service] : serviceMap)
+        services.push_back(service);
 
       std::sort(services.begin(), services.end(), [](const Service* x, const Service* y) {
         return x->getStartOrder() < y->getStartOrder();
       });
 
+      return services;
+    }
+
+    void ServiceManager::startEnabledServices() {
+      std::vector<Service*> services = getServicesInStartOrder();
+
       for (const auto& service : services)
         if (service->isEnabled()) service->start();
     }
 
 
+    void ServiceManager::printServiceTable() {
+
+      // burn a few cycles because Espressivs logging is mehr :/
+      // while (xTaskGetTickCount() * portTICK_PERIOD_MS < 1000) {
+      //   vTaskDelay(42 / portTICK_PERIOD_MS);
+      // }
+      vTaskDelay(100 / portTICK_PERIOD_MS);
+
+      // helper function, never used outside of this
+      // TODO: should we move it to utils…?
+      auto strmul = [](const str& target, u32 count) {
+        str out = "";
+
+        for (u32 n = 0; n < count; n++)
+          out += target;
+
+        return out;
+      };
+
+
+      u8 nameColSize = 4;  // size of "name"
+
+      for (const auto& [name, _] : serviceMap)
+        if (name.length() > nameColSize) nameColSize = name.length();
+
+      nameColSize += 2;  // padding
+
+
+      u8 startOrderColSize = 10 + 2;  // size of "StartOrder" + padding
+      u8 enabledColSize    =  8 + 2;  // size of "Enabled " + padding (must be even)
+
+
+      ESP_LOGI(TAG, "┌%s┬%s┬%s┐",
+        strmul("─", nameColSize).c_str(),
+        strmul("─", startOrderColSize).c_str(),
+        strmul("─", enabledColSize).c_str()
+      );
+
+      ESP_LOGI(TAG, "│ Name %s│ StartOrder %s│ Enabled  %s│",
+        strmul(" ", nameColSize - 4 - 2).c_str(),
+        strmul(" ", startOrderColSize - 10 - 2).c_str(),
+        strmul(" ", enabledColSize - 8 - 2).c_str()
+      );
+
+      ESP_LOGI(TAG, "╞%s╪%s╪%s╡",
+        strmul("═", nameColSize).c_str(),
+        strmul("═", startOrderColSize).c_str(),
+        strmul("═", enabledColSize).c_str()
+      );
+
+      std::vector<Service*> services = getServicesInStartOrder();
+
+      for (const auto& service : services) {
+        u8 nameSize = service->getName().length();
+        ESP_LOGI(TAG, "│ %s %s│ % 5d %s│%s%s%s│",
+          service->getName().c_str(),
+          strmul(" ", nameColSize - 2 - nameSize).c_str(),
+          service->getStartOrder(),
+          strmul(" ", startOrderColSize - 2 - 5).c_str(),
+          strmul(" ", (enabledColSize - 2) / 2).c_str(),
+          service->isEnabled() ? "✅" : "❌",
+          strmul(" ", (enabledColSize - 2) / 2).c_str()
+        );
+      }
+
+      ESP_LOGI(TAG, "└%s┴%s┴%s┘",
+        strmul("─", nameColSize).c_str(),
+        strmul("─", startOrderColSize).c_str(),
+        strmul("─", enabledColSize).c_str()
+      );
+
+    }
+
+
+
     void ServiceManager::setServiceEnabled(const str& name, bool enabled) {
       if (serviceMap.count(name) > 0) {
         serviceMap.at(name)->setEnabled(enabled);
diff --git a/CLC-qthing/SiliconTorch/Service/ServiceManager.hpp b/CLC-qthing/SiliconTorch/Service/ServiceManager.hpp
index 54cdeeb..3a487b6 100644
--- a/CLC-qthing/SiliconTorch/Service/ServiceManager.hpp
+++ b/CLC-qthing/SiliconTorch/Service/ServiceManager.hpp
@@ -2,6 +2,7 @@
 
 // C++ system level
 #include <map>
+#include <vector>
 // #include <cstring>     // memset, strncmp
 // #include <cstdlib>     // TODO: is this for memcpy?
 // #include <functional>
@@ -34,10 +35,15 @@ namespace SiliconTorch {
 
         void startEnabledServices();
 
+        void printServiceTable();
+
         void setServiceEnabled(const str& name, bool enabled);
         bool getServiceEnabled(const str& name);
 
 
+        std::vector<Service*> getServicesInStartOrder();
+
+
         void registerService(Service* s);
 
       private:
-- 
GitLab