memoize parsed text labels

This commit is contained in:
Joeri Exelmans 2025-10-23 22:29:45 +02:00
parent 529ad1d4bd
commit 65b6a343d1
3 changed files with 9 additions and 5 deletions

View file

@ -150,7 +150,7 @@ export function App() {
}, [setTrace, setTime]); }, [setTrace, setTime]);
// raise input event, producing a new runtime configuration (or a runtime error) // raise input event, producing a new runtime configuration (or a runtime error)
function onRaise(inputEvent: string, param: any) { const onRaise = (inputEvent: string, param: any) => {
if (trace !== null && ast.inputEvents.some(e => e.event === inputEvent)) { if (trace !== null && ast.inputEvents.some(e => e.event === inputEvent)) {
const config = current(trace); const config = current(trace);
if (config.kind === "bigstep") { if (config.kind === "bigstep") {
@ -158,7 +158,7 @@ export function App() {
produceNextConfig(simtime, {kind: "input", name: inputEvent, param}, config); produceNextConfig(simtime, {kind: "input", name: inputEvent, param}, config);
} }
} }
} };
// timer elapse events are triggered by a change of the simulated time (possibly as a scheduled JS event loop timeout) // timer elapse events are triggered by a change of the simulated time (possibly as a scheduled JS event loop timeout)
useEffect(() => { useEffect(() => {
let timeout: NodeJS.Timeout | undefined; let timeout: NodeJS.Timeout | undefined;
@ -219,6 +219,7 @@ export function App() {
...trace!.trace.slice(0, trace!.idx+1), // remove everything after current item ...trace!.trace.slice(0, trace!.idx+1), // remove everything after current item
newItem, newItem,
], ],
// idx: 0,
idx: trace!.idx+1, idx: trace!.idx+1,
})); }));
scrollDownSidebar(); scrollDownSidebar();

View file

@ -1,6 +1,6 @@
import { Dispatch, ReactElement, SetStateAction, useState, KeyboardEvent, useEffect, useRef } from "react"; import { Dispatch, ReactElement, SetStateAction, useState, KeyboardEvent, useEffect, useRef } from "react";
import { parse as parseLabel } from "../statecharts/label_parser"; import { cachedParseLabel } from "@/statecharts/parser";
export function TextDialog(props: {setModal: Dispatch<SetStateAction<ReactElement|null>>, text: string, done: (newText: string|undefined) => void}) { export function TextDialog(props: {setModal: Dispatch<SetStateAction<ReactElement|null>>, text: string, done: (newText: string|undefined) => void}) {
const [text, setText] = useState(props.text); const [text, setText] = useState(props.text);
@ -22,7 +22,7 @@ export function TextDialog(props: {setModal: Dispatch<SetStateAction<ReactElemen
let parseError = ""; let parseError = "";
try { try {
parseLabel(text); cachedParseLabel(text);
} catch (e) { } catch (e) {
// @ts-ignore // @ts-ignore
parseError = e.message; parseError = e.message;

View file

@ -6,6 +6,7 @@ import { parse as parseLabel, SyntaxError } from "./label_parser";
import { Connections } from "./detect_connections"; import { Connections } from "./detect_connections";
import { HISTORY_RADIUS } from "../VisualEditor/parameters"; import { HISTORY_RADIUS } from "../VisualEditor/parameters";
import { VisualEditorState } from "@/VisualEditor/VisualEditor"; import { VisualEditorState } from "@/VisualEditor/VisualEditor";
import { memoize } from "@/App/util";
export type TraceableError = { export type TraceableError = {
shapeUid: string; shapeUid: string;
@ -13,6 +14,8 @@ export type TraceableError = {
data?: any; data?: any;
} }
export const cachedParseLabel = memoize(parseLabel);
function addEvent(events: EventTrigger[], e: EventTrigger, textUid: string) { function addEvent(events: EventTrigger[], e: EventTrigger, textUid: string) {
const haveEvent = events.find(({event}) => event === e.event); const haveEvent = events.find(({event}) => event === e.event);
if (haveEvent) { if (haveEvent) {
@ -229,7 +232,7 @@ export function parseStatechart(state: VisualEditorState, conns: Connections): [
for (const text of textsSorted) { for (const text of textsSorted) {
let parsed: ParsedText; let parsed: ParsedText;
try { try {
parsed = parseLabel(text.text); // may throw parsed = cachedParseLabel(text.text); // may throw
parsed.uid = text.uid; parsed.uid = text.uid;
} catch (e) { } catch (e) {
if (e instanceof SyntaxError) { if (e instanceof SyntaxError) {