|
|
@ -2,7 +2,7 @@ import * as THREE from 'three' |
|
|
import type Viewport from '@/core/engine/Viewport' |
|
|
import type Viewport from '@/core/engine/Viewport' |
|
|
import type BaseRenderer from '@/core/base/BaseRenderer' |
|
|
import type BaseRenderer from '@/core/base/BaseRenderer' |
|
|
import { getRenderer } from './ModuleManager' |
|
|
import { getRenderer } from './ModuleManager' |
|
|
import { getLineId } from '@/core/ModelUtils' |
|
|
import { getLineId, parseLineId } from '@/core/ModelUtils' |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 实体管理器 |
|
|
* 实体管理器 |
|
|
@ -21,20 +21,21 @@ export default class EntityManager { |
|
|
// 关系索引
|
|
|
// 关系索引
|
|
|
readonly relationIndex = new Map<string, Relation>() |
|
|
readonly relationIndex = new Map<string, Relation>() |
|
|
|
|
|
|
|
|
// 所有 THREEJS "点"对象
|
|
|
// 所有 THREEJS "点"对象, 检索值是"点实体"的 id, 值是 THREE.Object3D 数组
|
|
|
readonly objects = new Map<string, THREE.Object3D[]>() |
|
|
readonly objects = new Map<string, THREE.Object3D[]>() |
|
|
|
|
|
|
|
|
// 所有 THREEJS "线"对象
|
|
|
// 所有 THREEJS "线"对象, 检索值是"线实体"的 id, 取值方式是 {type}${startId}${endId}, 值是 THREE.Object3D 数组
|
|
|
readonly lines = new Map<string, THREE.Object3D[]>() |
|
|
readonly lines = new Map<string, THREE.Object3D[]>() |
|
|
|
|
|
|
|
|
// 差量渲染器
|
|
|
// 差量渲染器
|
|
|
readonly diffRenderer = new Map<string, BaseRenderer>() |
|
|
readonly diffRenderer = new Map<string, BaseRenderer>() |
|
|
// 线差量记录
|
|
|
// 线差量记录
|
|
|
lineDiffs = { |
|
|
readonly lineDiffs = { |
|
|
create: new Map<string, LineDiffItem>(), |
|
|
create: new Map<string, LineDiffItem>(), |
|
|
update: new Map<string, LineDiffItem>(), |
|
|
update: new Map<string, LineDiffItem>(), |
|
|
delete: new Map<string, LineDiffItem>() |
|
|
delete: new Map<string, LineDiffItem>() |
|
|
} |
|
|
} |
|
|
|
|
|
isUpdating = false |
|
|
|
|
|
|
|
|
init(viewport: Viewport) { |
|
|
init(viewport: Viewport) { |
|
|
this.viewport = viewport |
|
|
this.viewport = viewport |
|
|
@ -44,6 +45,7 @@ export default class EntityManager { |
|
|
* 批量更新开始 |
|
|
* 批量更新开始 |
|
|
*/ |
|
|
*/ |
|
|
beginUpdate(): void { |
|
|
beginUpdate(): void { |
|
|
|
|
|
this.isUpdating = true |
|
|
this.viewport.beginUpdate() |
|
|
this.viewport.beginUpdate() |
|
|
this.diffRenderer.clear() |
|
|
this.diffRenderer.clear() |
|
|
this.lineDiffs.create.clear() |
|
|
this.lineDiffs.create.clear() |
|
|
@ -134,6 +136,7 @@ export default class EntityManager { |
|
|
renderer.endUpdate() |
|
|
renderer.endUpdate() |
|
|
} |
|
|
} |
|
|
this.viewport.endUpdate() |
|
|
this.viewport.endUpdate() |
|
|
|
|
|
this.isUpdating = false |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
@ -210,6 +213,71 @@ export default class EntityManager { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
|
|
|
* 重命名一个点 |
|
|
|
|
|
* 注意, 不能在更新时刻改名. 所有的关系节点都应该改名 |
|
|
|
|
|
*/ |
|
|
|
|
|
renamePoint(newId: string, originId: string) { |
|
|
|
|
|
if (this.isUpdating) { |
|
|
|
|
|
throw new Error('Cannot rename point during update') |
|
|
|
|
|
} |
|
|
|
|
|
const entity = this.entities.get(originId) |
|
|
|
|
|
if (!entity) { |
|
|
|
|
|
throw new Error(`Entity with id ${originId} does not exist`) |
|
|
|
|
|
} |
|
|
|
|
|
if (this.entities.has(newId)) { |
|
|
|
|
|
throw new Error(`Entity with id ${newId} already exists`) |
|
|
|
|
|
} |
|
|
|
|
|
entity.id = newId |
|
|
|
|
|
this.entities.set(newId, entity) |
|
|
|
|
|
this.entities.delete(originId) |
|
|
|
|
|
this.objects.set(newId, this.objects.get(originId) || []) |
|
|
|
|
|
this.objects.delete(originId) |
|
|
|
|
|
|
|
|
|
|
|
// 更新关系索引
|
|
|
|
|
|
const relations = this.relationIndex.get(originId) |
|
|
|
|
|
if (relations) { |
|
|
|
|
|
this.relationIndex.delete(originId) |
|
|
|
|
|
|
|
|
|
|
|
// 更新所有关系中的 id
|
|
|
|
|
|
relations.center.forEach((relatedId) => { |
|
|
|
|
|
const rev = this.relationIndex.get(relatedId) |
|
|
|
|
|
if (rev && rev.delete('center', originId)) { |
|
|
|
|
|
rev.add('center', newId) |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
relations.input.forEach((relatedId) => { |
|
|
|
|
|
const rev = this.relationIndex.get(relatedId) |
|
|
|
|
|
if (rev && rev.delete('out', originId)) { |
|
|
|
|
|
rev.add('out', newId) |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
relations.output.forEach((relatedId) => { |
|
|
|
|
|
const rev = this.relationIndex.get(relatedId) |
|
|
|
|
|
if (rev && rev.delete('in', originId)) { |
|
|
|
|
|
rev.add('in', newId) |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
this.relationIndex.set(newId, relations) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 更新所有线段数据
|
|
|
|
|
|
for (const [lineId, lineObjects] of this.lines.entries()) { |
|
|
|
|
|
const [type, startId, endId] = parseLineId(lineId) |
|
|
|
|
|
if (startId === originId) { |
|
|
|
|
|
const newLineId = getLineId(newId, endId, type) |
|
|
|
|
|
this.lines.set(newLineId, lineObjects) |
|
|
|
|
|
this.lines.delete(lineId) |
|
|
|
|
|
|
|
|
|
|
|
} else if (endId === originId) { |
|
|
|
|
|
const newLineId = getLineId(startId, newId, type) |
|
|
|
|
|
this.lines.set(newLineId, lineObjects) |
|
|
|
|
|
this.lines.delete(lineId) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
* 删除关系关系网, 计算出差值, 可以临时放在 diffRenderer 中, 等待 commitUpdate 时统一处理 |
|
|
* 删除关系关系网, 计算出差值, 可以临时放在 diffRenderer 中, 等待 commitUpdate 时统一处理 |
|
|
*/ |
|
|
*/ |
|
|
private removeRelations(id: string): void { |
|
|
private removeRelations(id: string): void { |
|
|
@ -291,22 +359,22 @@ export class Relation { |
|
|
|
|
|
|
|
|
add(type: LinkType, id: string) { |
|
|
add(type: LinkType, id: string) { |
|
|
if (type === 'in') |
|
|
if (type === 'in') |
|
|
this.input.add(id) |
|
|
return this.input.add(id) |
|
|
else if (type === 'out') |
|
|
else if (type === 'out') |
|
|
this.output.add(id) |
|
|
return this.output.add(id) |
|
|
else if (type === 'center') |
|
|
else if (type === 'center') |
|
|
this.center.add(id) |
|
|
return this.center.add(id) |
|
|
else |
|
|
else |
|
|
throw new Error(`Unknown link type: ${type}`) |
|
|
throw new Error(`Unknown link type: ${type}`) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
delete(type: LinkType, id: string) { |
|
|
delete(type: LinkType, id: string) { |
|
|
if (type === 'in') |
|
|
if (type === 'in') |
|
|
this.input.delete(id) |
|
|
return this.input.delete(id) |
|
|
else if (type === 'out') |
|
|
else if (type === 'out') |
|
|
this.output.delete(id) |
|
|
return this.output.delete(id) |
|
|
else if (type === 'center') |
|
|
else if (type === 'center') |
|
|
this.center.delete(id) |
|
|
return this.center.delete(id) |
|
|
else |
|
|
else |
|
|
throw new Error(`Unknown link type: ${type}`) |
|
|
throw new Error(`Unknown link type: ${type}`) |
|
|
} |
|
|
} |
|
|
|