-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp-controller.ts
More file actions
119 lines (115 loc) · 4.76 KB
/
Copy pathapp-controller.ts
File metadata and controls
119 lines (115 loc) · 4.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { createHttpSimulationBackend } from "./api.js";
import { createAppControllerBootstrap } from "./app-controller-bootstrap.js";
import { createAppControllerSync } from "./app-controller-sync.js";
import { initializeAppController } from "./app-controller-startup.js";
import type { AppActionSet } from "./types/actions.js";
import type { AppController, CreateAppControllerOptions } from "./types/controller-app.js";
import type { ConfigSyncController, UiSessionController } from "./types/controller-sync-session.js";
import type { InteractionController, ViewportController } from "./types/controller-view.js";
export function createAppController({
elements,
gridView,
backend = createHttpSimulationBackend(),
onError = (error: unknown) => console.error(error),
}: CreateAppControllerOptions): AppController {
let interactions: InteractionController | null = null;
let viewportController: ViewportController | null = null;
let configSyncController: ConfigSyncController | null = null;
let uiSessionController: UiSessionController | null = null;
let controlActions: AppActionSet | null = null;
let disposed = false;
const controllerRefs = {
configSyncController: null as ConfigSyncController | null,
uiSessionController: null as UiSessionController | null,
};
const bootstrap = createAppControllerBootstrap({
elements,
gridView,
getSyncState: () =>
controllerRefs.configSyncController
? controllerRefs.configSyncController.getViewState()
: {
pendingRuleName: null,
syncingRuleName: null,
pendingSpeed: null,
syncingSpeed: null,
isSyncing: false,
hasPendingRuleSync: false,
hasPendingSpeedSync: false,
shouldLockRule: false,
shouldLockSpeed: false,
},
});
const { state, mutationRunner, appView } = bootstrap;
const sync = createAppControllerSync({
state,
appView,
onError,
fetchRulesFn: () => backend.getRules(),
fetchStateFn: () => backend.getState(),
getConfigSyncController: () => controllerRefs.configSyncController,
getUiSessionController: () => controllerRefs.uiSessionController,
getRefreshState: () => sync.refreshState,
});
async function init(): Promise<void> {
({
interactions,
viewportController,
configSyncController,
uiSessionController,
controlActions,
} = await initializeAppController({
state,
elements,
gridView,
mutationRunner,
appView,
onError,
postControlFn: backend.postControl.bind(backend),
toggleCellRequestFn: backend.toggleCell.bind(backend),
setCellRequestFn: backend.setCell.bind(backend),
setCellsRequestFn: backend.setCells.bind(backend),
sync,
onConfigSyncController: (nextConfigSyncController) => {
controllerRefs.configSyncController = nextConfigSyncController;
configSyncController = nextConfigSyncController;
},
onUiSessionController: (nextUiSessionController) => {
controllerRefs.uiSessionController = nextUiSessionController;
uiSessionController = nextUiSessionController;
},
}));
}
function dispose(): void {
if (disposed) {
return;
}
disposed = true;
viewportController?.dispose();
configSyncController?.dispose();
mutationRunner.dispose();
void Promise.resolve(backend.dispose()).catch(onError);
interactions = null;
viewportController = null;
configSyncController = null;
uiSessionController = null;
controlActions = null;
controllerRefs.configSyncController = null;
controllerRefs.uiSessionController = null;
}
return {
init,
dispose,
refreshState: sync.refreshState,
loadRules: sync.loadRules,
applySimulationState: sync.applySimulationState,
applyCellSize: (nextCellSize) => controlActions?.setCellSize?.(nextCellSize),
applyPaintState: (nextPaintState) => controlActions?.setPaintState(nextPaintState),
loadPattern: (payload) => controlActions?.loadPattern(payload) ?? Promise.resolve(null),
getState: () => state,
getInteractions: () => interactions,
getViewportController: () => viewportController,
getConfigSyncController: () => configSyncController,
getUiSessionController: () => uiSessionController,
};
}