# TaskManager ## Basic Usage ### Including Required Headers ```cpp #include // For std::bind #include "TaskManager.h" ``` ### Registering Member Functions ```cpp class MyClass { public: void myMethod() { Serial.println("My method called"); } void methodWithParams(int value, String text) { Serial.printf("Method called with %d and %s\n", value, text.c_str()); } }; // Create an instance MyClass myObject; // Register member function taskManager.registerTask("my_task", 1000, std::bind(&MyClass::myMethod, &myObject)); // Register method with parameters taskManager.registerTask("param_task", 2000, std::bind(&MyClass::methodWithParams, &myObject, 42, "hello")); ``` ### Registering Lambda Functions ```cpp // Simple lambda taskManager.registerTask("lambda_task", 3000, []() { Serial.println("Lambda executed"); }); // Lambda with capture int counter = 0; taskManager.registerTask("counter_task", 4000, [&counter]() { counter++; Serial.printf("Counter: %d\n", counter); }); // Lambda that calls multiple methods taskManager.registerTask("multi_task", 5000, [&myObject]() { myObject.myMethod(); // Do other work... }); ``` ### Registering Global Functions ```cpp void globalFunction() { Serial.println("Global function called"); } // Still supported for backward compatibility taskManager.registerTask("global_task", 6000, globalFunction); ``` ## Advanced Examples ### Binding to Different Object Types ```cpp class NetworkManager { public: void sendHeartbeat() { /* ... */ } void checkConnection() { /* ... */ } }; class SensorManager { public: void readSensors() { /* ... */ } void calibrate() { /* ... */ } }; NetworkManager network; SensorManager sensors; // Bind to different objects taskManager.registerTask("heartbeat", 1000, std::bind(&NetworkManager::sendHeartbeat, &network)); taskManager.registerTask("sensor_read", 500, std::bind(&SensorManager::readSensors, &sensors)); ``` ### Using std::placeholders for Complex Binding ```cpp #include class ConfigManager { public: void updateConfig(int interval, bool enabled) { Serial.printf("Updating config: interval=%d, enabled=%d\n", interval, enabled); } }; ConfigManager config; // Use placeholders for complex parameter binding using namespace std::placeholders; taskManager.registerTask("config_update", 10000, std::bind(&ConfigManager::updateConfig, &config, _1, _2)); ``` ### Conditional Task Execution ```cpp class TaskController { public: bool shouldExecute() { return millis() % 10000 < 5000; // Execute only in first 5 seconds of each 10-second cycle } void conditionalTask() { if (shouldExecute()) { Serial.println("Conditional task executed"); } } }; TaskController controller; taskManager.registerTask("conditional", 1000, std::bind(&TaskController::conditionalTask, &controller)); ``` ## Benefits of Using std::bind 1. **Cleaner Code**: No need for wrapper functions 2. **Direct Binding**: Bind member functions directly to objects 3. **Parameter Passing**: Easily pass parameters to bound methods 4. **Lambda Support**: Use lambdas for complex logic 5. **Type Safety**: Better type checking than function pointers 6. **Flexibility**: Mix and match different callable types ## Migration from Wrapper Functions ### Before (with wrapper functions): ```cpp void discoverySendTask() { cluster.sendDiscovery(); } void discoveryListenTask() { cluster.listenForDiscovery(); } taskManager.registerTask("discovery_send", interval, discoverySendTask); taskManager.registerTask("discovery_listen", interval, discoveryListenTask); ``` ### After (with std::bind): ```cpp taskManager.registerTask("discovery_send", interval, std::bind(&ClusterManager::sendDiscovery, &cluster)); taskManager.registerTask("discovery_listen", interval, std::bind(&ClusterManager::listenForDiscovery, &cluster)); ``` ## Performance Considerations - `std::bind` creates a callable object that may have a small overhead compared to direct function pointers - For high-frequency tasks, consider the performance impact - The overhead is typically negligible for most embedded applications - The TaskManager stores bound functions efficiently in a registry ## Compatibility - The new `std::bind` support is fully backward compatible - Existing code using function pointers will continue to work - You can mix both approaches in the same project - All existing TaskManager methods remain unchanged