Commanders
Arduino buttons/bus library
EventsSequencer.cpp
1 #include "EventsSequencer.hpp"
2 
3 #ifndef NO_EVENTSSEQUENCER
4 EventsSequencer *EventsSequencer::pFirstSequencer = NULL;
5 
7 {
8  this->pFirst = NULL;
9  this->flags = 0;
10  this->pCurrent = NULL;
11  this->startDate = 0;
12 
13  this->pNextSequencer = NULL;
14  if (this->pFirstSequencer == NULL)
15  this->pFirstSequencer = this;
16  else
17  this->GetLastSequencer()->pNextSequencer = this;
18 }
19 
20 void EventsSequencer::AddEvent(unsigned long inId, COMMANDERS_EVENT_TYPE inType, int inData, unsigned long inDelay)
21 {
22 #ifdef COMMANDERS_DEBUG_MODE
23  if (this->IsPPointer())
24  {
25  Serial.println(F("Warning : a PROGMEM event list is already defined !"));
26  }
27 #endif
28  EventsSequencerItem *pNew = new EventsSequencerItem();//inId, inType, inData, inDelay);
29  pNew->delay = inDelay;
30  pNew->id = inId;
31  pNew->type = inType;
32  pNew->data = inData;
33  pNew->next = NULL;
34  if (this->pFirst == NULL)
35  this->pFirst = pNew;
36  else
37  this->GetLastItem()->SetNext(pNew);
38 }
39 
41 {
42 #ifdef COMMANDERS_DEBUG_MODE
43  if (!this->IsPPointer() && this->pFirst != NULL)
44  {
45  Serial.println(F("Warning : an event list is already defined !"));
46  }
47 #endif
48  this->pFirst = (EventsSequencerItem *)apEvents;
49  this->SetPPointer();
50 }
51 
52 EventsSequencerItem *EventsSequencer::GetLastItem() const
53 {
54  if (this->IsPPointer())
55  return NULL;
56 
57  EventsSequencerItem *curr = this->pFirst;
58  while (curr != NULL && curr->GetNext() != NULL)
59  curr = curr->GetNext();
60 
61  return curr;
62 }
63 
64 EventsSequencerItem *EventsSequencer::GetFirstItem(EventsSequencerItem *apLocal) const
65 {
66  if (this->IsPPointer())
67  {
68  memcpy_P(apLocal, this->pFirst, sizeof(EventsSequencerItem));
69  apLocal->next = this->pFirst + 1;
70  return apLocal;
71  }
72 
73  return this->pFirst;
74 }
75 
76 EventsSequencerItem *EventsSequencer::GetCurrentItem(EventsSequencerItem *apLocal) const
77 {
78  if (this->IsPPointer())
79  {
80  memcpy_P(apLocal, this->pCurrent, sizeof(EventsSequencerItem));
81  apLocal->next = this->pCurrent + 1;
82  return apLocal;
83  }
84 
85  return this->pCurrent;
86 }
87 
89 {
90  if (inItem == NULL)
91  inItem = this->pFirst;
92  this->pCurrent = inItem;
94  this->GetCurrentItem(&item);
95  Commanders::RaiseEvent(item.id, item.type, item.data);
96  this->startDate = millis();
97 }
98 
99 bool EventsSequencer::IsCurrentItemLast()
100 {
101  if (this->IsPPointer())
102  {
103  EventsSequencerItem item;
104  this->GetCurrentItem(&item);
105 
106  if (item.id == UNDEFINED_ID)
107  return true;
108 
109  this->pCurrent += 1;
110  this->GetCurrentItem(&item);
111  this->pCurrent -= 1;
112 
113  if (item.id == UNDEFINED_ID)
114  return true;
115  }
116  else
117  {
118  if (this->pCurrent->GetNext() == NULL)
119  return true;
120  }
121 
122  return false;
123 }
124 
126 {
127  if (this->pCurrent == NULL)
128  return false; // Sequence stopped.
129 
130  EventsSequencerItem item;
131  this->GetCurrentItem(&item);
132 
133  if (millis() - this->startDate < item.GetDelay())
134  return false;
135 
136  if (this->IsCurrentItemLast())
137  {
138  if (this->IsPerpetual())
139  this->StartItem();
140  else
141  this->startDate = 0;
142  return false;
143  }
144 
145  if (this->IsPPointer())
146  this->StartItem(this->pCurrent + 1);
147  else
148  this->StartItem(this->pCurrent->GetNext());
149  return true;
150 }
151 
152 EventsSequencer *EventsSequencer::GetLastSequencer()
153 {
154  EventsSequencer *curr = EventsSequencer::pFirstSequencer;
155  while (curr != NULL && curr->GetNextSequencer() != NULL)
156  curr = curr->GetNextSequencer();
157 
158  return curr;
159 }
160 
162 {
163  EventsSequencer *curr = EventsSequencer::pFirstSequencer;
164  while (curr != NULL)
165  {
166  if (!curr->IsPaused())
167  curr->loop();
168  curr = curr->GetNextSequencer();
169  }
170 }
171 
172 #ifdef COMMANDERS_PRINT_COMMANDERS
174 {
175  Serial.print(F(" Sequencer "));
176  Serial.println((long) this, HEX);
177 
178  EventsSequencerItem item, *pItem, *pNext;
179 
180  pItem = this->GetFirstItem(&item);
181 
182  while (pItem != NULL && pItem->id != UNDEFINED_ID)
183  {
184  Serial.print(F(" Event - Id: "));
185  Serial.print(pItem->id);
186  Serial.print(F(" / type: "));
187  Commanders::printEventType(pItem->type, true);
188  Commanders::printEventData(pItem->type, pItem->data);
189  Serial.print(F(" / delay: "));
190  Serial.print(pItem->delay);
191  Serial.println(F(""));
192 
193  if (this->IsPPointer())
194  {
195  pNext = pItem->next;
196  memcpy_P(pItem, pItem->next, sizeof(EventsSequencerItem));
197  pItem->next = pNext + 1;
198  }
199  else
200  pItem = pItem->next;
201  }
202 }
203 
205 {
206  EventsSequencer *curr = EventsSequencer::pFirstSequencer;
207  while (curr != NULL)
208  {
209  curr->printSequencer();
210  curr = curr->GetNextSequencer();
211  }
212 }
213 #endif
214 
215 #endif
static void printEventData(COMMANDERS_EVENT_TYPE inEventType, int inEventData)
static void printAllSequencers()
static void loops()
unsigned long GetDelay()
#define UNDEFINED_ID
Definition: Events.h:38
static unsigned long RaiseEvent(unsigned long inId, COMMANDERS_EVENT_TYPE inEvent = COMMANDERS_EVENT_MOVEPOSITIONID, int inData = 0)
Definition: Commanders.cpp:27
void StartItem(EventsSequencerItem *inItem = NULL)
void AddEvents(const EventsSequencerItem *apEvents)
void SetNext(EventsSequencerItem *inNext)
EventsSequencerItem * next
COMMANDERS_EVENT_TYPE type
static void printEventType(COMMANDERS_EVENT_TYPE inEventType, bool inDataFollow)
bool IsPPointer() const
COMMANDERS_EVENT_TYPE
Definition: Events.h:25
void AddEvent(unsigned long inId, COMMANDERS_EVENT_TYPE inType, int inData, unsigned long inDelay)
EventsSequencerItem * pCurrent
bool IsPerpetual() const
EventsSequencerItem * pFirst
EventsSequencerItem * GetNext()