diff --git a/examples/task_management_example.cpp b/examples/task_management_example.cpp index 142233e..4c6cd60 100644 --- a/examples/task_management_example.cpp +++ b/examples/task_management_example.cpp @@ -1,8 +1,8 @@ /* - * Task Management Example with std::bind + * Task Management Example with std::bind and Class-Based Registration * * This example demonstrates how to use the TaskManager with std::bind - * to register member functions, lambdas, and other callable objects. + * and how classes can register their own tasks. */ #include @@ -10,23 +10,101 @@ #include "TaskManager.h" #include "NodeContext.h" -// Example class with methods that can be bound -class ExampleClass { +// Example service class that registers its own tasks +class SensorService { public: - void method1() { - Serial.println("[ExampleClass] Method 1 called"); + SensorService(NodeContext& ctx, TaskManager& taskMgr) : ctx(ctx), taskManager(taskMgr) { + // Register all sensor-related tasks in constructor + registerTasks(); } - void method2() { - Serial.println("[ExampleClass] Method 2 called"); + void readTemperature() { + Serial.println("[SensorService] Reading temperature"); + // Simulate temperature reading + temperature = random(20, 30); + Serial.printf("[SensorService] Temperature: %d°C\n", temperature); } - void methodWithParam(int value) { - Serial.printf("[ExampleClass] Method with param called: %d\n", value); + void readHumidity() { + Serial.println("[SensorService] Reading humidity"); + // Simulate humidity reading + humidity = random(40, 80); + Serial.printf("[SensorService] Humidity: %d%%\n", humidity); } + + void calibrateSensors() { + Serial.println("[SensorService] Calibrating sensors"); + // Simulate calibration + calibrationOffset = random(-2, 3); + Serial.printf("[SensorService] Calibration offset: %d\n", calibrationOffset); + } + + void printStatus() { + Serial.printf("[SensorService] Status - Temp: %d°C, Humidity: %d%%, Offset: %d\n", + temperature, humidity, calibrationOffset); + } + +private: + void registerTasks() { + // Register all sensor tasks using std::bind + taskManager.registerTask("temp_read", 2000, + std::bind(&SensorService::readTemperature, this)); + taskManager.registerTask("humidity_read", 3000, + std::bind(&SensorService::readHumidity, this)); + taskManager.registerTask("calibrate", 10000, + std::bind(&SensorService::calibrateSensors, this)); + taskManager.registerTask("status_print", 5000, + std::bind(&SensorService::printStatus, this)); + + Serial.println("[SensorService] Registered all sensor tasks"); + } + + NodeContext& ctx; + TaskManager& taskManager; + int temperature = 25; + int humidity = 60; + int calibrationOffset = 0; }; -// Example custom task functions (legacy style) +// Example network service class +class NetworkService { +public: + NetworkService(NodeContext& ctx, TaskManager& taskMgr) : ctx(ctx), taskManager(taskMgr) { + registerTasks(); + } + + void checkConnection() { + Serial.println("[NetworkService] Checking WiFi connection"); + if (WiFi.status() == WL_CONNECTED) { + Serial.printf("[NetworkService] Connected to %s\n", WiFi.SSID().c_str()); + } else { + Serial.println("[NetworkService] WiFi disconnected"); + } + } + + void sendHeartbeat() { + Serial.println("[NetworkService] Sending heartbeat"); + // Simulate heartbeat + heartbeatCount++; + Serial.printf("[NetworkService] Heartbeat #%d sent\n", heartbeatCount); + } + +private: + void registerTasks() { + taskManager.registerTask("connection_check", 5000, + std::bind(&NetworkService::checkConnection, this)); + taskManager.registerTask("heartbeat", 8000, + std::bind(&NetworkService::sendHeartbeat, this)); + + Serial.println("[NetworkService] Registered all network tasks"); + } + + NodeContext& ctx; + TaskManager& taskManager; + int heartbeatCount = 0; +}; + +// Example custom task functions (legacy style - still supported) void customTask1() { Serial.println("[CustomTask1] Executing custom task 1"); } @@ -41,45 +119,26 @@ void periodicMaintenance() { void setup() { Serial.begin(115200); - Serial.println("Task Management Example with std::bind"); + Serial.println("Task Management Example with Class-Based Registration"); // Create context and task manager NodeContext ctx; TaskManager taskManager(ctx); - // Create an instance of our example class - ExampleClass example; + // Create service instances - they will register their own tasks + SensorService sensors(ctx, taskManager); + NetworkService network(ctx, taskManager); - // Method 1: Register tasks using std::bind for member functions - taskManager.registerTask("member_method_1", 2000, - std::bind(&ExampleClass::method1, &example)); - - taskManager.registerTask("member_method_2", 3000, - std::bind(&ExampleClass::method2, &example)); - - // Method 2: Register a task with a lambda that calls a method with parameters - taskManager.registerTask("method_with_param", 4000, - std::bind([](ExampleClass* obj) { - obj->methodWithParam(42); - }, &example)); - - // Method 3: Register legacy global functions (still supported) - taskManager.registerTask("custom_task_1", 5000, customTask1); - taskManager.registerTask("custom_task_2", 10000, customTask2); + // Register additional custom tasks (legacy style) + taskManager.registerTask("custom_task_1", 12000, customTask1); + taskManager.registerTask("custom_task_2", 15000, customTask2); taskManager.registerTask("maintenance", 30000, periodicMaintenance); - // Method 4: Register a lambda function directly + // Register a lambda function directly taskManager.registerTask("lambda_function", 6000, []() { Serial.println("[Lambda] Lambda function called"); }); - // Method 5: Register a task that calls multiple methods - taskManager.registerTask("multi_method", 7000, - std::bind([](ExampleClass* obj) { - obj->method1(); - obj->method2(); - }, &example)); - // Initialize and start all tasks taskManager.initialize(); @@ -87,12 +146,10 @@ void setup() { taskManager.printTaskStatus(); Serial.println("\n=== Task Registration Examples ==="); - Serial.println("1. member_method_1: Uses std::bind(&ExampleClass::method1, &example)"); - Serial.println("2. member_method_2: Uses std::bind(&ExampleClass::method2, &example)"); - Serial.println("3. method_with_param: Uses lambda with std::bind for parameter passing"); - Serial.println("4. custom_task_1: Legacy global function registration"); - Serial.println("5. lambda_function: Direct lambda registration"); - Serial.println("6. multi_method: Lambda that calls multiple methods"); + Serial.println("1. SensorService: Registers its own tasks in constructor"); + Serial.println("2. NetworkService: Registers its own tasks in constructor"); + Serial.println("3. Custom tasks: Legacy function registration"); + Serial.println("4. Lambda function: Direct lambda registration"); Serial.println("=====================================\n"); } diff --git a/src/ClusterManager.cpp b/src/ClusterManager.cpp index 8792e39..dca56fc 100644 --- a/src/ClusterManager.cpp +++ b/src/ClusterManager.cpp @@ -1,6 +1,6 @@ #include "ClusterManager.h" -ClusterManager::ClusterManager(NodeContext& ctx) : ctx(ctx) { +ClusterManager::ClusterManager(NodeContext& ctx, TaskManager& taskMgr) : ctx(ctx), taskManager(taskMgr) { // Register callback for node_discovered event ctx.on("node_discovered", [this](void* data) { NodeInfo* node = static_cast(data); @@ -8,6 +8,27 @@ ClusterManager::ClusterManager(NodeContext& ctx) : ctx(ctx) { }); } +void ClusterManager::registerTasks() { + // Register all cluster-related tasks using std::bind + taskManager.registerTask("discovery_send", ctx.config.discovery_interval_ms, + std::bind(&ClusterManager::sendDiscovery, this)); + taskManager.registerTask("discovery_listen", ctx.config.discovery_interval_ms / 10, + std::bind(&ClusterManager::listenForDiscovery, this)); + taskManager.registerTask("status_update", ctx.config.status_update_interval_ms, + std::bind([](ClusterManager* cm) { + cm->updateAllNodeStatuses(); + cm->removeDeadNodes(); + }, this)); + taskManager.registerTask("print_members", ctx.config.print_interval_ms, + std::bind(&ClusterManager::printMemberList, this)); + taskManager.registerTask("heartbeat", ctx.config.heartbeat_interval_ms, + std::bind(&ClusterManager::heartbeatTaskCallback, this)); + taskManager.registerTask("update_members_info", ctx.config.member_info_update_interval_ms, + std::bind(&ClusterManager::updateAllMembersInfoTaskCallback, this)); + + Serial.println("[ClusterManager] Registered all cluster tasks"); +} + void ClusterManager::sendDiscovery() { //Serial.println("[Cluster] Sending discovery packet..."); ctx.udp->beginPacket("255.255.255.255", ctx.config.udp_port); diff --git a/src/ClusterManager.h b/src/ClusterManager.h index 5953b42..725b040 100644 --- a/src/ClusterManager.h +++ b/src/ClusterManager.h @@ -2,6 +2,7 @@ #include "Globals.h" #include "NodeContext.h" #include "NodeInfo.h" +#include "TaskManager.h" #include #include #include @@ -10,7 +11,8 @@ class ClusterManager { public: - ClusterManager(NodeContext& ctx); + ClusterManager(NodeContext& ctx, TaskManager& taskMgr); + void registerTasks(); void sendDiscovery(); void listenForDiscovery(); void addOrUpdateNode(const String& nodeHost, IPAddress nodeIP); @@ -24,4 +26,5 @@ public: void updateAllMembersInfoTaskCallback(); private: NodeContext& ctx; + TaskManager& taskManager; }; diff --git a/src/main.cpp b/src/main.cpp index ea5bd3a..4e810aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,30 +11,16 @@ using namespace std; NodeContext ctx; NetworkManager network(ctx); -ClusterManager cluster(ctx); TaskManager taskManager(ctx); +ClusterManager cluster(ctx, taskManager); ApiServer apiServer(ctx, taskManager, ctx.config.api_server_port); void setup() { // Setup WiFi first network.setupWiFi(); - // Register all system tasks using std::bind for member functions - taskManager.registerTask("discovery_send", ctx.config.discovery_interval_ms, - std::bind(&ClusterManager::sendDiscovery, &cluster)); - taskManager.registerTask("discovery_listen", ctx.config.discovery_interval_ms / 10, - std::bind(&ClusterManager::listenForDiscovery, &cluster)); - taskManager.registerTask("status_update", ctx.config.status_update_interval_ms, - std::bind([](ClusterManager* cm) { - cm->updateAllNodeStatuses(); - cm->removeDeadNodes(); - }, &cluster)); - taskManager.registerTask("print_members", ctx.config.print_interval_ms, - std::bind(&ClusterManager::printMemberList, &cluster)); - taskManager.registerTask("heartbeat", ctx.config.heartbeat_interval_ms, - std::bind(&ClusterManager::heartbeatTaskCallback, &cluster)); - taskManager.registerTask("update_members_info", ctx.config.member_info_update_interval_ms, - std::bind(&ClusterManager::updateAllMembersInfoTaskCallback, &cluster)); + // Register tasks in their respective classes + cluster.registerTasks(); // Initialize and start all tasks taskManager.initialize();