/* eslint-disable @typescript-eslint/no-explicit-any */ import { injectable } from 'inversify'; import type { Able, AbleRegistry } from './able'; import type { Entity } from './entity'; import { AbleChangedEvent, EntityAbles } from './entity-ables'; import { Disposable, DisposableCollection, Emitter, iterToArray } from '@gedit/utils'; import { getPayloadMetadata } from './playground-decorator-helper'; import { PlaygroundSchedule } from './playground-schedule'; export interface AbleDispatchEvent
{
payloadKey: string | Symbol,
payload: P,
entityChangedKeys: string[]
}
@injectable()
export class AbleManager implements Disposable {
readonly toDispose = new DisposableCollection();
private schedule = new PlaygroundSchedule();
protected onAbleChangedEmitter = new Emitter (payloadKey: string | Symbol, payload: P): string[] {
const hitAbles = this.payloadAbleMap.get(payloadKey);
if (!hitAbles) return [];
const emptySet: Entity[] = [];
const dispatchedEntities: Entity[] = [];
const entityChangedKeys: string[] = [];
hitAbles
.filter(able => {
const entities = this.entityDataMapByAble.get(able.type) || emptySet;
if ((able as any).globalBefore) {
payload = (able as any).globalBefore(iterToArray(entities.values()), payload);
return payload !== undefined;
}
return true;
})
.forEach(able => {
const entities = this.entityDataMapByAble.get(able.type) || emptySet;
for (const entity of entities.values()) {
// 可能两个able同时注册到同一个实体
if (!dispatchedEntities.includes(entity)) {
const preVersion = entity.version;
entity.ables.dispatchAbles (hitAbles, payload);
dispatchedEntities.push(entity);
if (entity.version !== preVersion) {
entityChangedKeys.push(entity.id);
}
}
}
if ((able as any).globalAfter) {
return (able as any).globalAfter(iterToArray(entities.values()), payload);
}
});
this.onAbleDispatchEmitter.fire({
payloadKey,
payload,
entityChangedKeys
});
return entityChangedKeys;
}
createAbleMap(entity: Entity): EntityAbles {
const ables = new EntityAbles(entity, this);
ables.onAbleChanged((event: AbleChangedEvent) => {
const ableTypes = event.ableTypes;
ableTypes.forEach(ableType => {
// 子节点不存储到全局
if (event.entity.savedInManager) {
let entities = this.entityDataMapByAble.get(ableType);
switch (event.type) {
case 'delete':
if (!entities) return;
const idex = entities.indexOf(event.entity);
if (idex !== -1) entities.splice(idex, 1);
break;
case 'add':
if (!entities) {
entities = [];
this.entityDataMapByAble.set(ableType, entities);
}
entities.push(event.entity);
break;
}
}
this.fireAbleChanged(ableType);
});
});
return ables;
}
/**
* 通过able查找entity
* @param registry
*/
getEntitiesByAble