Core/Task.h
Go to the documentation of this file.
1 /****
2  * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
3  * Created 2015 by Skurydin Alexey
4  * http://github.com/SmingHub/Sming
5  * All files of the Sming Core are provided under the LGPL v3 license.
6  *
7  * Task.h
8  *
9  * @author mikee47 mike@sillyhouse.net
10  *
11  * Sming provides a task queue for applications to use. It can be used to defer processing
12  * from an interrupt service routine, but can also be used to provide a form of multi-tasking.
13  *
14  * This class provides a simple way to create a task which runs continuously, or can be started
15  * and stopped as required.
16  *
17  * You can see how this class is used in the `Basic_Tasks` sample.
18  *
19  *
20  ****/
21 
22 #pragma once
23 
24 #include <SimpleTimer.h>
25 
33 class Task
34 {
35 public:
39  enum class State {
40  Suspended,
41  Sleeping,
42  Running,
43  };
44 
48  enum class Notify {
49  None,
50  Suspending,
51  Resuming,
52  Sleeping,
53  Waking,
54  };
55 
56  virtual ~Task() = default;
57 
62  bool resume()
63  {
64  switch(state) {
65  case State::Sleeping:
66  sleepTimer.stop();
67  notification = Notify::Waking;
68  state = State::Running;
69  return schedule();
70  case State::Suspended:
71  notification = Notify::Resuming;
72  state = State::Running;
73  return schedule();
74  case State::Running:
75  return true;
76  default:
77  assert(false);
78  return false;
79  }
80  }
81 
85  void suspend()
86  {
87  switch(state) {
88  case State::Sleeping:
89  sleepTimer.stop();
90  notify(Notify::Suspending);
91  state = State::Suspended;
92  break;
93  case State::Running:
94  notify(Notify::Suspending);
95  state = State::Suspended;
96  break;
97  case State::Suspended:
98  break;
99  default:
100  assert(false);
101  }
102  }
103 
108  void sleep(unsigned interval)
109  {
110  switch(state) {
111  case State::Suspended:
112  case State::Running:
113  sleepTimer.initializeMs(
114  interval,
115  [](void* param) {
116  auto task = static_cast<Task*>(param);
117  task->notify(Notify::Waking);
118  task->state = State::Running;
119  task->service();
120  },
121  this);
122  sleepTimer.startOnce();
123  notify(Notify::Sleeping);
124  state = State::Sleeping;
125  break;
126  case State::Sleeping:
127  break;
128  }
129  }
130 
131 protected:
135  virtual void loop() = 0;
136 
140  virtual void onNotify([[maybe_unused]] Notify code)
141  {
142  }
143 
144 private:
145  /*
146  *
147  */
148  void notify(Notify code)
149  {
150  notification = Notify::None;
151  onNotify(code);
152  }
153 
158  bool schedule()
159  {
160  if(scheduled) {
161  return true;
162  }
163 
164  scheduled = System.queueCallback(
165  [](void* param) {
166  auto task = reinterpret_cast<Task*>(param);
167  task->scheduled = false;
168  task->service();
169  },
170  this);
171 
172  return scheduled;
173  }
174 
175  /*
176  * Executed via task queue
177  */
178  void service()
179  {
180  if(state == State::Running) {
181  if(notification != Notify::None) {
182  notify(notification);
183  }
184  loop();
185  schedule();
186  }
187  }
188 
189 private:
190  State state{State::Suspended};
191  Notify notification{Notify::None};
192  bool scheduled{false};
193  SimpleTimer sleepTimer;
194 };
CallbackTimer & initializeMs(TimerCallback callback, void *arg=nullptr)
Initialise hardware timer in milliseconds (static check) with Timer Callback and optional argument.
Definition: CallbackTimer.h:184
void stop()
Stops timer.
Definition: CallbackTimer.h:237
bool startOnce()
Start one-shot timer.
Definition: CallbackTimer.h:230
static bool queueCallback(TaskCallback32 callback, uint32_t param=0)
Queue a deferred callback.
Definition: System.h:190
Class to support running a background task.
Definition: Core/Task.h:34
virtual void loop()=0
Inherited classes override this to perform actual work.
virtual ~Task()=default
bool resume()
Call to set task running.
Definition: Core/Task.h:62
Notify
Notification of state change.
Definition: Core/Task.h:48
virtual void onNotify([[maybe_unused]] Notify code)
Called immediately before calling to loop() to indicate a state change.
Definition: Core/Task.h:140
void sleep(unsigned interval)
Puts the task to sleep for a while.
Definition: Core/Task.h:108
void suspend()
Suspend a task.
Definition: Core/Task.h:85
State
State of a task.
Definition: Core/Task.h:39
SystemClass System
Global instance of system object.