diff --git a/src/VisualEditor/VisualEditor.css b/src/VisualEditor/VisualEditor.css
index a15f2a5..ce04107 100644
--- a/src/VisualEditor/VisualEditor.css
+++ b/src/VisualEditor/VisualEditor.css
@@ -143,4 +143,8 @@ text.error, tspan.error {
g:hover > .errorHover {
display: inline;
+}
+
+text.uid {
+ fill: lightgrey;
}
\ No newline at end of file
diff --git a/src/VisualEditor/VisualEditor.tsx b/src/VisualEditor/VisualEditor.tsx
index bccd45e..644b6bc 100644
--- a/src/VisualEditor/VisualEditor.tsx
+++ b/src/VisualEditor/VisualEditor.tsx
@@ -734,6 +734,7 @@ export function RountangleSVG(props: {rountangle: Rountangle, selected: string[]
data-parts="bottom left"
/>
{uid}
;
diff --git a/src/VisualEditor/ast.ts b/src/VisualEditor/ast.ts
index ebe6798..92e6675 100644
--- a/src/VisualEditor/ast.ts
+++ b/src/VisualEditor/ast.ts
@@ -1,9 +1,11 @@
-import { TransitionLabel } from "./label_ast";
+import { Action, TransitionLabel } from "./label_ast";
export type AbstractState = {
uid: string;
children: ConcreteState[];
comments: [string, string][]; // array of tuple (text-uid, text-text)
+ entryActions: Action[];
+ exitActions: Action[];
}
export type AndState = {
diff --git a/src/VisualEditor/parser.ts b/src/VisualEditor/parser.ts
index 314e794..02b876c 100644
--- a/src/VisualEditor/parser.ts
+++ b/src/VisualEditor/parser.ts
@@ -15,6 +15,9 @@ export function parseStatechart(state: VisualEditorState): [Statechart, [string,
uid: "root",
children: [],
initial: [],
+ comments: [],
+ entryActions: [],
+ exitActions: [],
}
const uid2State = new Map([["root", root]]);
@@ -38,6 +41,8 @@ export function parseStatechart(state: VisualEditorState): [Statechart, [string,
uid: rt.uid,
children: [],
comments: [],
+ entryActions: [],
+ exitActions: [],
}
if (state.kind === "or") {
state.initial = [];
@@ -122,7 +127,8 @@ export function parseStatechart(state: VisualEditorState): [Statechart, [string,
// step 3: figure out labels
- for (const text of state.texts) {
+ const textsSorted = state.texts.toSorted((a,b) => a.topLeft.y - b.topLeft.y);
+ for (const text of textsSorted) {
let parsed: ParsedText;
try {
parsed = parseLabel(text.text); // may throw
@@ -176,19 +182,27 @@ export function parseStatechart(state: VisualEditorState): [Statechart, [string,
// text does not belong to transition...
// so it belongs to a rountangle (a state)
const rountangle = findRountangle(text.topLeft, state.rountangles);
+ const belongsToState = rountangle ? uid2State.get(rountangle.uid)! : root;
if (parsed.kind === "transitionLabel") {
// labels belonging to a rountangle (= a state) must by entry/exit actions
// if we cannot find a containing state, then it belong to the root
- const state = rountangle ? uid2State.get(rountangle.uid)! : root;
- if (parsed.trigger.kind !== "entry" && parsed.trigger.kind !== "exit") {
+ if (parsed.trigger.kind === "entry") {
+ belongsToState.entryActions.push(...parsed.actions);
+ }
+ else if(parsed.trigger.kind === "exit") {
+ belongsToState.exitActions.push(...parsed.actions);
+ }
+ else {
errorShapes.push([text.uid, {
message: "states can only have entry/exit triggers",
location: {start: {offset: 0}, end: {offset: text.text.length}},
- }]);
+ } as unknown as string]);
}
+
}
else if (parsed.kind === "comment") {
// just append comments to their respective states
+ belongsToState.comments.push([text.uid, parsed.text]);
}
}