Skip to content

Commit 2378c25

Browse files
Merge pull request #262 from HyperloopUPV-H8/fix/return_action_reference
Fix/return action reference
2 parents 05d41ed + cba141c commit 2378c25

2 files changed

Lines changed: 92 additions & 34 deletions

File tree

Inc/ST-LIB_LOW/StateMachine/StateMachine.hpp

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class TimedAction {
2525
uint32_t period;
2626
AlarmType alarm_precision;
2727
uint8_t id = -1;
28+
bool is_on = false;
2829

2930
TimedAction() = default;
3031
};
@@ -37,15 +38,17 @@ class State {
3738
void enter();
3839
void exit();
3940
template<class TimeUnit>
40-
void add_new_timed_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, AlarmType precision_type);
41+
TimedAction* add_new_timed_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, AlarmType precision_type);
4142
template<class TimeUnit>
42-
void register_new_timed_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, AlarmType precision_type);
43+
TimedAction* register_new_timed_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, AlarmType precision_type);
4344
void unregister_all_timed_actions();
4445
void register_all_timed_actions();
46+
void unregister_timed_action(TimedAction* timed_action);
47+
void erase_timed_action(TimedAction* timed_action);
4548
};
4649

4750
template<class TimeUnit>
48-
void State::register_new_timed_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, AlarmType precision_type){
51+
TimedAction* State::register_new_timed_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, AlarmType precision_type){
4952
TimedAction timed_action = {};
5053
timed_action.alarm_precision = precision_type;
5154
timed_action.action = action;
@@ -66,14 +69,15 @@ void State::register_new_timed_action(function<void()> action, chrono::duration<
6669
break;
6770
default:
6871
ErrorHandler("Alarm Precision Type does not exist, AlarmType: %d", precision_type);
69-
return;
7072
break;
7173
}
74+
timed_action.is_on = true;
7275
cyclic_actions.push_back(timed_action);
76+
return &cyclic_actions.back();
7377
}
7478

7579
template<class TimeUnit>
76-
void State::add_new_timed_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, AlarmType precision_type){
80+
TimedAction* State::add_new_timed_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, AlarmType precision_type){
7781
TimedAction timed_action = {};
7882
timed_action.alarm_precision = precision_type;
7983
timed_action.action = action;
@@ -91,10 +95,11 @@ void State::add_new_timed_action(function<void()> action, chrono::duration<int64
9195
break;
9296
default:
9397
ErrorHandler("Alarm Precision Type does not exist, AlarmType: %d", precision_type);
94-
return;
98+
return nullptr;
9599
break;
96100
}
97101
cyclic_actions.push_back(timed_action);
102+
return &cyclic_actions.back();
98103
}
99104

100105

@@ -115,19 +120,22 @@ class StateMachine {
115120
void add_transition(state_id old_state, state_id new_state, function<bool()> transition);
116121

117122
template<class TimeUnit>
118-
void add_low_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period);
123+
TimedAction* add_low_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period);
119124
template<class TimeUnit>
120-
void add_low_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, state_id state);
125+
TimedAction* add_low_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, state_id state);
121126

122127
template<class TimeUnit>
123-
void add_mid_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period);
128+
TimedAction* add_mid_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period);
124129
template<class TimeUnit>
125-
void add_mid_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, state_id state);
130+
TimedAction* add_mid_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, state_id state);
126131

127132
template<class TimeUnit>
128-
void add_high_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period);
133+
TimedAction* add_high_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period);
129134
template<class TimeUnit>
130-
void add_high_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, state_id state);
135+
TimedAction* add_high_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, state_id state);
136+
137+
void remove_cyclic_action(TimedAction* timed_action);
138+
void remove_cyclic_action(TimedAction* timed_action, state_id state);
131139

132140
void add_enter_action(function<void()> action);
133141
void add_enter_action(function<void()> action, state_id state);
@@ -148,72 +156,72 @@ class StateMachine {
148156
};
149157

150158
template<class TimeUnit>
151-
void StateMachine::add_low_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, state_id state) {
159+
TimedAction* StateMachine::add_low_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, state_id state) {
152160
if (not states.contains(state)) {
153161
ErrorHandler("The state %d is not added to the state machine", state);
154-
return;
162+
return nullptr;
155163
}
156164

157165
uint32_t microseconds = (uint32_t)chrono::duration_cast<chrono::microseconds>(period).count();
158166

159167
if(microseconds % 1000 != 0){
160168
ErrorHandler("Low precision cyclic action does not have enough resolution for the desired period, Desired period: %d uS", microseconds);
161-
return;
169+
return nullptr;
162170
}
171+
if(state == current_state && is_on) return states[state].register_new_timed_action(action, period, LOW_PRECISION);
172+
else return states[state].add_new_timed_action(action, period,LOW_PRECISION);
163173

164-
if(state == current_state && is_on) states[state].register_new_timed_action(action, period, LOW_PRECISION);
165-
else states[state].add_new_timed_action(action, period,LOW_PRECISION);
166174
}
167175

168176
template<class TimeUnit>
169-
void StateMachine::add_low_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period){
170-
add_low_precision_cyclic_action(action, period, current_state);
177+
TimedAction* StateMachine::add_low_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period){
178+
return add_low_precision_cyclic_action(action, period, current_state);
171179
}
172180

173181
template<class TimeUnit>
174-
void StateMachine::add_mid_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, state_id state) {
182+
TimedAction* StateMachine::add_mid_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, state_id state) {
175183
if (not states.contains(state)) {
176184
ErrorHandler("The state %d is not added to the state machine", state);
177-
return;
185+
return nullptr;
178186
}
179187

180188
uint32_t microseconds = (uint32_t)chrono::duration_cast<chrono::microseconds>(period).count();
181189

182190
if(microseconds % 50 != 0){
183191
ErrorHandler("Mid precision cyclic action does not have enough resolution for the desired period, Desired period: %d uS", microseconds);
184-
return;
192+
return nullptr;
185193
}
186194

187-
if(state == current_state && is_on) states[state].register_new_timed_action(action, period, MID_PRECISION);
188-
else states[state].add_new_timed_action(action, period,MID_PRECISION);
195+
if(state == current_state && is_on) return states[state].register_new_timed_action(action, period, MID_PRECISION);
196+
else return states[state].add_new_timed_action(action, period,MID_PRECISION);
189197
}
190198

191199
template<class TimeUnit>
192-
void StateMachine::add_mid_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period){
193-
add_mid_precision_cyclic_action(action, period, current_state);
200+
TimedAction* StateMachine::add_mid_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period){
201+
return add_mid_precision_cyclic_action(action, period, current_state);
194202
}
195203

196204
template<class TimeUnit>
197-
void StateMachine::add_high_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, state_id state) {
205+
TimedAction* StateMachine::add_high_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period, state_id state) {
198206
if (not states.contains(state)) {
199207
ErrorHandler("The state %d is not added to the state machine", state);
200-
return;
208+
return nullptr;
201209
}
202210

203211
uint32_t microseconds = (uint32_t)chrono::duration_cast<chrono::microseconds>(period).count();
204212

205213
if(microseconds < 1){
206214
ErrorHandler("High precision cyclic action does not have enough resolution for the desired period, Desired period: %d uS", microseconds);
207-
return;
215+
return nullptr;
208216
}
209217

210-
if(state == current_state && is_on) states[state].register_new_timed_action(action, period, HIGH_PRECISION);
211-
else states[state].add_new_timed_action(action, period,HIGH_PRECISION);
218+
if(state == current_state && is_on) return states[state].register_new_timed_action(action, period, HIGH_PRECISION);
219+
else return states[state].add_new_timed_action(action, period,HIGH_PRECISION);
212220
}
213221

214222
template<class TimeUnit>
215-
void StateMachine::add_high_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period){
216-
add_high_precision_cyclic_action(action, period, current_state);
223+
TimedAction* StateMachine::add_high_precision_cyclic_action(function<void()> action, chrono::duration<int64_t, TimeUnit> period){
224+
return add_high_precision_cyclic_action(action, period, current_state);
217225
}
218226

219227
#endif

Src/ST-LIB_LOW/StateMachine/StateMachine.cpp

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,36 @@ void State::exit() {
1717
}
1818
}
1919

20+
void State::unregister_timed_action(TimedAction* timed_action){
21+
switch (timed_action->alarm_precision) {
22+
case LOW_PRECISION:
23+
Time::unregister_low_precision_alarm(timed_action->id);
24+
break;
25+
case MID_PRECISION:
26+
Time::unregister_mid_precision_alarm(timed_action->id);
27+
break;
28+
case HIGH_PRECISION:
29+
Time::unregister_high_precision_alarm(timed_action->id);
30+
break;
31+
default:
32+
ErrorHandler("Alarm Precision Type does not exist, AlarmType: %d", timed_action->alarm_precision);
33+
return;
34+
break;
35+
}
36+
timed_action->is_on = false;
37+
}
38+
39+
void State::erase_timed_action(TimedAction* timed_action){
40+
if(timed_action->is_on) unregister_timed_action(timed_action);
41+
cyclic_actions.erase(find_if(cyclic_actions.begin(), cyclic_actions.end(), [&](TimedAction& other){
42+
if(&other == timed_action) return true;
43+
return false;
44+
}));
45+
}
46+
2047
void State::unregister_all_timed_actions(){
21-
for(const TimedAction& timed_action : cyclic_actions){
48+
for(TimedAction& timed_action : cyclic_actions){
49+
if(!timed_action.is_on) continue;
2250
switch(timed_action.alarm_precision){
2351
case LOW_PRECISION:
2452
Time::unregister_low_precision_alarm(timed_action.id);
@@ -31,8 +59,10 @@ void State::unregister_all_timed_actions(){
3159
break;
3260
default:
3361
ErrorHandler("Cannot unregister timed action with erroneus alarm precision, Alarm Precision Type: %d", timed_action.alarm_precision);
62+
return;
3463
break;
3564
}
65+
timed_action.is_on = false;
3666
}
3767
}
3868

@@ -50,8 +80,10 @@ void State::register_all_timed_actions(){
5080
break;
5181
default:
5282
ErrorHandler("Cannot register timed action with erroneus alarm precision, Alarm Precision Type: %d", timed_action.alarm_precision);
83+
return;
5384
break;
5485
}
86+
timed_action.is_on = true;
5587
}
5688
}
5789

@@ -247,3 +279,21 @@ void StateMachine::force_change_state(uint8_t new_state) {
247279

248280
states[current_state].register_all_timed_actions();
249281
}
282+
283+
void StateMachine::remove_cyclic_action(TimedAction* action) {
284+
if (not states.contains(current_state)) {
285+
ErrorHandler("The state %d is not added to the state machine", current_state);
286+
return;
287+
}
288+
289+
states[current_state].erase_timed_action(action);
290+
}
291+
292+
void StateMachine::remove_cyclic_action(TimedAction* action, uint8_t state) {
293+
if (not states.contains(state)) {
294+
ErrorHandler("The state %d is not added to the state machine", state);
295+
return;
296+
}
297+
298+
states[state].erase_timed_action(action);
299+
}

0 commit comments

Comments
 (0)