Merged PR 392: Events: Fix needing to use setTimeout for callbacks

This commit is contained in:
Eric Nguyen 2023-03-01 09:53:06 +00:00
parent 6792d5e105
commit 460669987d
8 changed files with 182 additions and 88 deletions

View file

@ -15,16 +15,16 @@ import { type IEditorState } from '../Interfaces/IEditorState';
import { type IHistoryState } from '../Interfaces/IHistoryState';
import { FindContainerById } from '../utils/itertools';
import { GetCircularReplacer } from '../utils/saveload';
import { type WrappedCustomEvent } from './AppEvents';
interface IEditorEventParams {
root: Element | Document
editorState: IEditorState
setNewHistory: (newHistory: IHistoryState[], historyCurrentStep?: number) => void
eventInitDict?: CustomEventInit
}
export interface IEditorEvent {
name: string
func: (params: IEditorEventParams) => void
func: (params: IEditorEventParams) => WrappedCustomEvent
}
export const events: IEditorEvent[] = [
@ -41,6 +41,7 @@ export const events: IEditorEvent[] = [
];
export function UseCustomEvents(
callbackQueue: React.RefObject<CustomEvent[]>,
root: Element | Document,
history: IHistoryState[],
historyCurrentStep: number,
@ -64,12 +65,17 @@ export function UseCustomEvents(
for (const event of events) {
function Func(eventInitDict?: CustomEventInit): void {
event.func({
root,
const customEvent = event.func({
editorState,
setNewHistory,
eventInitDict
});
if (customEvent.runAfterRender) {
callbackQueue.current?.push(customEvent.event);
} else {
root.dispatchEvent(customEvent.event);
}
}
current?.addEventListener(event.name, Func);
funcs.set(event.name, Func);
@ -84,6 +90,22 @@ export function UseCustomEvents(
}
};
});
useEffect(() => {
if (callbackQueue.current === null) {
return;
}
while (callbackQueue.current.length > 0) {
const callback = callbackQueue.current.shift();
if (callback === undefined) {
continue;
}
root.dispatchEvent(callback);
}
});
}
export function UseEditorListener(
@ -104,74 +126,83 @@ export function UseEditorListener(
}
function GetEditorState({
root,
editorState
}: IEditorEventParams): void {
const customEvent = new CustomEvent<IEditorState>('getEditorState', { detail: structuredClone(editorState) });
root.dispatchEvent(customEvent);
}: IEditorEventParams): WrappedCustomEvent {
const event = new CustomEvent<IEditorState>('getEditorState', { detail: structuredClone(editorState) });
return {
event,
runAfterRender: false
};
}
function GetEditorStateAsString({
root,
editorState
}: IEditorEventParams): void {
}: IEditorEventParams): WrappedCustomEvent {
const spaces = import.meta.env.DEV
? 4
: 0;
const data = JSON.stringify(editorState, GetCircularReplacer(), spaces);
const customEvent = new CustomEvent<string>('getEditorStateAsString', { detail: data });
root.dispatchEvent(customEvent);
const event = new CustomEvent<string>('getEditorStateAsString', { detail: data });
return {
event,
runAfterRender: false
};
}
function SetHistory({
root,
editorState,
setNewHistory,
eventInitDict
}: IEditorEventParams): void {
}: IEditorEventParams): WrappedCustomEvent {
const history: IHistoryState[] = eventInitDict?.detail.history;
const historyCurrentStep: number | undefined = eventInitDict?.detail.historyCurrentStep;
setNewHistory(history, historyCurrentStep);
const customEvent = new CustomEvent<IEditorState>('setHistory', { detail: editorState });
root.dispatchEvent(customEvent);
const event = new CustomEvent<IEditorState>('setHistory', { detail: editorState });
return {
event,
runAfterRender: true
};
}
function GetCurrentHistoryState({
root,
editorState
}: IEditorEventParams): void {
const customEvent = new CustomEvent<IHistoryState>(
}: IEditorEventParams): WrappedCustomEvent {
const event = new CustomEvent<IHistoryState>(
'getCurrentHistoryState',
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
);
root.dispatchEvent(customEvent);
return {
event,
runAfterRender: true
};
}
function AppendNewState({
root,
editorState,
setNewHistory,
eventInitDict
}: IEditorEventParams): void {
}: IEditorEventParams): WrappedCustomEvent {
const state: IHistoryState = eventInitDict?.detail.state;
const history = GetCurrentHistory(editorState.history, editorState.historyCurrentStep);
history.push(state);
setNewHistory(history);
const customEvent = new CustomEvent<IHistoryState>(
const event = new CustomEvent<IHistoryState>(
'appendNewState',
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
);
root.dispatchEvent(customEvent);
return {
event,
runAfterRender: true
};
}
function AddContainer({
root,
editorState,
setNewHistory,
eventInitDict
}: IEditorEventParams): void {
}: IEditorEventParams): WrappedCustomEvent {
const {
index,
type,
@ -189,19 +220,21 @@ function AddContainer({
);
setNewHistory(newHistory);
const customEvent = new CustomEvent<IHistoryState>(
const event = new CustomEvent<IHistoryState>(
'addContainer',
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
);
root.dispatchEvent(customEvent);
return {
event,
runAfterRender: true
};
}
function AppendContainer({
root,
editorState,
setNewHistory,
eventInitDict
}: IEditorEventParams): void {
}: IEditorEventParams): WrappedCustomEvent {
const {
type,
parentId
@ -222,19 +255,21 @@ function AppendContainer({
);
setNewHistory(newHistory);
const customEvent = new CustomEvent<IHistoryState>(
const event = new CustomEvent<IHistoryState>(
'appendContainerToSelectedContainer',
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
);
root.dispatchEvent(customEvent);
return {
event,
runAfterRender: true
};
}
function DeleteContainer({
root,
editorState,
setNewHistory,
eventInitDict
}: IEditorEventParams): void {
}: IEditorEventParams): WrappedCustomEvent {
const {
containerId
} = eventInitDict?.detail;
@ -248,19 +283,21 @@ function DeleteContainer({
);
setNewHistory(newHistory);
const customEvent = new CustomEvent<IHistoryState>(
const event = new CustomEvent<IHistoryState>(
'deleteContainer',
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
);
root.dispatchEvent(customEvent);
return {
event,
runAfterRender: true
};
}
function AddSymbol({
root,
editorState,
setNewHistory,
eventInitDict
}: IEditorEventParams): void {
}: IEditorEventParams): WrappedCustomEvent {
const {
name
} = eventInitDict?.detail;
@ -275,19 +312,21 @@ function AddSymbol({
);
setNewHistory(newHistory);
const customEvent = new CustomEvent<IHistoryState>(
const event = new CustomEvent<IHistoryState>(
'AddSymbol',
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
);
root.dispatchEvent(customEvent);
return {
event,
runAfterRender: true
};
}
function DeleteSymbol({
root,
editorState,
setNewHistory,
eventInitDict
}: IEditorEventParams): void {
}: IEditorEventParams): WrappedCustomEvent {
const {
symbolId
} = eventInitDict?.detail;
@ -300,9 +339,12 @@ function DeleteSymbol({
);
setNewHistory(newHistory);
const customEvent = new CustomEvent<IHistoryState>(
const event = new CustomEvent<IHistoryState>(
'DeleteSymbol',
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) }
);
root.dispatchEvent(customEvent);
return {
event,
runAfterRender: true
};
}