#include "TaskSchedulerManager.h" //Schedule part TaskSchedulerManagerHelper::Schedule::Schedule() : _days(0xFE), _months(0xFFF0), _triggered(false), _triggerRightAway(true), _hasBeenTriggeredRightAway(false), _triggerType(TRIGGER_REPEAT), _mode(EVERY), _enabled(true), _millis(millis()), _everyMillis(1000), _dateTime(NULL) { } TaskSchedulerManagerHelper::Schedule::Schedule(const TaskSchedulerManagerHelper::Schedule &Object) : _days(Object._days), _months(Object._months), _triggered(Object._triggered), _triggerRightAway(Object._triggerRightAway), _hasBeenTriggeredRightAway(Object._hasBeenTriggeredRightAway), _triggerType(Object._triggerType), _mode(Object._mode), _enabled(Object._enabled), _millis(Object._millis), _everyMillis(Object._everyMillis), _dateTime(NULL) { if(Object._dateTime != NULL) _dateTime = new DateTime(*(Object._dateTime)); } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::scheduleBuilder() { return new TaskSchedulerManagerHelper::Schedule(); } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setMillis(uint32_t millis) { if(millis == 0)return this; _everyMillis = millis; delete _dateTime;_dateTime = NULL; return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setSeconds(uint32_t seconds) { return TaskSchedulerManagerHelper::Schedule::setMillis(seconds*1000); } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setDateTime(DateTime &dateTime) { _everyMillis = 0; delete _dateTime;_dateTime = NULL; _dateTime = new DateTime(dateTime); return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setDays(uint8_t days) { _days = days; return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setMonths(uint16_t months) { _months = months; return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setTriggerRightAway(boolean enabled) { _triggerRightAway = enabled; return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setTriggerType(TriggerType triggerType) { _triggerType = triggerType; return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setMode(Mode mode) { _mode = mode; return this; } TaskSchedulerManagerHelper::Schedule *TaskSchedulerManagerHelper::Schedule::setEnabled(boolean enabled) { _enabled = enabled; return this; } // TaskScheduleManager part TaskSchedulerManager::TaskSchedulerManager() : _nextTaskIndexToBeRun(0), _rtcManager(NULL) { } TaskSchedulerManager::TaskSchedulerManager(RtcManager &rtcManager) : _nextTaskIndexToBeRun(0), _rtcManager(&rtcManager) { } boolean TaskSchedulerManager::addTask(const char *name, TaskSchedulerManagerHelper::Schedule *schedule, boolean (*taskRoutine)(void*), void *pData) { boolean result = _taskDataDictio.add(name, new TaskData({*schedule, taskRoutine, pData})); delete schedule;schedule = NULL; return result; } boolean TaskSchedulerManager::addTask(uint16_t id, TaskSchedulerManagerHelper::Schedule *schedule, boolean (*taskRoutine)(void*), void *pData) { boolean result = _taskDataDictio.add(id, new TaskData({*schedule, taskRoutine, pData})); delete schedule;schedule = NULL; return result; } boolean TaskSchedulerManager::removeTask(const char *name) { return _taskDataDictio.remove(name); } boolean TaskSchedulerManager::removeTask(uint16_t id) { return _taskDataDictio.remove(id); } boolean TaskSchedulerManager::enableTask(const char *name) { _taskDataDictio(name)->schedule.setEnabled(true); } boolean TaskSchedulerManager::enableTask(uint16_t id) { char indiceToStr[10]; sprintf(indiceToStr,"%d", id); _taskDataDictio(indiceToStr)->schedule.setEnabled(true); } boolean TaskSchedulerManager::disableTask(const char *name) { _taskDataDictio(name)->schedule.setEnabled(false); } boolean TaskSchedulerManager::disableTask(uint16_t id) { char indiceToStr[10]; sprintf(indiceToStr,"%d", id); _taskDataDictio(indiceToStr)->schedule.setEnabled(false); } boolean TaskSchedulerManager::clearTask() { _taskDataDictio.clear(); } void TaskSchedulerManager::run() { if(_taskDataDictio.count() == 0)return; if(_nextTaskIndexToBeRun >= _taskDataDictio.count())_nextTaskIndexToBeRun = 0; TaskData *p = _taskDataDictio.getAt(_nextTaskIndexToBeRun); if(p == NULL)//Shouldn't happen return; if(p->schedule._enabled) { if(p->schedule._everyMillis != 0) { if(p->schedule._triggerRightAway && !p->schedule._hasBeenTriggeredRightAway)//No rollover possible { p->schedule._millis = millis(); p->schedule._hasBeenTriggeredRightAway = true; p->schedule._triggered = true; (*(p->taskRoutine))(p->pData); } else if(millis() >= p->schedule._millis) //Millis rollover ? { if(millis() - p->schedule._millis >= p->schedule._everyMillis) //No, we execute the task { p->schedule._millis = millis(); p->schedule._triggered = true; (*(p->taskRoutine))(p->pData); } } else //Millis rollover { //We compute the time elapsed during the rollover: unsigned long max_ul(~0), from_last_millis_to_max(max_ul - p->schedule._millis), total_elapsed_millis(from_last_millis_to_max + millis()); if(total_elapsed_millis >= p->schedule._everyMillis) { p->schedule._millis = millis(); p->schedule._triggered = true; (*(p->taskRoutine))(p->pData); } } } else //Probably AT mode task { } } if(p->schedule._triggerType != TaskSchedulerManagerHelper::Schedule::TRIGGER_ONCE_AND_DELETE)_nextTaskIndexToBeRun++; else if(p->schedule._triggerType == TaskSchedulerManagerHelper::Schedule::TRIGGER_ONCE_AND_DELETE && !(p->schedule._triggered))_nextTaskIndexToBeRun++; else if(p->schedule._triggerType == TaskSchedulerManagerHelper::Schedule::TRIGGER_ONCE_AND_DELETE && p->schedule._triggered) //If the task has to be deleted after it has been executed and if it has, we delete it { _taskDataDictio.removeAt(_nextTaskIndexToBeRun); } } const unsigned int TaskSchedulerManager::taskCount() { return _taskDataDictio.count(); } uint16_t TaskSchedulerManager::findFreeTaskId() { uint16_t idToTry(1); while(_taskDataDictio(idToTry) != NULL) { idToTry++; } return idToTry; }