generated from HyperloopUPV-H8/template-project
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstate_machine_gen.py
112 lines (95 loc) · 4.26 KB
/
state_machine_gen.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import json
from state_machine_object_descriptions import *
def instance_object_name(name):
return f"{name}_State_Machine"
def generate_code(state_machine):
content = []
content.extend([
"#pragma once",
'#include "ST-LIB.hpp"',
"using namespace std::chrono_literals;",
"",
"// AUTOGENERATED CODE, DO NOT EDIT MANUALLY",
"",
f"class {state_machine.name}{{",
"",
" public:",
""
])
for t in state_machine.transitions:
content.append(f" static bool {t.name}();")
for action in state_machine.actions:
for sa in action.state_actions:
content.append(f" static void {sa.name}();")
content.append("")
main_instance = instance_object_name(state_machine.name)
content.append(f" StateMachine {main_instance};")
for nested_sm in state_machine.nested_state_machines:
nested_instance = instance_object_name(nested_sm.name)
content.append(f" StateMachine {nested_instance};")
content.append("")
content.append(f" enum {state_machine.name}States {{")
for state in state_machine.states:
if isinstance(state, State):
content.append(f" {state.name.upper()},")
content.append(" };")
content.append("")
for nested_sm in state_machine.nested_state_machines:
content.append(f" enum {nested_sm.name}{{")
for state in nested_sm.states:
content.append(f" {state.name.upper()},")
content.append(" };")
content.append("")
content.append(f" {state_machine.name}(){{")
content.append("")
if state_machine.states:
first_state = state_machine.states[0]
content.append(f" {main_instance} = StateMachine({state_machine.name}States::{first_state.name.upper()});")
content.append("")
for nested_sm in state_machine.nested_state_machines:
nested_instance = instance_object_name(nested_sm.name)
if nested_sm.states:
first_nested = nested_sm.states[0]
content.extend([
f" {nested_instance} = StateMachine({nested_sm.name}::{first_nested.name.upper()});",
f" {main_instance}.add_state_machine({nested_instance}, {get_state_reference(nested_sm.nested_to, state_machine.name)});"
])
for state in nested_sm.states[1:]:
content.append(f" {nested_instance}.add_state({nested_sm.name}::{state.name.upper()});")
content.append("")
for state in state_machine.states[1:]:
if isinstance(state, State):
content.append(f" {main_instance}.add_state({state_machine.name}States::{state.name.upper()});")
content.append("")
for t in state_machine.transitions:
if t.comment:
content.append(f" // {t.comment}")
from_state = get_state_reference(t.from_state, state_machine.name)
to_state = get_state_reference(t.to_state, state_machine.name)
content.append(f" {main_instance}.add_transition({from_state}, {to_state}, {t.name});")
content.append("")
for action in state_machine.actions:
for sa in action.state_actions:
if sa.description:
content.append(f" // {sa.description}")
state_ref = get_state_reference(action.state, state_machine.name)
if action.type == "enter":
content.append(f" {main_instance}.add_enter_action({sa.name}, {state_ref});")
elif action.type == "exit":
content.append(f" {main_instance}.add_exit_action({sa.name}, {state_ref});")
elif action.type.startswith("cyclic"):
precision = action.type.split("_")[1]
content.append(f" {main_instance}.add_{precision}_precision_cyclic_action({sa.name}, {sa.period}, {state_ref});")
content.append("")
content.extend([
" }",
"",
"};"
])
with open("Core/Inc/state_machine.hpp", "w") as f:
f.write("\n".join(content))
if __name__ == "__main__":
with open("state_machine.json", "r") as file:
data = json.load(file)
sm = parse_state_machine(data)
generate_code(sm)