Browse Source

stateManager 测试用例1,2,3 通过

master
修宁 7 months ago
parent
commit
fe486d15b4
  1. 190
      src/core/manager/EntityManager.ts
  2. 16
      src/core/manager/StateManager.ts

190
src/core/manager/EntityManager.ts

@ -4,6 +4,34 @@ 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}`)
}
}
/**
*
* (ItemJson), THREE.Object3D
@ -112,11 +140,28 @@ export default class EntityManager {
option.originEntity = _.cloneDeep(entity)
this.entities.delete(id)
this.removeRelations(id)
// 先生成线差量,再清理关系
this.generateLineDiffsForDelete(id)
this.removeRelations(id) // 清理关系
this.entities.delete(id) // 删除实体
this.getDiffRenderer(entity.t).deletePoint(id, option)
}
generateLineDiffsForDelete(id: string): void {
const relations = this.relationIndex.get(id)
if (!relations) return
const removeLine = (relatedId: string, type: LinkType) => {
const lineId = getLineId(id, relatedId, type)
this.lineDiffs.delete.set(lineId, { startId: id, endId: relatedId, type })
}
relations.center.forEach(relatedId => removeLine(relatedId, 'center'))
relations.input.forEach(relatedId => removeLine(relatedId, 'in'))
relations.output.forEach(relatedId => removeLine(relatedId, 'out'))
}
/**
* ,
* 线
@ -127,9 +172,17 @@ export default class EntityManager {
*/
endEntityUpdate(): void {
for (const [itemTypeName, renderer] of this.diffRenderer.entries()) {
// "线"创建
for (const [lineId, lineDiffItem] of this.lineDiffs.create.entries()) {
const start = this.entities.get(lineDiffItem.startId)
const end = this.entities.get(lineDiffItem.endId)
// 添加存在性检查
if (!start || !end) {
console.warn(`无法创建线 ${lineId}, 起点或终点不存在`)
continue
}
if (start.t !== itemTypeName) {
// 只通知起点对应的渲染器
continue
@ -137,9 +190,17 @@ export default class EntityManager {
renderer.createLine(start, end, lineDiffItem.type)
}
// "线"更新
for (const [lineId, lineDiffItem] of this.lineDiffs.update.entries()) {
const start = this.entities.get(lineDiffItem.startId)
const end = this.entities.get(lineDiffItem.endId)
// 添加存在性检查
if (!start || !end) {
console.warn(`无法更新线 ${lineId}, 起点或终点不存在`)
continue
}
if (start.t !== itemTypeName) {
// 只通知起点对应的渲染器
continue
@ -147,13 +208,26 @@ export default class EntityManager {
renderer.updateLine(start, end, lineDiffItem.type)
}
// "线"删除
for (const [lineId, lineDiffItem] of this.lineDiffs.delete.entries()) {
const start = this.entities.get(lineDiffItem.startId)
const end = this.entities.get(lineDiffItem.endId)
if (!start || !end) {
// 即使实体不存在也要处理删除
renderer.deleteLine(
start || { id: lineDiffItem.startId, t: 'unknown' } as ItemJson,
end || { id: lineDiffItem.endId, t: 'unknown' } as ItemJson,
lineDiffItem.type)
continue
}
if (start.t !== itemTypeName) {
// 只通知起点对应的渲染器
continue
}
// 使用安全删除方法, 即使实体不存在也要处理删除
renderer.deleteLine(start, end, lineDiffItem.type)
}
@ -197,6 +271,11 @@ export default class EntityManager {
}
private updateReverseRelations(id: string, oldIds: Set<string>, newIds: Set<string>, relationType: LinkType) {
// 确保关系索引存在
if (!this.relationIndex.has(id)) {
this.relationIndex.set(id, new Relation())
}
// 移除旧关系
for (const relatedId of oldIds) {
if (!newIds.has(relatedId)) {
@ -219,6 +298,9 @@ export default class EntityManager {
}
private calculateLineDiffs(id: string, oldIds: Set<string>, newIds: Set<string>, lineType: LinkType) {
// 确保关系索引存在
if (!this.relationIndex.has(id)) return
// 删除被移除的线
for (const relatedId of oldIds) {
if (!newIds.has(relatedId)) {
@ -236,6 +318,43 @@ export default class EntityManager {
}
}
/**
* , , diffRenderer , commitUpdate
*/
private removeRelations(id: string): void {
const relations = this.relationIndex.get(id)
if (!relations) return
relations.center.forEach(relatedId => {
const rev = this.relationIndex.get(relatedId)
if (rev) rev.center.delete(id)
})
relations.input.forEach(relatedId => {
const rev = this.relationIndex.get(relatedId)
if (rev) rev.output.delete(id)
})
relations.output.forEach(relatedId => {
const rev = this.relationIndex.get(relatedId)
if (rev) rev.input.delete(id)
})
this.relationIndex.delete(id)
}
private getDiffRenderer(type: string) {
let renderer = this.diffRenderer.get(type)
if (typeof renderer === 'undefined') {
renderer = getRenderer(type)
renderer.beginRendererUpdate(this.viewport)
this.diffRenderer.set(type, renderer)
}
return renderer
}
/**
*
* , .
@ -301,46 +420,6 @@ export default class EntityManager {
}
}
/**
* , , diffRenderer , commitUpdate
*/
private removeRelations(id: string): void {
const relations = this.relationIndex.get(id)
if (!relations) return
const removeLine = (relatedId: string, type: LinkType) => {
const lineId = getLineId(id, relatedId, type)
this.lineDiffs.delete.set(lineId, { startId: id, endId: relatedId, type })
}
relations.center.forEach((relatedId) => {
this.relationIndex.get(relatedId)?.center.delete(id)
removeLine(relatedId, 'center')
})
relations.input.forEach((relatedId) => {
this.relationIndex.get(relatedId)?.output.delete(id)
removeLine(relatedId, 'in')
})
relations.output.forEach((relatedId) => {
this.relationIndex.get(relatedId)?.input.delete(id)
removeLine(relatedId, 'out')
})
this.relationIndex.delete(id)
}
private getDiffRenderer(type: string) {
let renderer = this.diffRenderer.get(type)
if (typeof renderer === 'undefined') {
renderer = getRenderer(type)
renderer.beginRendererUpdate(this.viewport)
this.diffRenderer.set(type, renderer)
}
return renderer
}
deleteEntityOnly(id: string) {
return this.entities.delete(id)
}
@ -376,30 +455,3 @@ 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}`)
}
}

16
src/core/manager/StateManager.ts

@ -40,11 +40,7 @@ interface HistoryStep {
* stateManager.redo()
*
* // 用例2 添加
* stateManager.beginStateUpdate();
* stateManager.vdata.items[3].dt.center.push('p5');
* stateManager.vdata.items.push({ id: 'p5', t: 'measure', tf: [[-6.0, 0, 8], [0, 0, 0], [0.25, 0.1, 0.25]], dt: { center: ['p4'] } });
* stateManager.endStateUpdate();
*
* stateManager.beginStateUpdate();stateManager.vdata.items[3].dt.center.push('p5');stateManager.vdata.items.push({ id: 'p5', t: 'measure', tf: [[-6.0, 0, 8], [0, 0, 0], [0.25, 0.1, 0.25]], dt: { center: ['p4'] } });stateManager.endStateUpdate();
* stateManager.undo();
* stateManager.redo();
*
@ -233,11 +229,6 @@ export default class StateManager {
this.entityManager.beginEntityUpdate()
// 处理删除
for (const item of diff.removed) {
this.entityManager.deleteEntity(item.id)
}
for (const item of diff.added) {
this.entityManager.createOrUpdateEntity(item)
}
@ -246,6 +237,11 @@ export default class StateManager {
this.entityManager.createOrUpdateEntity(after)
}
// 最后处理删除
for (const item of diff.removed) {
this.entityManager.deleteEntity(item.id)
}
this.entityManager.endEntityUpdate()
}

Loading…
Cancel
Save