Skip to content

Commit c5c928d

Browse files
committed
better cancellation
1 parent 2d55941 commit c5c928d

File tree

1 file changed

+43
-27
lines changed

1 file changed

+43
-27
lines changed

components/visuals/forth/components.tsx

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -530,14 +530,15 @@ export function Tokenizer() {
530530
const [tokens, setTokens] = useState<Token[]>([]);
531531
const [isRunning, setIsRunning] = useState(false);
532532

533-
const runTokenizer = async () => {
534-
if (isRunning) return;
533+
const runTokenizer = async (shouldStop: () => boolean) => {
534+
if (isRunning || shouldStop()) return;
535535
setIsRunning(true);
536536
setTokens([]);
537537
setHighlight({ start: 0, end: 0 });
538538

539539
try {
540540
await tokenize(fib10, async (newHighlight, newTokens) => {
541+
if (shouldStop()) return;
541542
setHighlight(newHighlight);
542543
setTokens([...newTokens]);
543544
await new Promise(resolve => setTimeout(resolve, 150));
@@ -547,21 +548,26 @@ export function Tokenizer() {
547548
}
548549

549550
// Sleep for 2 seconds before allowing next run
550-
await new Promise(resolve => setTimeout(resolve, 2000));
551+
if (!shouldStop()) {
552+
await new Promise(resolve => setTimeout(resolve, 2000));
553+
}
551554
setIsRunning(false);
552555
};
553556

554557
// Auto-start tokenization loop
555558
useEffect(() => {
556-
let shouldContinue = true;
559+
// Only run in browser environment
560+
if (typeof window === 'undefined') return;
561+
562+
let cancelled = false;
557563
const loop = async () => {
558-
while (shouldContinue) {
559-
await runTokenizer();
564+
while (!cancelled) {
565+
await runTokenizer(() => cancelled);
560566
}
561567
};
562568
loop();
563569
return () => {
564-
shouldContinue = false;
570+
cancelled = true;
565571
};
566572
}, []);
567573

@@ -688,8 +694,8 @@ export function Compiler() {
688694
const [bytecode, setBytecode] = useState<Bytecode[]>([]);
689695
const [isRunning, setIsRunning] = useState(false);
690696

691-
const runCompiler = async () => {
692-
if (isRunning) return;
697+
const runCompiler = async (shouldStop: () => boolean) => {
698+
if (isRunning || shouldStop()) return;
693699
setIsRunning(true);
694700
setTokens([]);
695701
setBytecode([]);
@@ -703,6 +709,7 @@ export function Compiler() {
703709

704710
// Then compile with highlighting
705711
await compile(allTokens, async (highlight, newBytecode) => {
712+
if (shouldStop()) return;
706713
setHighlightRange({ start: highlight.tokenIdxStart, end: highlight.tokenIdxEnd });
707714
setTokens([...allTokens]);
708715
setBytecode([...newBytecode]);
@@ -713,23 +720,26 @@ export function Compiler() {
713720
}
714721

715722
// Sleep for 2 seconds before next run
716-
await new Promise(resolve => setTimeout(resolve, 2000));
723+
if (!shouldStop()) {
724+
await new Promise(resolve => setTimeout(resolve, 2000));
725+
}
717726
setIsRunning(false);
718727
};
719728

720729
useEffect(() => {
721-
let shouldContinue = true;
730+
// Only run in browser environment
731+
if (typeof window === 'undefined') return;
732+
733+
let cancelled = false;
722734
const loop = async () => {
723-
while (shouldContinue) {
724-
while (true) {
725-
await runCompiler();
726-
}
735+
while (!cancelled) {
736+
await runCompiler(() => cancelled);
727737
}
728-
return () => {
729-
shouldContinue = false;
730-
};
731738
};
732739
loop();
740+
return () => {
741+
cancelled = true;
742+
};
733743
}, []);
734744

735745
// Calculate which tokens to show
@@ -852,8 +862,8 @@ export function VM() {
852862
const [variableTable, setVariableTable] = useState<number[]>([]);
853863
const [isRunning, setIsRunning] = useState(false);
854864

855-
const runVM = async () => {
856-
if (isRunning) return;
865+
const runVM = async (shouldStop: () => boolean) => {
866+
if (isRunning || shouldStop()) return;
857867
setIsRunning(true);
858868
setBytecode([]);
859869
setDataStack([]);
@@ -875,6 +885,7 @@ export function VM() {
875885

876886
// Run the VM with highlighting
877887
await vm(program, async (highlight, newDataStack, newReturnStack, newVariableTable) => {
888+
if (shouldStop()) return;
878889
setHighlightIP(highlight.ip);
879890
setDataStack([...newDataStack]);
880891
setReturnStack([...newReturnStack]);
@@ -886,21 +897,26 @@ export function VM() {
886897
}
887898

888899
// Sleep for 2 seconds before next run
889-
await new Promise(resolve => setTimeout(resolve, 2000));
900+
if (!shouldStop()) {
901+
await new Promise(resolve => setTimeout(resolve, 2000));
902+
}
890903
setIsRunning(false);
891904
};
892905

893906
useEffect(() => {
894-
let shouldContinue = true;
907+
// Only run in browser environment
908+
if (typeof window === 'undefined') return;
909+
910+
let cancelled = false;
895911
const loop = async () => {
896-
while (shouldContinue) {
897-
await runVM();
912+
while (!cancelled) {
913+
await runVM(() => cancelled);
898914
}
899-
return () => {
900-
shouldContinue = false;
901-
};
902915
};
903916
loop();
917+
return () => {
918+
cancelled = true;
919+
};
904920
}, []);
905921

906922
// Calculate which bytecode lines to show (scrolled around IP)

0 commit comments

Comments
 (0)