feat: implement Spore framework class as main orchestration layer

- Add Spore class as unified interface for all core framework functionality
- Implement setup() and begin() methods for flexible initialization pattern
- Add service registration with addService() for both raw and smart pointers
- Provide accessor methods for core components (getTaskManager, getContext, etc.)
- Automatically include core services (Node, Network, Cluster, Task)
- Update all examples to use simplified Spore framework approach
- Fix circular dependency issues in include structure
- Remove setHostname and setApiPort configuration methods
- Add comprehensive documentation and usage examples

The Spore class encapsulates all core functionality from the base example
and provides a clean, unified API for the entire framework. Examples now
use just spore.setup() -> add services -> spore.begin() -> spore.loop().
This commit is contained in:
2025-09-13 21:17:54 +02:00
parent 72b559e047
commit bf17684dc6
12 changed files with 356 additions and 184 deletions

View File

@@ -1,4 +1,5 @@
#include "ClusterManager.h"
#include "Globals.h"
ClusterManager::ClusterManager(NodeContext& ctx, TaskManager& taskMgr) : ctx(ctx), taskManager(taskMgr) {
// Register callback for node_discovered event

View File

@@ -1,4 +1,5 @@
#include "NodeInfo.h"
#include "Globals.h"
const char* statusToStr(NodeInfo::Status status) {
switch (status) {

153
src/Spore.cpp Normal file
View File

@@ -0,0 +1,153 @@
#include "Spore.h"
#include "services/NodeService.h"
#include "services/NetworkService.h"
#include "services/ClusterService.h"
#include "services/TaskService.h"
#include <Arduino.h>
Spore::Spore() : ctx(), network(ctx), taskManager(ctx), cluster(ctx, taskManager),
apiServer(ctx, taskManager, ctx.config.api_server_port),
initialized(false), apiServerStarted(false) {
}
Spore::Spore(std::initializer_list<std::pair<String, String>> initialLabels)
: ctx(initialLabels), network(ctx), taskManager(ctx), cluster(ctx, taskManager),
apiServer(ctx, taskManager, ctx.config.api_server_port),
initialized(false), apiServerStarted(false) {
}
Spore::~Spore() {
// Services will be automatically cleaned up by shared_ptr
}
void Spore::setup() {
if (initialized) {
Serial.println("[Spore] Already initialized, skipping setup");
return;
}
Serial.begin(115200);
Serial.println("[Spore] Starting Spore framework...");
// Initialize core components
initializeCore();
// Register core services
registerCoreServices();
initialized = true;
Serial.println("[Spore] Framework setup complete - call begin() to start API server");
}
void Spore::begin() {
if (!initialized) {
Serial.println("[Spore] Framework not initialized, call setup() first");
return;
}
if (apiServerStarted) {
Serial.println("[Spore] API server already started");
return;
}
Serial.println("[Spore] Starting API server...");
// Start API server
startApiServer();
// Print initial task status
taskManager.printTaskStatus();
Serial.println("[Spore] Framework ready!");
}
void Spore::loop() {
if (!initialized) {
Serial.println("[Spore] Framework not initialized, call setup() first");
return;
}
taskManager.execute();
yield();
}
void Spore::addService(std::shared_ptr<Service> service) {
if (!service) {
Serial.println("[Spore] Warning: Attempted to add null service");
return;
}
services.push_back(service);
if (apiServerStarted) {
// If API server is already started, register the service immediately
apiServer.addService(*service);
Serial.printf("[Spore] Added service '%s' to running API server\n", service->getName());
} else {
Serial.printf("[Spore] Registered service '%s' (will be added to API server when begin() is called)\n", service->getName());
}
}
void Spore::addService(Service* service) {
if (!service) {
Serial.println("[Spore] Warning: Attempted to add null service");
return;
}
// Wrap raw pointer in shared_ptr with no-op deleter to avoid double-delete
addService(std::shared_ptr<Service>(service, [](Service*){}));
}
void Spore::initializeCore() {
Serial.println("[Spore] Initializing core components...");
// Setup WiFi first
network.setupWiFi();
// Initialize task manager
taskManager.initialize();
Serial.println("[Spore] Core components initialized");
}
void Spore::registerCoreServices() {
Serial.println("[Spore] Registering core services...");
// Create core services
auto nodeService = std::make_shared<NodeService>(ctx, apiServer);
auto networkService = std::make_shared<NetworkService>(network);
auto clusterService = std::make_shared<ClusterService>(ctx);
auto taskService = std::make_shared<TaskService>(taskManager);
// Add to services list
services.push_back(nodeService);
services.push_back(networkService);
services.push_back(clusterService);
services.push_back(taskService);
Serial.println("[Spore] Core services registered");
}
void Spore::startApiServer() {
if (apiServerStarted) {
Serial.println("[Spore] API server already started");
return;
}
Serial.println("[Spore] Starting API server...");
// Register all services with API server
for (auto& service : services) {
if (service) {
apiServer.addService(*service);
Serial.printf("[Spore] Added service '%s' to API server\n", service->getName());
}
}
// Start the API server
apiServer.begin();
apiServerStarted = true;
Serial.println("[Spore] API server started");
}