From e796d131ac4bae33757ee5fc50665b9d17f144d1 Mon Sep 17 00:00:00 2001 From: luoyifan Date: Wed, 18 Jun 2025 00:06:53 +0800 Subject: [PATCH] =?UTF-8?q?RuntimeManager=20=E8=BF=90=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/base/BaseRenderer.ts | 20 +++++++++++ src/core/engine/Viewport.ts | 7 ++-- src/core/manager/RuntimeManager.ts | 68 ++++++++++++++++++++++++++++++++++++++ src/modules/rack/RackRenderer.ts | 31 ++++++++++++++++- 4 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 src/core/manager/RuntimeManager.ts diff --git a/src/core/base/BaseRenderer.ts b/src/core/base/BaseRenderer.ts index 375c808..f0b8d9e 100644 --- a/src/core/base/BaseRenderer.ts +++ b/src/core/base/BaseRenderer.ts @@ -111,6 +111,10 @@ export default abstract class BaseRenderer { const point = this.createPoint(item, option) point.visible = ((typeof item.v !== 'undefined') ? item.v : true) + if (item.dt.storeAt?.item) { + this.tempViewport.runtimeManager.addStoreAt(item.dt.storeAt?.item, item.id) + } + setUserDataForItem(item, point) this.afterCreateOrUpdatePoint(item, option, point) this.tempViewport.entityManager.appendObject(item.id, point) @@ -198,15 +202,31 @@ export default abstract class BaseRenderer { throw new Error('unkown Point type', object) } + const item = this.tempViewport.entityManager.findItemById(id) + if (item.dt.storeAt?.item) { + this.tempViewport.runtimeManager.removeStoreAt(item.dt.storeAt?.item, id) + } + this.tempViewport.entityManager.deleteEntityOnly(id) this.tempViewport.entityManager.deleteObjectsOnly(id) } updatePointForEntity(item: ItemJson, option?: RendererCudOption): Object3DLike { const originObject = this.tempViewport.entityManager.findObjectById(item.id) + const originItem = this.tempViewport.entityManager.findItemById(item.id) const newObject = this.updatePoint(item, originObject, option) newObject.visible = ((typeof item.v !== 'undefined') ? item.v : true) + // 库存位置发生改变 + if (originItem.dt.storeAt?.item !== item.dt.storeAt?.item) { + if (originItem.dt.storeAt?.item) { + this.tempViewport.runtimeManager.removeStoreAt(originItem.dt.storeAt?.item, item.id) + } + if (item.dt.storeAt?.item) { + this.tempViewport.runtimeManager.addStoreAt(item.dt.storeAt?.item, item.id) + } + } + if (originObject !== newObject) { // 如果更新后的对象和原来的对象不同, 则替换掉 setUserDataForItem(item, newObject) diff --git a/src/core/engine/Viewport.ts b/src/core/engine/Viewport.ts index 4194046..faae13a 100644 --- a/src/core/engine/Viewport.ts +++ b/src/core/engine/Viewport.ts @@ -25,12 +25,13 @@ import type InstanceMeshManager from '@/core/manager/InstanceMeshManager.ts' import ItemFindManager from '@/core/manager/ItemFindManager.ts' import { MapControls } from 'three/examples/jsm/controls/MapControls' import ModelManager from '@/core/script/ModelManager.ts' +import RuntimeManager from '@/core/manager/RuntimeManager.ts' /** * 视窗对象 * 所有状态管理器,场景,控制器,摄像机,实体管理器, 都在这里可以取到 */ -export default class Viewport implements Model { +export default class Viewport { viewerDom: HTMLElement camera: THREE.Camera // THREE.OrthographicCamera renderer: THREE.WebGLRenderer @@ -48,6 +49,7 @@ export default class Viewport implements Model { itemFindManager = new ItemFindManager() interactionManager = new InteractionManager() modelManager = new ModelManager() + runtimeManager = new RuntimeManager() // 状态管理器 stateManager: StateManager @@ -60,7 +62,8 @@ export default class Viewport implements Model { markRaw(this.entityManager), markRaw(this.itemFindManager), markRaw(this.interactionManager), - markRaw(this.modelManager) + markRaw(this.modelManager), + markRaw(this.runtimeManager) ] // 对象实例管理器 moduleName -> InstanceMeshManager diff --git a/src/core/manager/RuntimeManager.ts b/src/core/manager/RuntimeManager.ts new file mode 100644 index 0000000..468200e --- /dev/null +++ b/src/core/manager/RuntimeManager.ts @@ -0,0 +1,68 @@ +import type Viewport from '@/core/engine/Viewport.ts' + +/** + * 运行时管理器, 管理运行时的各种数据 + */ +export default class RuntimeManager { + private viewport: Viewport + private readonly storeRackMap = new Map>() + + init(viewport: Viewport): void { + this.viewport = viewport + } + + /** + * 在指定的货架位置添加存储项 + * @param rackId 货架ID + * @param itemId 存储项ID + */ + addStoreAt(rackId: string, itemId: string): void { + if (!this.storeRackMap.has(rackId)) { + this.storeRackMap.set(rackId, new Set()) + } + this.storeRackMap.get(rackId).add(itemId) + } + + /** + * 从指定的货架位置移除存储项 + * @param rackId 货架ID + * @param itemId 存储项ID + */ + removeStoreAt(rackId: string, itemId: string): void { + const rack = this.storeRackMap.get(rackId) + if (rack) { + rack.delete(itemId) + if (rack.size === 0) { + this.storeRackMap.delete(rackId) + } + } + } + + /** + * 获取指定货架位置的所有存储项 + * @param rackId 货架ID + */ + getItemsByRack(rackId: string): Set | undefined { + return this.storeRackMap.get(rackId) + } + + /** + * 移除指定货架 + * @param rackId 货架ID + */ + removeRack(rackId: string): void { + this.storeRackMap.delete(rackId) + } + + /** + * 清空所有存储项 + */ + clear() { + this.storeRackMap.clear() + } + + dispose(): void { + this.viewport = null + this.storeRackMap.clear() + } +} diff --git a/src/modules/rack/RackRenderer.ts b/src/modules/rack/RackRenderer.ts index 339f19f..e89eb01 100644 --- a/src/modules/rack/RackRenderer.ts +++ b/src/modules/rack/RackRenderer.ts @@ -74,7 +74,7 @@ export default class RackRenderer extends BaseRenderer { // 暂时不用算格子 const cell = item.dt?.storeAt?.cell || 0 // 目标货架 - const rack = viewport.entityManager.findItemById(item.dt.storeAt.item) + const rack = viewport.stateManager.findItemById(item.dt.storeAt.item) const rackWidth = decimalSumBy(rack.dt.bays, (b: any) => b.bayWidth) const bays = rack.dt.bays const levelHeights = rack.dt.bays[bay]?.levelHeight @@ -135,6 +135,35 @@ export default class RackRenderer extends BaseRenderer { // 禁止缩放, item.tf[2][0] = item.dt.rackWidth item.tf[2][1] = item.dt.rackHeight + + + // 更新放在内部的所有箱子 + const subItems = this.tempViewport.runtimeManager.getItemsByRack(item.id) + const viewport = this.tempViewport + + if (subItems) { + _.defer(() => { + viewport.stateManager.update(({ getEntity, putEntity, deleteEntity, addEntity }) => { + for (const subItemId of subItems) { + const subItem = getEntity(subItemId) + if (subItem) { + const { position, rotation } = this.getStorePlacement(viewport, subItem) + if (position) { + subItem.tf[0][0] = position[0] + subItem.tf[0][1] = position[1] + subItem.tf[0][2] = position[2] + subItem.tf[1][0] = rotation[0] + subItem.tf[1][1] = rotation[1] + subItem.tf[1][2] = rotation[2] + putEntity(subItem) + } + } + } + }) + + }) + } + return group }