import { inject, injectable } from 'inversify'; import { AbleManager, AbleRegistry, Entity, EntityManager, EntityRegistry } from '../../common'; import { Layer } from '../layer'; type SelectorVersion = Map; export interface LayerEntitiesSelector { lastAbleVersion?: SelectorVersion lastEntityVersion?: SelectorVersion entities: EntityRegistry[], ables: AbleRegistry[] } /** * 选择器用来在pipeline绘制之前,筛选并注入entities */ @injectable() export class PipelineEntitiesSelector { protected layerEntitiesSelectorMap: WeakMap = new WeakMap(); readonly entityLayerMap: Map> = new Map(); readonly ableLayerMap: Map> = new Map(); @inject(AbleManager) ableManager: AbleManager; @inject(EntityManager) entityManager: EntityManager; /** * 订阅关联的entity,会影响draw */ subscribeEntities(layer: Layer, entities: EntityRegistry[]): void { const selector = this.getSelector(layer); entities.forEach(e => { if (!selector.entities.includes(e)) selector.entities.push(e); let layers = this.entityLayerMap.get(e.type); if (!layers) { layers = new Set(); this.entityLayerMap.set(e.type, layers); } layers.add(layer); }); } /** * 订阅关联的able, 会影响draw */ subscribeAbles(layer: Layer, ables: AbleRegistry[]): void { const selector = this.getSelector(layer); ables.forEach(able => { if (!selector.ables.includes(able)) selector.ables.push(able); let layers = this.ableLayerMap.get(able.type); if (!layers) { layers = new Set(); this.ableLayerMap.set(able.type, layers); } layers.add(layer); }); } protected getSelector(layer: Layer): LayerEntitiesSelector { let selector = this.layerEntitiesSelectorMap.get(layer); if (!selector) { selector = { entities: [], ables: [] }; this.layerEntitiesSelectorMap.set(layer, selector); } return selector; } /** * 查询layer关联的实体 */ getEntities(layer: Layer): { entities: Entity[], changed: boolean } { const selector = this.layerEntitiesSelectorMap.get(layer); if (!selector) return { entities: [], changed: false }; const all: Set = new Set; const entityVersion: SelectorVersion = new Map; let entityChanged = false; selector.entities.forEach(registry => { const entities = this.entityManager.getEntities(registry); for (const item of entities) { all.add(item); } }); selector.ables.forEach(registry => { const entities = this.ableManager.getEntitiesByAble(registry); for (const item of entities) { all.add(item); } }); // To array const result: Entity[] = []; for (const item of all.values()) { result.push(item); entityVersion.set(item.id, item.version); } /** * 检查版本变化 */ if (checkChanged(entityVersion, selector.lastEntityVersion)) { selector.lastEntityVersion = entityVersion; entityChanged = true; } return { entities: result, changed: entityChanged }; } } function checkChanged(v1: SelectorVersion = new Map, v2: SelectorVersion = new Map): boolean { if (v1.size !== v2.size) return true; for (const key of v1.keys()) { if (v1.get(key) !== v2.get(key)) return true; } return false; }