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()
57  {
58  }
59 
64  bool resume()
65  {
66  switch(state) {
67  case State::Sleeping:
68  sleepTimer.stop();
69  notification = Notify::Waking;
70  state = State::Running;
71  return schedule();
72  case State::Suspended:
73  notification = Notify::Resuming;
74  state = State::Running;
75  return schedule();
76  case State::Running:
77  return true;
78  default:
79  assert(false);
80  return false;
81  }
82  }
83 
87  void suspend()
88  {
89  switch(state) {
90  case State::Sleeping:
91  sleepTimer.stop();
92  notify(Notify::Suspending);
93  state = State::Suspended;
94  break;
95  case State::Running:
96  notify(Notify::Suspending);
97  state = State::Suspended;
98  break;
99  case State::Suspended:
100  break;
101  default:
102  assert(false);
103  }
104  }
105 
110  void sleep(unsigned interval)
111  {
112  switch(state) {
113  case State::Suspended:
114  case State::Running:
115  sleepTimer.initializeMs(interval,
116  [](void* param) {
117  auto task = static_cast<Task*>(param);
118  task->notify(Notify::Waking);
119  task->state = State::Running;
120  task->service();
121  },
122  this);
123  sleepTimer.startOnce();
124  notify(Notify::Sleeping);
125  state = State::Sleeping;
126  break;
127  case State::Sleeping:
128  break;
129  }
130  }
131 
132 protected:
136  virtual void loop() = 0;
137 
141  virtual void onNotify(Notify code)
142  {
143  }
144 
145 private:
146  /*
147  *
148  */
149  void notify(Notify code)
150  {
151  notification = Notify::None;
152  onNotify(code);
153  }
154 
159  bool schedule()
160  {
161  if(scheduled) {
162  return true;
163  }
164 
165  scheduled = System.queueCallback(
166  [](uint32_t param) {
167  auto task = reinterpret_cast<Task*>(param);
168  task->scheduled = false;
169  task->service();
170  },
171  uint32_t(this));
172 
173  return scheduled;
174  }
175 
176  /*
177  * Executed via task queue
178  */
179  void service()
180  {
181  if(state == State::Running) {
182  if(notification != Notify::None) {
183  notify(notification);
184  }
185  loop();
186  schedule();
187  }
188  }
189 
190 private:
191  State state{State::Suspended};
192  Notify notification{Notify::None};
193  bool scheduled{false};
194  SimpleTimer sleepTimer;
195 };
virtual void loop()=0
Inherited classes override this to perform actual work.
virtual ~Task()
Definition: Task.h:56
SystemClass System
Global instance of system object.
State
State of a task.
Definition: Task.h:39
bool resume()
Call to set task running.
Definition: Task.h:64
void suspend()
Suspend a task.
Definition: Task.h:87
void sleep(unsigned interval)
Puts the task to sleep for a while.
Definition: Task.h:110
static bool queueCallback(TaskCallback32 callback, uint32_t param=0)
Queue a deferred callback.
virtual void onNotify(Notify code)
Called immediately before calling to loop() to indicate a state change.
Definition: Task.h:141
Notify
Notification of state change.
Definition: Task.h:48
Class to support running a background task.
Definition: Task.h:33