import { makeAutoObservable } from "mobx"; import type { ObjectInstance, ObjectType } from "../types"; import { MobxReconcilerMap } from '../utils/reconciler'; import { ObjectGeometryViewItem, ObjectTypeGeometryViewItem, ControlledCameraViewItem, ViewItem } from './viewLayers'; import type { WorldState } from "./worldState"; import { ObjectSelectionViewItem } from "./viewLayers/objectSelection"; import type { WorldEditorState } from "./worldEditorState"; export class ViewState { public objectTypeGeometries: MobxReconcilerMap; public objectGeometries: MobxReconcilerMap; public camera?: ControlledCameraViewItem; private readonly editor: WorldEditorState; constructor(world: WorldState, editor: WorldEditorState) { this.editor = editor; makeAutoObservable( this, ); this.camera = new ControlledCameraViewItem(); this.objectTypeGeometries = new MobxReconcilerMap({ reaction: () => Object.values(world.data.objectTypes), keyOf: (ot) => ot.id, mapItem: (ot) => new ObjectTypeGeometryViewItem(this, ot), updateItem: () => true, disposeItem: (item) => { item.dispose(); }, }); this.objectGeometries = new MobxReconcilerMap({ reaction: () => Object.values(world.data.initialScene.objects) .filter(obj => obj.visible) .filter(obj => !!world.data.objectTypes[obj.typeId]), keyOf: (obj) => obj.id, mapItem: (obj) => new ObjectGeometryViewItem(obj, this.objectTypeGeometries.get(obj.typeId)!), }); } public dispose(): void { this.objectTypeGeometries.dispose(); this.objectGeometries.dispose(); } public get selectedObject(): ObjectSelectionViewItem | undefined { const sel = this.editor.selection; if (sel?.type !== 'object') return; const geom = this.objectGeometries.get(sel.id); if (!geom) return; return new ObjectSelectionViewItem(geom, sel.editMode); } public get items(): ViewItem[] { return [ ...this.objectTypeGeometries, ...this.objectGeometries, ...[this.camera ? [this.camera] : []], ...[this.selectedObject ? [this.selectedObject] : []], ]; } }