toolbar buttons to select shape
This commit is contained in:
parent
a73d51a31a
commit
5ffa084516
14 changed files with 367 additions and 239 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { Action, TransitionLabel } from "./label_ast";
|
||||
import { Action, EventTrigger, TransitionLabel } from "./label_ast";
|
||||
|
||||
export type AbstractState = {
|
||||
uid: string;
|
||||
|
|
@ -37,8 +37,8 @@ export type Statechart = {
|
|||
|
||||
variables: Set<string>;
|
||||
|
||||
inputEvents: Set<string>;
|
||||
internalEvents: Set<string>;
|
||||
inputEvents: EventTrigger[];
|
||||
internalEvents: EventTrigger[];
|
||||
outputEvents: Set<string>;
|
||||
|
||||
uid2State: Map<string, ConcreteState>;
|
||||
|
|
@ -60,8 +60,8 @@ export const emptyStatechart: Statechart = {
|
|||
root: emptyRoot,
|
||||
transitions: new Map(),
|
||||
variables: new Set(),
|
||||
inputEvents: new Set(),
|
||||
internalEvents: new Set(),
|
||||
inputEvents: [],
|
||||
internalEvents: [],
|
||||
outputEvents: new Set(),
|
||||
uid2State: new Map([["root", emptyRoot]]),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ export function evalExpr(expr: Expression, environment: Environment): any {
|
|||
else if (expr.kind === "ref") {
|
||||
const found = environment.get(expr.variable);
|
||||
if (found === undefined) {
|
||||
console.log({environment});
|
||||
throw new Error(`variable '${expr.variable}' does not exist in environment`);
|
||||
}
|
||||
return found;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { Rect2D, Vec2D, Line2D, euclideanDistance, intersectLines, isWithin, lineBBox, isEntirelyWithin } from "../VisualEditor/geometry";
|
||||
import { Rect2D, Vec2D, Line2D, euclideanDistance, intersectLines, isWithin, lineBBox } from "../VisualEditor/geometry";
|
||||
import { ARROW_SNAP_THRESHOLD, TEXT_SNAP_THRESHOLD } from "../VisualEditor/parameters";
|
||||
import { sides } from "../VisualEditor/VisualEditor";
|
||||
|
||||
export type Rountangle = {
|
||||
uid: string;
|
||||
kind: "and" | "or";
|
||||
kind: "and" | "or" | "pseudo";
|
||||
} & Rect2D;
|
||||
|
||||
export type Text = {
|
||||
|
|
|
|||
|
|
@ -238,10 +238,10 @@ export function handleEvent(simtime: number, event: RT_Event, statechart: Statec
|
|||
if (event.kind === "input" && event.param !== undefined) {
|
||||
// input events may have a parameter
|
||||
// *temporarily* add event to environment (dirty!)
|
||||
oldValue = environment.get(event.param.name);
|
||||
oldValue = environment.get(event.param);
|
||||
environment = new Map([
|
||||
...environment,
|
||||
[(t.label[0].trigger as EventTrigger).paramName as string, event.param.value],
|
||||
[(t.label[0].trigger as EventTrigger).paramName as string, event.param],
|
||||
]);
|
||||
}
|
||||
({mode, environment, ...raised} = fireTransition(simtime, t, arena, srcPath, tgtPath, {mode, environment, ...raised}));
|
||||
|
|
@ -251,6 +251,7 @@ export function handleEvent(simtime: number, event: RT_Event, statechart: Statec
|
|||
...environment,
|
||||
[(t.label[0].trigger as EventTrigger).paramName as string, oldValue],
|
||||
]);
|
||||
console.log('restored environment:', environment);
|
||||
}
|
||||
arenasFired.add(arena);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ function peg$parse(input, options) {
|
|||
};
|
||||
}
|
||||
function peg$f1(event, param) {
|
||||
return {kind: "event", event, param: param ? param[1] : undefined};
|
||||
return {kind: "event", event, paramName: param ? param[1] : undefined};
|
||||
}
|
||||
function peg$f2(dur) {
|
||||
return {kind: "after", durationMs: dur};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ConcreteState, OrState, Statechart, Transition } from "./abstract_syntax";
|
||||
import { findNearestArrow, findNearestRountangleSide, findRountangle, Rountangle, VisualEditorState } from "./concrete_syntax";
|
||||
import { isEntirelyWithin } from "../VisualEditor/geometry";
|
||||
import { Action, Expression, ParsedText } from "./label_ast";
|
||||
import { Action, EventTrigger, Expression, ParsedText } from "./label_ast";
|
||||
|
||||
import { parse as parseLabel, SyntaxError } from "./label_parser";
|
||||
|
||||
|
|
@ -11,6 +11,24 @@ export type TraceableError = {
|
|||
data?: any;
|
||||
}
|
||||
|
||||
function addEvent(events: EventTrigger[], e: EventTrigger, textUid: string) {
|
||||
const haveEvent = events.find(({event}) => event === e.event);
|
||||
if (haveEvent) {
|
||||
if (haveEvent.paramName !== e.paramName === undefined) {
|
||||
return [{
|
||||
shapeUid: textUid,
|
||||
message: "inconsistent event parameter",
|
||||
}];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
else {
|
||||
events.push(e);
|
||||
events.sort((a,b) => a.event.localeCompare(b.event));
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export function parseStatechart(state: VisualEditorState): [Statechart, TraceableError[]] {
|
||||
const errors: TraceableError[] = [];
|
||||
|
||||
|
|
@ -144,9 +162,9 @@ export function parseStatechart(state: VisualEditorState): [Statechart, Traceabl
|
|||
}
|
||||
|
||||
let variables = new Set<string>();
|
||||
const inputEvents = new Set<string>();
|
||||
const inputEvents: EventTrigger[] = [];
|
||||
const internalEvents: EventTrigger[] = [];
|
||||
const outputEvents = new Set<string>();
|
||||
const internalEvents = new Set<string>();
|
||||
|
||||
// step 3: figure out labels
|
||||
|
||||
|
|
@ -176,31 +194,35 @@ export function parseStatechart(state: VisualEditorState): [Statechart, Traceabl
|
|||
if (belongsToTransition) {
|
||||
// parse as transition label
|
||||
belongsToTransition.label.push(parsed);
|
||||
|
||||
// collect events
|
||||
// triggers
|
||||
if (parsed.trigger.kind === "event") {
|
||||
const {event} = parsed.trigger;
|
||||
if (event.startsWith("_")) {
|
||||
internalEvents.add(event);
|
||||
errors.push(...addEvent(internalEvents, parsed.trigger, parsed.uid));
|
||||
}
|
||||
else {
|
||||
inputEvents.add(event);
|
||||
errors.push(...addEvent(inputEvents, parsed.trigger, parsed.uid));
|
||||
}
|
||||
}
|
||||
else if (parsed.trigger.kind === "after") {
|
||||
belongsToTransition.src.timers.push(parsed.trigger.durationMs);
|
||||
belongsToTransition.src.timers.sort();
|
||||
}
|
||||
for (const action of parsed.actions) {
|
||||
if (action.kind === "raise") {
|
||||
const {event} = action;
|
||||
if (event.startsWith("_")) {
|
||||
internalEvents.add(event);
|
||||
}
|
||||
else {
|
||||
outputEvents.add(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
// // 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));
|
||||
|
|
|
|||
|
|
@ -19,6 +19,28 @@ export type Mode = Set<string>; // set of active states
|
|||
|
||||
export type Environment = ReadonlyMap<string, any>; // variable name -> value
|
||||
|
||||
// export class Environment {
|
||||
// env: Map<string, any>[];
|
||||
// constructor(env = [new Map()]) {
|
||||
// this.env = env;
|
||||
// }
|
||||
|
||||
// with(key: string, value: any): Environment {
|
||||
// for (let i=0; i<this.env.length; i++) {
|
||||
// if (this.env[i].has(key)) {
|
||||
// return new Environment(this.env.with(i, new Map([
|
||||
// ...this.env[i].entries(),
|
||||
// [key, value],
|
||||
// ])));
|
||||
// }
|
||||
// }
|
||||
// return new Environment(this.env.with(-1, new Map([
|
||||
// ...this.env[this.env.length-1].entries(),
|
||||
// [key, value],
|
||||
// ])));
|
||||
// }
|
||||
// }
|
||||
|
||||
export type RT_Statechart = {
|
||||
mode: Mode;
|
||||
environment: Environment;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ tlabel = _ trigger:trigger _ guard:("[" _ guard _ "]")? _ actions:("/" _ actions
|
|||
trigger = afterTrigger / entryTrigger / exitTrigger / eventTrigger
|
||||
|
||||
eventTrigger = event:identifier param:("(" identifier ")")? {
|
||||
return {kind: "event", event, param: param ? param[1] : undefined};
|
||||
return {kind: "event", event, paramName: param ? param[1] : undefined};
|
||||
}
|
||||
|
||||
afterTrigger = "after" _ dur:durationMs {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue