Skip to content

Commit e04ecb1

Browse files
Sandeep PinnintiGitHub Enterprise
authored andcommitted
Support internal transitions in class state machines (#78)
* Internal Transitions test case * test case update * update in test case * RIC-1080 update in test case * Test case update * Update in test case * RIC-1080 update in test case * added test case and update for PR comments * added test case and update for PR comments * PR commnets fix * Update in test case md file * Update in test case * PR commnets fix
1 parent d6f4ecb commit e04ecb1

7 files changed

Lines changed: 263 additions & 1 deletion

File tree

art-comp-test/art-comp-test.code-workspace

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,16 @@
220220
},
221221
{
222222
"path": "tests/transition_inheritance"
223-
},
223+
},
224+
{
225+
"path": "tests/trigger_operation_with_parameters"
226+
},
227+
{
228+
"path": "tests/trigger_operation_internal"
229+
},
230+
{
231+
"path": "tests/trigger_operation_internal_1"
232+
},
224233
{
225234
"path": "tests/type_descriptor_inheritance"
226235
},
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
class DataObject {
2+
[[rt::header_preface]]
3+
`
4+
#include <iostream>
5+
`
6+
[[rt::impl_preface]]
7+
`
8+
#include "testlib.art.h"
9+
`
10+
[[rt::decl]]
11+
`
12+
public:
13+
DataObject();
14+
public:
15+
RTString rtg_current_val, entry_point1, entry_point2;
16+
`
17+
[[rt::impl]]
18+
`
19+
DataObject::DataObject() {
20+
rtg_init1();
21+
}
22+
`
23+
trigger op1();
24+
trigger op2(`bool` b);
25+
trigger op3(`int` i);
26+
trigger op4();
27+
trigger op5(`bool` b);
28+
statemachine {
29+
state P;
30+
state A {
31+
entrypoint ep1;
32+
ep1 -> B.ep2
33+
`
34+
entry_point1 = "ep1";
35+
`;
36+
state B {
37+
entrypoint ep2;
38+
ep2 -> C
39+
`
40+
entry_point2 = "ep2";
41+
`;
42+
state C {
43+
t1: on op5(`bool`) [`b == true`]
44+
`
45+
rtg_current_val = "op5";
46+
`;
47+
};
48+
};
49+
};
50+
state R {
51+
x: on op2(`bool`) [`b == true`]
52+
`
53+
rtg_current_val = "op2";
54+
`;
55+
y: on op3(`int`)[`i == 3`]
56+
`
57+
rtg_current_val = "op3";
58+
`;
59+
};
60+
initial -> P
61+
`
62+
`;
63+
P -> R on op1()
64+
`
65+
rtg_current_val = "op1";
66+
`;
67+
R -> A.ep1 on op4()
68+
`
69+
rtg_current_val = "op4";
70+
`;
71+
};
72+
73+
};
74+
75+
capsule Top {
76+
[[rt::header_preface]]
77+
`
78+
#include "testlib.art.h"
79+
#include "DataObject.h"
80+
#include <iostream>
81+
`
82+
[[rt::decl]]
83+
`
84+
private:
85+
DataObject _dataObject1;
86+
`
87+
behavior port t : Timing;
88+
statemachine {
89+
state State1, State2, State3, State4, State5, State6;
90+
initial -> State1
91+
`
92+
_dataObject1.op1();
93+
ASSERT(RTMemoryUtil::strcmp(_dataObject1.rtg_current_val, "op1") == 0, "op1 failed");
94+
t.informIn(RTTimespec(0,50000));
95+
96+
`;
97+
onState1: State1 -> State2 on t.timeout
98+
`
99+
_dataObject1.op2(true);
100+
ASSERT(RTMemoryUtil::strcmp(_dataObject1.rtg_current_val, "op2") == 0, "op2 failed");
101+
t.informIn(RTTimespec(0,50000));
102+
103+
`;
104+
onState2: State2 -> State3 on t.timeout
105+
`
106+
_dataObject1.op3(3);
107+
ASSERT(RTMemoryUtil::strcmp(_dataObject1.rtg_current_val, "op3") == 0, "op3 failed");
108+
t.informIn(RTTimespec(0,50000));
109+
110+
`;
111+
onState3: State3 -> State4 on t.timeout
112+
`
113+
_dataObject1.op4();
114+
ASSERT(RTMemoryUtil::strcmp(_dataObject1.rtg_current_val, "op4") == 0, "op4 failed");
115+
ASSERT(RTMemoryUtil::strcmp(_dataObject1.entry_point1, "ep1") == 0, "ep1 failed");
116+
ASSERT(RTMemoryUtil::strcmp(_dataObject1.entry_point2, "ep2") == 0, "ep2 failed");
117+
t.informIn(RTTimespec(0,50000));
118+
`;
119+
onState4: State4 -> State5 on t.timeout
120+
`
121+
_dataObject1.op5(true);
122+
ASSERT(RTMemoryUtil::strcmp(_dataObject1.rtg_current_val, "op5") == 0, "op5 failed");
123+
PASS();
124+
`;
125+
};
126+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
group: cpp_code_generation
3+
---
4+
For class state machines, this test case ensures that effect code is generated for internal transitions, validates the handling of nested states with internal transitions, and confirms that trigger guards are supported on internal transitions.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
let tc = TCF.define(TCF.CPP_TRANSFORM);
2+
tc.topCapsule = 'Top';
3+
tc.prerequisites = ["../../TestUtils/testlib.tcjs"];
4+
tc.targetFolder = 'trigger_operation_internal_target';
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
class DataObject {
2+
[[rt::header_preface]]
3+
`
4+
#include <iostream>
5+
`
6+
[[rt::impl_preface]]
7+
`
8+
#include "testlib.art.h"
9+
`
10+
[[rt::decl]]
11+
`
12+
public:
13+
DataObject();
14+
public:
15+
std::string rtg_current_val, entry_point1, entry_point2, entry_point3;
16+
`
17+
[[rt::impl]]
18+
`
19+
DataObject::DataObject() {
20+
rtg_init1();
21+
}
22+
`
23+
trigger op();
24+
trigger op1();
25+
trigger op2();
26+
trigger op3();
27+
statemachine {
28+
state P;
29+
state A {
30+
t1: on op1()
31+
`
32+
rtg_current_val = "a_op1";
33+
`;
34+
t2: on op2()
35+
`
36+
rtg_current_val = "a_op2";
37+
`;
38+
t3: on op3()
39+
`
40+
rtg_current_val = "a_op3";
41+
`;
42+
entrypoint ep1;
43+
44+
ep1 -> B.ep2
45+
`
46+
entry_point1 = "ep1";
47+
`;
48+
state B {
49+
t1: on op1() [`true`]
50+
`
51+
rtg_current_val = "b_op1";
52+
`;
53+
t2: on op2() [`true`]
54+
`
55+
rtg_current_val = "b_op2";
56+
`;
57+
entrypoint ep2;
58+
ep2 -> C
59+
`
60+
entry_point2 = "ep2";
61+
`;
62+
63+
state C {
64+
t1: on op1()
65+
`
66+
rtg_current_val = "c_op1";
67+
`;
68+
};
69+
70+
};
71+
};
72+
73+
initial -> P;
74+
P -> A.ep1 on op()
75+
`
76+
rtg_current_val = "init";
77+
`;
78+
};
79+
80+
};
81+
82+
capsule Top {
83+
[[rt::header_preface]]
84+
`
85+
#include "testlib.art.h"
86+
#include "DataObject.h"
87+
#include <iostream>
88+
`
89+
[[rt::decl]]
90+
`
91+
private:
92+
DataObject _dataObject1;
93+
`
94+
behavior port t : Timing;
95+
statemachine {
96+
state State1;
97+
initial -> State1
98+
`
99+
_dataObject1.op();
100+
_dataObject1.op1();
101+
ASSERT(_dataObject1.rtg_current_val == "c_op1", "Expected c_op1");
102+
_dataObject1.op2();
103+
ASSERT(_dataObject1.rtg_current_val == "b_op2", "Expected b_op2");
104+
_dataObject1.op3();
105+
ASSERT(_dataObject1.rtg_current_val == "a_op3", "Expected a_op3");
106+
PASS();
107+
`;
108+
};
109+
};
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
group: cpp_code_generation
3+
---
4+
For class state machines, this test case ensures that the correct trigger operation is called according to precedence rules.
5+
6+
In this example, States A, B, and C are nested states, each containing the trigger operation op1. State C is within the scope of B, and B is within the scope of A. When the trigger op1 is called, it is expected to invoke the op1 operation inside State C due to the nesting hierarchy, where the innermost state (C) takes precedence.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
let tc = TCF.define(TCF.CPP_TRANSFORM);
2+
tc.topCapsule = 'Top';
3+
tc.prerequisites = ["../../TestUtils/testlib.tcjs"];
4+
tc.targetFolder = 'trigger_operation_internal_target_1';

0 commit comments

Comments
 (0)