Refactor simulation and viewer architecture
This commit is contained in:
272
apps/viewer/src/viewerControllerFactory.ts
Normal file
272
apps/viewer/src/viewerControllerFactory.ts
Normal file
@@ -0,0 +1,272 @@
|
||||
import * as THREE from "three";
|
||||
import { ViewerInteractionController } from "./viewerInteractionController";
|
||||
import { ViewerNavigationController } from "./viewerNavigationController";
|
||||
import { ViewerPresentationController } from "./viewerPresentationController";
|
||||
import { ViewerSceneDataController } from "./viewerSceneDataController";
|
||||
import { ViewerWorldLifecycle } from "./viewerWorldLifecycle";
|
||||
import { ViewerHistoryWindowController } from "./viewerHistoryWindowController";
|
||||
|
||||
export function createViewerControllers(host: any) {
|
||||
const sceneDataController = new ViewerSceneDataController({
|
||||
documentRef: document,
|
||||
getWorldGeneratedAtUtc: () => host.world?.generatedAtUtc,
|
||||
getWorldSeed: () => host.world?.seed ?? 1,
|
||||
getWorldTimeSyncMs: () => host.worldTimeSyncMs,
|
||||
getWorldPresentationContext: () => host.createWorldPresentationContext(),
|
||||
systemGroup: host.systemGroup,
|
||||
spatialNodeGroup: host.spatialNodeGroup,
|
||||
bubbleGroup: host.bubbleGroup,
|
||||
nodeGroup: host.nodeGroup,
|
||||
stationGroup: host.stationGroup,
|
||||
claimGroup: host.claimGroup,
|
||||
constructionSiteGroup: host.constructionSiteGroup,
|
||||
shipGroup: host.shipGroup,
|
||||
selectableTargets: host.selectableTargets,
|
||||
presentationEntries: host.presentationEntries,
|
||||
systemVisuals: host.systemVisuals,
|
||||
systemSummaryVisuals: host.systemSummaryVisuals,
|
||||
planetVisuals: host.planetVisuals,
|
||||
orbitLines: host.orbitLines,
|
||||
spatialNodeVisuals: host.spatialNodeVisuals,
|
||||
bubbleVisuals: host.bubbleVisuals,
|
||||
nodeVisuals: host.nodeVisuals,
|
||||
stationVisuals: host.stationVisuals,
|
||||
claimVisuals: host.claimVisuals,
|
||||
constructionSiteVisuals: host.constructionSiteVisuals,
|
||||
shipVisuals: host.shipVisuals,
|
||||
registerPresentation: host.registerPresentation.bind(host),
|
||||
});
|
||||
|
||||
const navigationController = new ViewerNavigationController({
|
||||
getWorld: () => host.world,
|
||||
getWorldTimeSyncMs: () => host.worldTimeSyncMs,
|
||||
getActiveSystemId: () => host.activeSystemId,
|
||||
setActiveSystemId: (value) => {
|
||||
host.activeSystemId = value;
|
||||
},
|
||||
getCameraMode: () => host.cameraMode,
|
||||
setCameraMode: (value) => {
|
||||
host.cameraMode = value;
|
||||
},
|
||||
getCameraTargetShipId: () => host.cameraTargetShipId,
|
||||
setCameraTargetShipId: (value) => {
|
||||
host.cameraTargetShipId = value;
|
||||
},
|
||||
getCurrentDistance: () => host.currentDistance,
|
||||
getSelectedItems: () => host.selectedItems,
|
||||
getOrbitYaw: () => host.orbitYaw,
|
||||
galaxyFocus: host.galaxyFocus,
|
||||
systemFocusLocal: host.systemFocusLocal,
|
||||
camera: host.camera,
|
||||
shipVisuals: host.shipVisuals,
|
||||
nodeVisuals: host.nodeVisuals,
|
||||
planetVisuals: host.planetVisuals,
|
||||
systemVisuals: host.systemVisuals,
|
||||
followCameraPosition: host.followCameraPosition,
|
||||
followCameraFocus: host.followCameraFocus,
|
||||
followCameraDirection: host.followCameraDirection,
|
||||
followCameraDesiredDirection: host.followCameraDesiredDirection,
|
||||
followCameraOffset: host.followCameraOffset,
|
||||
createWorldPresentationContext: () => host.createWorldPresentationContext(),
|
||||
updatePanels: () => host.updatePanels(),
|
||||
updateGamePanel: (mode: string) => host.updateGamePanel(mode),
|
||||
});
|
||||
|
||||
const presentationController = new ViewerPresentationController({
|
||||
renderer: host.renderer,
|
||||
scene: host.scene,
|
||||
camera: host.camera,
|
||||
ambienceGroup: host.ambienceGroup,
|
||||
statusEl: host.statusEl,
|
||||
networkPanelEl: host.networkPanelEl,
|
||||
performancePanelEl: host.performancePanelEl,
|
||||
systemPanelEl: host.systemPanelEl,
|
||||
systemTitleEl: host.systemTitleEl,
|
||||
systemBodyEl: host.systemBodyEl,
|
||||
networkStats: host.networkStats,
|
||||
performanceStats: host.performanceStats,
|
||||
getWorld: () => host.world,
|
||||
getActiveSystemId: () => host.activeSystemId,
|
||||
getCameraMode: () => host.cameraMode,
|
||||
getCameraTargetShipId: () => host.cameraTargetShipId,
|
||||
getZoomLevel: () => host.zoomLevel,
|
||||
getWorldTimeSyncMs: () => host.worldTimeSyncMs,
|
||||
getCurrentDistance: () => host.currentDistance,
|
||||
systemFocusLocal: host.systemFocusLocal,
|
||||
planetVisuals: host.planetVisuals,
|
||||
systemSummaryVisuals: host.systemSummaryVisuals,
|
||||
presentationEntries: host.presentationEntries,
|
||||
orbitLines: host.orbitLines,
|
||||
systemVisuals: host.systemVisuals,
|
||||
createWorldPresentationContext: () => host.createWorldPresentationContext(),
|
||||
});
|
||||
|
||||
const worldLifecycle = new ViewerWorldLifecycle({
|
||||
getWorld: () => host.world,
|
||||
setWorld: (world) => {
|
||||
host.world = world;
|
||||
},
|
||||
getWorldTimeSyncMs: () => host.worldTimeSyncMs,
|
||||
setWorldTimeSyncMs: (value) => {
|
||||
host.worldTimeSyncMs = value;
|
||||
},
|
||||
getWorldSignature: () => host.worldSignature,
|
||||
setWorldSignature: (value) => {
|
||||
host.worldSignature = value;
|
||||
},
|
||||
getStream: () => host.stream,
|
||||
setStream: (stream) => {
|
||||
host.stream = stream;
|
||||
},
|
||||
getCurrentStreamScopeKey: () => host.currentStreamScopeKey,
|
||||
setCurrentStreamScopeKey: (value) => {
|
||||
host.currentStreamScopeKey = value;
|
||||
},
|
||||
getZoomLevel: () => host.zoomLevel,
|
||||
getActiveSystemId: () => host.activeSystemId,
|
||||
getSelectedItems: () => host.selectedItems,
|
||||
getCameraMode: () => host.cameraMode,
|
||||
getCameraTargetShipId: () => host.cameraTargetShipId,
|
||||
getNetworkStats: () => host.networkStats,
|
||||
getSystemSummaryVisuals: () => host.systemSummaryVisuals,
|
||||
errorEl: host.errorEl,
|
||||
factionStripEl: host.factionStripEl,
|
||||
detailTitleEl: host.detailTitleEl,
|
||||
detailBodyEl: host.detailBodyEl,
|
||||
worldLabel: () => host.world?.label ?? "",
|
||||
rebuildSystems: (systems) => sceneDataController.rebuildSystems(systems),
|
||||
syncSpatialNodes: (nodes) => sceneDataController.syncSpatialNodes(nodes),
|
||||
syncLocalBubbles: (bubbles) => sceneDataController.syncLocalBubbles(bubbles),
|
||||
syncNodes: (nodes) => sceneDataController.syncNodes(nodes),
|
||||
syncStations: (stations) => sceneDataController.syncStations(stations),
|
||||
syncClaims: (claims) => sceneDataController.syncClaims(claims),
|
||||
syncConstructionSites: (sites) => sceneDataController.syncConstructionSites(sites),
|
||||
syncShips: (ships, tickIntervalMs) => sceneDataController.syncShips(ships, tickIntervalMs),
|
||||
applySpatialNodeDeltas: (nodes) => sceneDataController.applySpatialNodeDeltas(nodes),
|
||||
applyLocalBubbleDeltas: (bubbles) => sceneDataController.applyLocalBubbleDeltas(bubbles),
|
||||
applyNodeDeltas: (nodes) => sceneDataController.applyNodeDeltas(nodes),
|
||||
applyStationDeltas: (stations) => sceneDataController.applyStationDeltas(stations),
|
||||
applyClaimDeltas: (claims) => sceneDataController.applyClaimDeltas(claims),
|
||||
applyConstructionSiteDeltas: (sites) => sceneDataController.applyConstructionSiteDeltas(sites),
|
||||
applyShipDeltas: (ships, tickIntervalMs) => sceneDataController.applyShipDeltas(ships, tickIntervalMs),
|
||||
refreshHistoryWindows: () => host.refreshHistoryWindows(),
|
||||
resolveFocusedBubbleId: () => host.resolveFocusedBubbleId(),
|
||||
updateSystemSummaries: () => host.updateSystemSummaries(),
|
||||
applyZoomPresentation: () => presentationController.applyZoomPresentation(),
|
||||
updateNetworkPanel: () => presentationController.updateNetworkPanel(),
|
||||
updateSystemPanel: () => host.updateSystemPanel(),
|
||||
updateGamePanel: (mode) => host.updateGamePanel(mode),
|
||||
describeSelectionParent: (selection) => host.describeSelectionParent(selection),
|
||||
});
|
||||
|
||||
const historyController = new ViewerHistoryWindowController({
|
||||
historyLayerEl: host.historyLayerEl,
|
||||
historyWindows: host.historyWindows,
|
||||
getWorld: () => host.world,
|
||||
getHistoryWindowCounter: () => host.historyWindowCounter,
|
||||
setHistoryWindowCounter: (value) => {
|
||||
host.historyWindowCounter = value;
|
||||
},
|
||||
getHistoryWindowZCounter: () => host.historyWindowZCounter,
|
||||
setHistoryWindowZCounter: (value) => {
|
||||
host.historyWindowZCounter = value;
|
||||
},
|
||||
getHistoryWindowDragId: () => host.historyWindowDragId,
|
||||
setHistoryWindowDragId: (value) => {
|
||||
host.historyWindowDragId = value;
|
||||
},
|
||||
getHistoryWindowDragPointerId: () => host.historyWindowDragPointerId,
|
||||
setHistoryWindowDragPointerId: (value) => {
|
||||
host.historyWindowDragPointerId = value;
|
||||
},
|
||||
historyWindowDragOffset: host.historyWindowDragOffset,
|
||||
renderRecentEvents: (entityKind, entityId) => presentationController.renderRecentEvents(entityKind, entityId),
|
||||
});
|
||||
|
||||
const interactionController = new ViewerInteractionController({
|
||||
renderer: host.renderer,
|
||||
raycaster: host.raycaster,
|
||||
mouse: host.mouse,
|
||||
camera: host.camera,
|
||||
selectableTargets: host.selectableTargets,
|
||||
hoverLabelEl: host.hoverLabelEl,
|
||||
marqueeEl: host.marqueeEl,
|
||||
keyState: host.keyState,
|
||||
getWorld: () => host.world,
|
||||
getActiveSystemId: () => host.activeSystemId,
|
||||
getSelectedItems: () => host.selectedItems,
|
||||
setSelectedItems: (items) => {
|
||||
host.selectedItems = items;
|
||||
},
|
||||
getDragMode: () => host.dragMode,
|
||||
setDragMode: (mode) => {
|
||||
host.dragMode = mode;
|
||||
},
|
||||
getDragPointerId: () => host.dragPointerId,
|
||||
setDragPointerId: (pointerId) => {
|
||||
host.dragPointerId = pointerId;
|
||||
},
|
||||
dragStart: host.dragStart,
|
||||
dragLast: host.dragLast,
|
||||
getMarqueeActive: () => host.marqueeActive,
|
||||
setMarqueeActive: (value) => {
|
||||
host.marqueeActive = value;
|
||||
},
|
||||
getSuppressClickSelection: () => host.suppressClickSelection,
|
||||
setSuppressClickSelection: (value) => {
|
||||
host.suppressClickSelection = value;
|
||||
},
|
||||
getDesiredDistance: () => host.desiredDistance,
|
||||
setDesiredDistance: (value) => {
|
||||
host.desiredDistance = value;
|
||||
},
|
||||
getCameraMode: () => host.cameraMode,
|
||||
setCameraMode: (value) => {
|
||||
host.cameraMode = value;
|
||||
},
|
||||
getCameraTargetShipId: () => host.cameraTargetShipId,
|
||||
setCameraTargetShipId: (value) => {
|
||||
host.cameraTargetShipId = value;
|
||||
},
|
||||
getFollowCameraPosition: () => host.followCameraPosition,
|
||||
getFollowCameraFocus: () => host.followCameraFocus,
|
||||
screenPointFromClient: (x, y) => presentationController.screenPointFromClient(x, y),
|
||||
applyOrbitDelta: (delta: THREE.Vector2) => {
|
||||
host.orbitYaw += delta.x * 0.008;
|
||||
host.orbitPitch = THREE.MathUtils.clamp(host.orbitPitch + delta.y * 0.004, 0.18, 1.3);
|
||||
},
|
||||
syncFollowStateFromSelection: () => navigationController.syncFollowStateFromSelection(),
|
||||
updatePanels: () => host.updatePanels(),
|
||||
focusOnSelection: (selection) => navigationController.focusOnSelection(selection),
|
||||
updateGamePanel: (mode) => host.updateGamePanel(mode),
|
||||
historyController,
|
||||
});
|
||||
|
||||
return {
|
||||
historyController,
|
||||
sceneDataController,
|
||||
navigationController,
|
||||
presentationController,
|
||||
worldLifecycle,
|
||||
interactionController,
|
||||
};
|
||||
}
|
||||
|
||||
export function wireViewerEvents(host: any) {
|
||||
host.renderer.domElement.addEventListener("pointerdown", host.interactionController.onPointerDown);
|
||||
host.renderer.domElement.addEventListener("pointermove", host.interactionController.onPointerMove);
|
||||
host.renderer.domElement.addEventListener("pointerup", host.interactionController.onPointerUp);
|
||||
host.renderer.domElement.addEventListener("pointerleave", host.interactionController.onPointerUp);
|
||||
host.renderer.domElement.addEventListener("click", host.interactionController.onClick);
|
||||
host.renderer.domElement.addEventListener("dblclick", host.interactionController.onDoubleClick);
|
||||
host.renderer.domElement.addEventListener("wheel", host.interactionController.onWheel, { passive: false });
|
||||
host.factionStripEl.addEventListener("click", host.interactionController.onShipStripClick);
|
||||
host.factionStripEl.addEventListener("dblclick", host.interactionController.onShipStripDoubleClick);
|
||||
host.historyLayerEl.addEventListener("click", host.interactionController.onHistoryLayerClick);
|
||||
host.historyLayerEl.addEventListener("pointerdown", host.interactionController.onHistoryLayerPointerDown);
|
||||
window.addEventListener("pointermove", host.interactionController.onHistoryWindowPointerMove);
|
||||
window.addEventListener("pointerup", host.interactionController.onHistoryWindowPointerUp);
|
||||
window.addEventListener("keydown", host.interactionController.onKeyDown);
|
||||
window.addEventListener("keyup", host.interactionController.onKeyUp);
|
||||
window.addEventListener("resize", host.onResize);
|
||||
}
|
||||
Reference in New Issue
Block a user