feat: register tasks outside of main
This commit is contained in:
@@ -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
|
* 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 <Arduino.h>
|
#include <Arduino.h>
|
||||||
@@ -10,23 +10,101 @@
|
|||||||
#include "TaskManager.h"
|
#include "TaskManager.h"
|
||||||
#include "NodeContext.h"
|
#include "NodeContext.h"
|
||||||
|
|
||||||
// Example class with methods that can be bound
|
// Example service class that registers its own tasks
|
||||||
class ExampleClass {
|
class SensorService {
|
||||||
public:
|
public:
|
||||||
void method1() {
|
SensorService(NodeContext& ctx, TaskManager& taskMgr) : ctx(ctx), taskManager(taskMgr) {
|
||||||
Serial.println("[ExampleClass] Method 1 called");
|
// Register all sensor-related tasks in constructor
|
||||||
|
registerTasks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void method2() {
|
void readTemperature() {
|
||||||
Serial.println("[ExampleClass] Method 2 called");
|
Serial.println("[SensorService] Reading temperature");
|
||||||
|
// Simulate temperature reading
|
||||||
|
temperature = random(20, 30);
|
||||||
|
Serial.printf("[SensorService] Temperature: %d°C\n", temperature);
|
||||||
}
|
}
|
||||||
|
|
||||||
void methodWithParam(int value) {
|
void readHumidity() {
|
||||||
Serial.printf("[ExampleClass] Method with param called: %d\n", value);
|
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() {
|
void customTask1() {
|
||||||
Serial.println("[CustomTask1] Executing custom task 1");
|
Serial.println("[CustomTask1] Executing custom task 1");
|
||||||
}
|
}
|
||||||
@@ -41,45 +119,26 @@ void periodicMaintenance() {
|
|||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
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
|
// Create context and task manager
|
||||||
NodeContext ctx;
|
NodeContext ctx;
|
||||||
TaskManager taskManager(ctx);
|
TaskManager taskManager(ctx);
|
||||||
|
|
||||||
// Create an instance of our example class
|
// Create service instances - they will register their own tasks
|
||||||
ExampleClass example;
|
SensorService sensors(ctx, taskManager);
|
||||||
|
NetworkService network(ctx, taskManager);
|
||||||
|
|
||||||
// Method 1: Register tasks using std::bind for member functions
|
// Register additional custom tasks (legacy style)
|
||||||
taskManager.registerTask("member_method_1", 2000,
|
taskManager.registerTask("custom_task_1", 12000, customTask1);
|
||||||
std::bind(&ExampleClass::method1, &example));
|
taskManager.registerTask("custom_task_2", 15000, customTask2);
|
||||||
|
|
||||||
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);
|
|
||||||
taskManager.registerTask("maintenance", 30000, periodicMaintenance);
|
taskManager.registerTask("maintenance", 30000, periodicMaintenance);
|
||||||
|
|
||||||
// Method 4: Register a lambda function directly
|
// Register a lambda function directly
|
||||||
taskManager.registerTask("lambda_function", 6000, []() {
|
taskManager.registerTask("lambda_function", 6000, []() {
|
||||||
Serial.println("[Lambda] Lambda function called");
|
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
|
// Initialize and start all tasks
|
||||||
taskManager.initialize();
|
taskManager.initialize();
|
||||||
|
|
||||||
@@ -87,12 +146,10 @@ void setup() {
|
|||||||
taskManager.printTaskStatus();
|
taskManager.printTaskStatus();
|
||||||
|
|
||||||
Serial.println("\n=== Task Registration Examples ===");
|
Serial.println("\n=== Task Registration Examples ===");
|
||||||
Serial.println("1. member_method_1: Uses std::bind(&ExampleClass::method1, &example)");
|
Serial.println("1. SensorService: Registers its own tasks in constructor");
|
||||||
Serial.println("2. member_method_2: Uses std::bind(&ExampleClass::method2, &example)");
|
Serial.println("2. NetworkService: Registers its own tasks in constructor");
|
||||||
Serial.println("3. method_with_param: Uses lambda with std::bind for parameter passing");
|
Serial.println("3. Custom tasks: Legacy function registration");
|
||||||
Serial.println("4. custom_task_1: Legacy global function registration");
|
Serial.println("4. Lambda function: Direct lambda registration");
|
||||||
Serial.println("5. lambda_function: Direct lambda registration");
|
|
||||||
Serial.println("6. multi_method: Lambda that calls multiple methods");
|
|
||||||
Serial.println("=====================================\n");
|
Serial.println("=====================================\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "ClusterManager.h"
|
#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
|
// Register callback for node_discovered event
|
||||||
ctx.on("node_discovered", [this](void* data) {
|
ctx.on("node_discovered", [this](void* data) {
|
||||||
NodeInfo* node = static_cast<NodeInfo*>(data);
|
NodeInfo* node = static_cast<NodeInfo*>(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() {
|
void ClusterManager::sendDiscovery() {
|
||||||
//Serial.println("[Cluster] Sending discovery packet...");
|
//Serial.println("[Cluster] Sending discovery packet...");
|
||||||
ctx.udp->beginPacket("255.255.255.255", ctx.config.udp_port);
|
ctx.udp->beginPacket("255.255.255.255", ctx.config.udp_port);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "NodeContext.h"
|
#include "NodeContext.h"
|
||||||
#include "NodeInfo.h"
|
#include "NodeInfo.h"
|
||||||
|
#include "TaskManager.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
@@ -10,7 +11,8 @@
|
|||||||
|
|
||||||
class ClusterManager {
|
class ClusterManager {
|
||||||
public:
|
public:
|
||||||
ClusterManager(NodeContext& ctx);
|
ClusterManager(NodeContext& ctx, TaskManager& taskMgr);
|
||||||
|
void registerTasks();
|
||||||
void sendDiscovery();
|
void sendDiscovery();
|
||||||
void listenForDiscovery();
|
void listenForDiscovery();
|
||||||
void addOrUpdateNode(const String& nodeHost, IPAddress nodeIP);
|
void addOrUpdateNode(const String& nodeHost, IPAddress nodeIP);
|
||||||
@@ -24,4 +26,5 @@ public:
|
|||||||
void updateAllMembersInfoTaskCallback();
|
void updateAllMembersInfoTaskCallback();
|
||||||
private:
|
private:
|
||||||
NodeContext& ctx;
|
NodeContext& ctx;
|
||||||
|
TaskManager& taskManager;
|
||||||
};
|
};
|
||||||
|
|||||||
20
src/main.cpp
20
src/main.cpp
@@ -11,30 +11,16 @@ using namespace std;
|
|||||||
|
|
||||||
NodeContext ctx;
|
NodeContext ctx;
|
||||||
NetworkManager network(ctx);
|
NetworkManager network(ctx);
|
||||||
ClusterManager cluster(ctx);
|
|
||||||
TaskManager taskManager(ctx);
|
TaskManager taskManager(ctx);
|
||||||
|
ClusterManager cluster(ctx, taskManager);
|
||||||
ApiServer apiServer(ctx, taskManager, ctx.config.api_server_port);
|
ApiServer apiServer(ctx, taskManager, ctx.config.api_server_port);
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// Setup WiFi first
|
// Setup WiFi first
|
||||||
network.setupWiFi();
|
network.setupWiFi();
|
||||||
|
|
||||||
// Register all system tasks using std::bind for member functions
|
// Register tasks in their respective classes
|
||||||
taskManager.registerTask("discovery_send", ctx.config.discovery_interval_ms,
|
cluster.registerTasks();
|
||||||
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));
|
|
||||||
|
|
||||||
// Initialize and start all tasks
|
// Initialize and start all tasks
|
||||||
taskManager.initialize();
|
taskManager.initialize();
|
||||||
|
|||||||
Reference in New Issue
Block a user