|
|
|
@ -4,36 +4,6 @@ import type BaseRenderer from '@/core/base/BaseRenderer' |
|
|
|
import { getRenderer } from './ModuleManager' |
|
|
|
import { getLineId, parseLineId } from '@/core/ModelUtils' |
|
|
|
|
|
|
|
/** |
|
|
|
* 关系详情 |
|
|
|
*/ |
|
|
|
export class Relation { |
|
|
|
center = new Set<string>() |
|
|
|
input = new Set<string>() |
|
|
|
output = new Set<string>() |
|
|
|
|
|
|
|
add(type: LinkType, id: string) { |
|
|
|
if (type === 'in') |
|
|
|
return this.input.add(id) |
|
|
|
else if (type === 'out') |
|
|
|
return this.output.add(id) |
|
|
|
else if (type === 'center') |
|
|
|
return this.center.add(id) |
|
|
|
else |
|
|
|
throw new Error(`Unknown link type: ${type}`) |
|
|
|
} |
|
|
|
|
|
|
|
delete(type: LinkType, id: string) { |
|
|
|
if (type === 'in') |
|
|
|
return this.input.delete(id) |
|
|
|
else if (type === 'out') |
|
|
|
return this.output.delete(id) |
|
|
|
else if (type === 'center') |
|
|
|
return this.center.delete(id) |
|
|
|
else |
|
|
|
throw new Error(`Unknown link type: ${type}`) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 实体管理器 |
|
|
|
@ -66,10 +36,37 @@ export default class EntityManager { |
|
|
|
update: new Map<string, LineDiffItem>(), |
|
|
|
delete: new Map<string, LineDiffItem>() |
|
|
|
} |
|
|
|
// 记录所有发生过变化的实体, 用于在 endEntityUpdate 时进行写回给 StateManager
|
|
|
|
private readonly writeBackEntities = new Set<string>() |
|
|
|
isUpdating = false |
|
|
|
|
|
|
|
getAllEntities(): Map<string, ItemJson> { |
|
|
|
return this.entities |
|
|
|
dispose() { |
|
|
|
// 清理所有差量渲染器
|
|
|
|
for (const renderer of this.diffRenderer.values()) { |
|
|
|
renderer.dispose() |
|
|
|
} |
|
|
|
this.diffRenderer.clear() |
|
|
|
|
|
|
|
// 清理所有实体和关系索引
|
|
|
|
this.entities.clear() |
|
|
|
this.relationIndex.clear() |
|
|
|
this.objects.clear() |
|
|
|
this.lines.clear() |
|
|
|
this.writeBackEntities.clear() |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 克隆需要回写的实体集合 |
|
|
|
*/ |
|
|
|
cloneWriteBackEntities(): Map<string, ItemJson> { |
|
|
|
const entities = new Map<string, ItemJson>() |
|
|
|
for (const id of this.writeBackEntities) { |
|
|
|
const entity = this.entities.get(id) |
|
|
|
if (!entity) continue |
|
|
|
entities.set(id, _.cloneDeep(entity)) |
|
|
|
} |
|
|
|
console.log('需要回写', entities.size, '行数据') |
|
|
|
return entities |
|
|
|
} |
|
|
|
|
|
|
|
init(viewport: Viewport) { |
|
|
|
@ -82,6 +79,7 @@ export default class EntityManager { |
|
|
|
beginEntityUpdate(): void { |
|
|
|
this.isUpdating = true |
|
|
|
this.viewport.beginViewUpdate() |
|
|
|
this.writeBackEntities.clear() |
|
|
|
this.diffRenderer.clear() |
|
|
|
this.lineDiffs.create.clear() |
|
|
|
this.lineDiffs.update.clear() |
|
|
|
@ -96,34 +94,36 @@ export default class EntityManager { |
|
|
|
throw new Error('Entity must have an id') |
|
|
|
} |
|
|
|
const entity = _.cloneDeep(entityRaw) as ItemJson |
|
|
|
const originEntity = this.entities.get(entity.id) |
|
|
|
|
|
|
|
// 找到这个数据的渲染器
|
|
|
|
const renderer = this.getDiffRenderer(entity.t) |
|
|
|
|
|
|
|
const originEntity = this.entities.get(entity.id) |
|
|
|
// 先判断坐标是否变化
|
|
|
|
const coordinateChanged = originEntity?.tf && entity?.tf && !_.isEqual(originEntity.tf[0], entity.tf[0]) |
|
|
|
|
|
|
|
this.entities.set(entity.id, entity) |
|
|
|
|
|
|
|
// 更新关系网
|
|
|
|
this.updateRelations(entity, originEntity) |
|
|
|
|
|
|
|
// 判断坐标是否变化
|
|
|
|
|
|
|
|
if (originEntity?.tf && entity?.tf && !_.isEqual(originEntity.tf[0], entity.tf[0])) { |
|
|
|
if (coordinateChanged) { |
|
|
|
this.writeBackEntities.add(entity.id) |
|
|
|
// 点的坐标发生变化, 要通知所有关联线更新
|
|
|
|
const relations = this.relationIndex.get(entity.id) |
|
|
|
if (!relations) return |
|
|
|
|
|
|
|
for (const type of (['center', 'in', 'out'] as LinkType[])) { |
|
|
|
const relatedIds = relations[type] |
|
|
|
if (!relatedIds) continue |
|
|
|
|
|
|
|
for (const relatedId of relatedIds) { |
|
|
|
const lineId = getLineId(entity.id, relatedId, type) |
|
|
|
this.lineDiffs.update.set(lineId, { startId: entity.id, endId: relatedId, type }) |
|
|
|
|
|
|
|
// 如果是双向线(比如 center),也要反向加一次
|
|
|
|
if (type === 'center') { |
|
|
|
this.lineDiffs.update.set(lineId, { startId: relatedId, endId: entity.id, type }) |
|
|
|
const relation = this.relationIndex.get(entity.id) |
|
|
|
if (relation) { |
|
|
|
for (const type of (['center', 'in', 'out'] as LinkType[])) { |
|
|
|
const relatedIds = relation[type] |
|
|
|
if (!relatedIds) continue |
|
|
|
|
|
|
|
for (const relatedId of relatedIds) { |
|
|
|
const lineId = getLineId(entity.id, relatedId, type) |
|
|
|
this.lineDiffs.update.set(lineId, { startId: entity.id, endId: relatedId, type }) |
|
|
|
|
|
|
|
// 如果是双向线(比如 center),也要反向加一次
|
|
|
|
if (type === 'center') { |
|
|
|
this.lineDiffs.update.set(lineId, { startId: relatedId, endId: entity.id, type }) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -146,6 +146,7 @@ export default class EntityManager { |
|
|
|
if (!entity) return |
|
|
|
|
|
|
|
option.originEntity = _.cloneDeep(entity) |
|
|
|
this.writeBackEntities.add(entity.id) |
|
|
|
|
|
|
|
// 先生成线差量,再清理关系
|
|
|
|
this.generateLineDiffsForDelete(id) |
|
|
|
@ -210,6 +211,7 @@ export default class EntityManager { |
|
|
|
|
|
|
|
if (start.t !== itemTypeName) { |
|
|
|
// 只通知起点对应的渲染器
|
|
|
|
console.error(`Line ${lineId} start point type mismatch: expected ${itemTypeName}, got ${start.t}`) |
|
|
|
continue |
|
|
|
} |
|
|
|
renderer.updateLine(start, end, lineDiffItem.type) |
|
|
|
@ -312,6 +314,7 @@ export default class EntityManager { |
|
|
|
if (!newIds.has(relatedId)) { |
|
|
|
const rev = this.relationIndex.get(relatedId) |
|
|
|
rev.delete(relationType, id) |
|
|
|
this.writeBackEntities.add(id) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -324,6 +327,7 @@ export default class EntityManager { |
|
|
|
this.relationIndex.set(relatedId, rev) |
|
|
|
} |
|
|
|
rev.add(relationType, id) |
|
|
|
this.writeBackEntities.add(id) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -360,16 +364,19 @@ export default class EntityManager { |
|
|
|
relations.center.forEach(relatedId => { |
|
|
|
const rev = this.relationIndex.get(relatedId) |
|
|
|
if (rev) rev.center.delete(id) |
|
|
|
this.writeBackEntities.add(relatedId) |
|
|
|
}) |
|
|
|
|
|
|
|
relations.input.forEach(relatedId => { |
|
|
|
const rev = this.relationIndex.get(relatedId) |
|
|
|
if (rev) rev.output.delete(id) |
|
|
|
this.writeBackEntities.add(relatedId) |
|
|
|
}) |
|
|
|
|
|
|
|
relations.output.forEach(relatedId => { |
|
|
|
const rev = this.relationIndex.get(relatedId) |
|
|
|
if (rev) rev.input.delete(id) |
|
|
|
this.writeBackEntities.add(relatedId) |
|
|
|
}) |
|
|
|
|
|
|
|
this.relationIndex.delete(id) |
|
|
|
@ -496,3 +503,34 @@ interface LineDiffItem { |
|
|
|
type: LinkType |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 关系详情 |
|
|
|
*/ |
|
|
|
export class Relation { |
|
|
|
center = new Set<string>() |
|
|
|
input = new Set<string>() |
|
|
|
output = new Set<string>() |
|
|
|
|
|
|
|
add(type: LinkType, id: string) { |
|
|
|
if (type === 'in') |
|
|
|
return this.input.add(id) |
|
|
|
else if (type === 'out') |
|
|
|
return this.output.add(id) |
|
|
|
else if (type === 'center') |
|
|
|
return this.center.add(id) |
|
|
|
else |
|
|
|
throw new Error(`Unknown link type: ${type}`) |
|
|
|
} |
|
|
|
|
|
|
|
delete(type: LinkType, id: string) { |
|
|
|
if (type === 'in') |
|
|
|
return this.input.delete(id) |
|
|
|
else if (type === 'out') |
|
|
|
return this.output.delete(id) |
|
|
|
else if (type === 'center') |
|
|
|
return this.center.delete(id) |
|
|
|
else |
|
|
|
throw new Error(`Unknown link type: ${type}`) |
|
|
|
} |
|
|
|
} |