show internal events in side panel:

This commit is contained in:
Joeri Exelmans 2025-10-21 14:37:55 +02:00
parent 29808a683c
commit 97d42c1cef
7 changed files with 47 additions and 24 deletions

View file

@ -53,6 +53,16 @@ details > summary:hover {
display: inline-block;
}
.internalEvent {
border: 1px black solid;
border-radius: 6px;
margin-left: 4px;
padding-left: 2px;
padding-right: 2px;
background-color: rgb(255, 218, 252);
display: inline-block;
}
.inputEvent {
border: 1px black solid;
border-radius: 6px;

View file

@ -13,7 +13,7 @@ import Stack from "@mui/material/Stack";
import Box from "@mui/material/Box";
import { TopPanel } from "./TopPanel";
import { RTHistory } from "./RTHistory";
import { ShowAST, ShowInputEvents, ShowOutputEvents } from "./ShowAST";
import { ShowAST, ShowInputEvents, ShowInternalEvents, ShowOutputEvents } from "./ShowAST";
import { TraceableError } from "../statecharts/parser";
import { getKeyHandler } from "./shortcut_handler";
import { BottomPanel } from "./BottomPanel";
@ -258,6 +258,10 @@ export function App() {
<summary>input events</summary>
<ShowInputEvents inputEvents={ast.inputEvents} onRaise={onRaise} disabled={rtIdx===undefined}/>
</PersistentDetails>
<PersistentDetails localStorageKey="showInternalEvents" initiallyOpen={true}>
<summary>internal events</summary>
<ShowInternalEvents internalEvents={ast.internalEvents}/>
</PersistentDetails>
<PersistentDetails localStorageKey="showOutputEvents" initiallyOpen={true}>
<summary>output events</summary>
<ShowOutputEvents outputEvents={ast.outputEvents}/>

View file

@ -4,7 +4,6 @@ import { TraceableError } from "../statecharts/parser";
import "./BottomPanel.css";
import head from "../head.svg" ;
import { usePersistentState } from "@/util/persistent_state";
import { PersistentDetails } from "./PersistentDetails";
import { DigitalWatch } from "@/Plant/DigitalWatch/DigitalWatch";

View file

@ -106,6 +106,13 @@ export function ShowInputEvents({inputEvents, onRaise, disabled}: {inputEvents:
)
}
export function ShowInternalEvents(props: {internalEvents: EventTrigger[]}) {
return [...props.internalEvents].map(({event, paramName}) => {
return <><div className="internalEvent">{event}{paramName===undefined?<></>:<>({paramName})</>}</div> </>;
});
}
export function ShowOutputEvents(props: {outputEvents: Set<string>}) {
return [...props.outputEvents].map(eventName => {
return <><div className="outputEvent">{eventName}</div> </>;

View file

@ -79,6 +79,8 @@ export function VisualEditor({state, setState, ast, setAST, rt, errors, setError
const [dragging, setDragging] = useState(false);
console.log(ast);
// uid's of selected rountangles
// const [selection, setSelection] = useState<Selection>([]);
const selection = state.selection || [];
@ -122,14 +124,13 @@ export function VisualEditor({state, setState, ast, setAST, rt, errors, setError
useEffect(() => {
// bit of a hacky way to force the animation on fired transitions to replay, if the new 'rt' contains the same fired transitions as the previous one
requestAnimationFrame(() => {
console.log('rt changed');
document.querySelectorAll(".arrow.fired").forEach(el => {
// @ts-ignore
el.style.animation = 'none';
requestAnimationFrame(() => {
// @ts-ignore
el.style.animation = '';
})
setTimeout(() => {
}, 10); // <- small timeout seems to be necessary or the animation won't restart
});
})
}, [rt]);

View file

@ -286,25 +286,6 @@ export function parseStatechart(state: VisualEditorState, conns: Connections): [
errors.push({shapeUid: text.uid, message: "triggerless transitions only allowed on pseudo-states"});
}
}
// raise-actions
for (const action of parsed.actions) {
if (action.kind === "raise") {
const {event} = action;
if (event.startsWith("_")) {
// internalEvents.add(event);
}
else {
outputEvents.add(event);
}
}
}
// collect variables
variables = variables.union(findVariables(parsed.guard));
for (const action of parsed.actions) {
variables = variables.union(findVariablesAction(action));
}
}
}
else {
@ -334,6 +315,26 @@ export function parseStatechart(state: VisualEditorState, conns: Connections): [
belongsToState.comments.push([text.uid, parsed.text]);
}
}
if (parsed.kind === "transitionLabel") {
// collect output events
for (const action of parsed.actions) {
if (action.kind === "raise") {
const {event} = action;
if (event.startsWith("_")) {
// internalEvents.add({event: event});
}
else {
outputEvents.add(event);
}
}
}
// collect variables
variables = variables.union(findVariables(parsed.guard));
for (const action of parsed.actions) {
variables = variables.union(findVariablesAction(action));
}
}
}
for (const transition of uid2Transition.values()) {