Просмотр исходного кода

v3.2.2 - cancel and abort methods

Anatoli Arkhipenko 5 лет назад
Родитель
Сommit
5ca1961300
2 измененных файлов с 49 добавлено и 22 удалено
  1. 39 14
      src/TaskScheduler.h
  2. 10 8
      src/TaskSchedulerDeclarations.h

+ 39 - 14
src/TaskScheduler.h

@@ -182,7 +182,13 @@
 //
 // v3.2.1:
 //    2020-10-04 - feature: Task.abort method. Stop task execution without calling OnDisable(). 
-
+//
+// v3.2.2:
+//    2020-12-14 - feature: enable and restart methods return true if task enabled 
+//                 feature: Task.cancel() method - disable task with a cancel flag (could be used for alt. path
+//                          processing in the onDisable method.
+//                 feature: Task.cancelled() method - indicates that task was disabled with a cancel() method.
+//
 
 #include <Arduino.h>
 
@@ -352,24 +358,26 @@ void StatusRequest::signalComplete(int aStatus) {
  *  @param: aStatusRequest - a pointer for the StatusRequest to wait for.
  *  If aStatusRequest is NULL, request for waiting is ignored, and the waiting task is not enabled.
  */
-void Task::waitFor(StatusRequest* aStatusRequest, unsigned long aInterval, long aIterations) {
+bool Task::waitFor(StatusRequest* aStatusRequest, unsigned long aInterval, long aIterations) {
     iStatusRequest = aStatusRequest;
     if ( iStatusRequest != NULL ) { // assign internal StatusRequest var and check if it is not NULL
         setIterations(aIterations);
         setInterval(aInterval);
         iStatus.waiting = _TASK_SR_NODELAY;  // no delay
-        enable();
+        return enable();
     }
+    return false;
 }
 
-void Task::waitForDelayed(StatusRequest* aStatusRequest, unsigned long aInterval, long aIterations) {
+bool Task::waitForDelayed(StatusRequest* aStatusRequest, unsigned long aInterval, long aIterations) {
     iStatusRequest = aStatusRequest;
     if ( iStatusRequest != NULL ) { // assign internal StatusRequest var and check if it is not NULL
         setIterations(aIterations);
         if ( aInterval ) setInterval(aInterval);  // For the dealyed version only set the interval if it was not a zero
         iStatus.waiting = _TASK_SR_DELAY;  // with delay equal to the current interval
-        enable();
+        return enable();
     }
+    return false;
 }
 #endif  // _TASK_STATUS_REQUEST
 
@@ -403,6 +411,7 @@ void Task::setOnDisable(TaskOnDisable aCallback) { iOnDisable = aCallback; }
 void Task::reset() {
     iStatus.enabled = false;
     iStatus.inonenable = false;
+    iStatus.canceled = false;
     iPreviousMillis = 0;
     iInterval = iDelay = 0;
     iPrev = NULL;
@@ -499,7 +508,7 @@ void Task::yieldOnce (TaskCallback aCallback) {
  *  schedules it for execution as soon as possible,
  *  and resets the RunCounter back to zero
  */
-void Task::enable() {
+bool Task::enable() {
     if (iScheduler) { // activation without active scheduler does not make sense
         iRunCounter = 0;
 
@@ -532,12 +541,15 @@ void Task::enable() {
             resetTimeout();
 #endif // _TASK_TIMEOUT
 
-#ifdef _TASK_STATUS_REQUEST
         if ( iStatus.enabled ) {
+#ifdef _TASK_STATUS_REQUEST
             iMyStatusRequest.setWaiting();
-        }
 #endif // _TASK_STATUS_REQUEST
+            iStatus.canceled = false;
+        }
+        return iStatus.enabled;
     }
+    return false;
 }
 
 /** Enables the task only if it was not enabled already
@@ -552,9 +564,10 @@ bool Task::enableIfNot() {
 /** Enables the task
  * and schedules it for execution after a delay = aInterval
  */
-void Task::enableDelayed(unsigned long aDelay) {
+bool Task::enableDelayed(unsigned long aDelay) {
     enable();
     delay(aDelay);
+    return iStatus.enabled;
 }
 
 #ifdef _TASK_TIMEOUT
@@ -650,27 +663,39 @@ bool Task::disable() {
 /** Aborts task execution
  * Task will no longer be executed by the scheduler AND ondisable method will not be called
  */
-
 void Task::abort() {
     iStatus.enabled = false;
     iStatus.inonenable = false;
 }
 
+
+/** Cancels task execution
+ * Task will no longer be executed by the scheduler. Ondisable method will be called after 'canceled' flag is set
+ */
+void Task::cancel() {
+    iStatus.canceled = true;
+    disable();
+}
+
+bool Task::canceled() {
+    return iStatus.canceled;
+}
+
 /** Restarts task
  * Task will run number of iterations again
  */
 
-void Task::restart() {
+bool Task::restart() {
     iIterations = iSetIterations;
-    enable();
+    return enable();
 }
 
 /** Restarts task delayed
  * Task will run number of iterations again
  */
-void Task::restartDelayed(unsigned long aDelay) {
-    enableDelayed(aDelay);
+bool Task::restartDelayed(unsigned long aDelay) {
     iIterations = iSetIterations;
+    return enableDelayed(aDelay);
 }
 
 bool Task::isFirstIteration() { return (iRunCounter <= 1); }

+ 10 - 8
src/TaskSchedulerDeclarations.h

@@ -119,9 +119,9 @@ typedef bool (*TaskOnEnable)();
 typedef struct  {
     bool  enabled    : 1;           // indicates that task is enabled or not.
     bool  inonenable : 1;           // indicates that task execution is inside OnEnable method (preventing infinite loops)
-
+    bool  canceled   : 1;           // indication that tast has been canceled prior to normal end of all iterations or regular call to disable()
 #ifdef _TASK_STATUS_REQUEST
-    uint8_t  waiting : 2;        // indication if task is waiting on the status request
+    uint8_t  waiting : 2;           // indication if task is waiting on the status request
 #endif
 
 #ifdef _TASK_TIMEOUT
@@ -164,17 +164,19 @@ class Task {
     INLINE bool timedOut();
 #endif
 
-    INLINE void enable();
+    INLINE bool enable();
     INLINE bool enableIfNot();
-    INLINE void enableDelayed(unsigned long aDelay=0);
-    INLINE void restart();
-    INLINE void restartDelayed(unsigned long aDelay=0);
+    INLINE bool enableDelayed(unsigned long aDelay=0);
+    INLINE bool restart();
+    INLINE bool restartDelayed(unsigned long aDelay=0);
 
     INLINE void delay(unsigned long aDelay=0);
     INLINE void forceNextIteration();
     INLINE bool disable();
     INLINE void abort();
+    INLINE void cancel();
     INLINE bool isEnabled();
+    INLINE bool canceled();
 
 #ifdef _TASK_SCHEDULING_OPTIONS
     INLINE unsigned int getSchedulingOption() { return iOption; }
@@ -213,8 +215,8 @@ class Task {
 #endif  // _TASK_TIMECRITICAL
 
 #ifdef _TASK_STATUS_REQUEST
-    INLINE void waitFor(StatusRequest* aStatusRequest, unsigned long aInterval = 0, long aIterations = 1);
-    INLINE void waitForDelayed(StatusRequest* aStatusRequest, unsigned long aInterval = 0, long aIterations = 1);
+    INLINE bool waitFor(StatusRequest* aStatusRequest, unsigned long aInterval = 0, long aIterations = 1);
+    INLINE bool waitForDelayed(StatusRequest* aStatusRequest, unsigned long aInterval = 0, long aIterations = 1);
     INLINE StatusRequest* getStatusRequest() ;
     INLINE StatusRequest* getInternalStatusRequest() ;
 #endif  // _TASK_STATUS_REQUEST