Skip to content

Commit 15efe35

Browse files
committed
🐛 禁止外部框跳入自己内部框导致的无限循环嵌套情况
1 parent 64d5f08 commit 15efe35

File tree

2 files changed

+41
-10
lines changed

2 files changed

+41
-10
lines changed

app/src/core/service/controlService/controller/concrete/ControllerEntityLayerMoving.tsx

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ import { StageEntityMoveManager } from "../../../../stage/stageManager/concreteM
77
import { StageSectionInOutManager } from "../../../../stage/stageManager/concreteMethods/StageSectionInOutManager";
88
import { StageSectionPackManager } from "../../../../stage/stageManager/concreteMethods/StageSectionPackManager";
99
import { StageManager } from "../../../../stage/stageManager/StageManager";
10+
import { Section } from "../../../../stage/stageObject/entity/Section";
1011
import { TextNode } from "../../../../stage/stageObject/entity/TextNode";
1112
import { EntityJumpMoveEffect } from "../../../feedbackService/effectEngine/concrete/EntityJumpMoveEffect";
13+
import { EntityShakeEffect } from "../../../feedbackService/effectEngine/concrete/EntityShakeEffect";
1214
import { RectanglePushInEffect } from "../../../feedbackService/effectEngine/concrete/RectanglePushInEffect";
15+
import { TextRiseEffect } from "../../../feedbackService/effectEngine/concrete/TextRiseEffect";
1316
import { Controller } from "../Controller";
1417
import { ControllerClass } from "../ControllerClass";
1518

@@ -36,27 +39,55 @@ ControllerLayerMoving.mouseup = (event: MouseEvent) => {
3639
return;
3740
}
3841
const mouseLocation = Renderer.transformView2World(new Vector(event.clientX, event.clientY));
42+
3943
// 提前检查点击的位置是否有一个TextNode,如果有,则转换成Section
4044
const entity = StageManager.findEntityByLocation(mouseLocation);
4145
if (entity && entity instanceof TextNode) {
42-
const newSection = StageSectionPackManager.targetTextNodeToSection(entity);
46+
// 防止无限循环嵌套:当跳入的实体是选中的所有内容当中任意一个Section的内部时,禁止触发该操作
4347
const selectedEntities = StageManager.getSelectedEntities();
44-
// 获取所有选中实体的外接矩形的中心点,以便计算移动距离
45-
const centerLocation = Rectangle.getBoundingRectangle(
46-
selectedEntities.map((entity) => entity.collisionBox.getRectangle()),
47-
).center;
48-
// 最后让所有选中的实体移动
4948
for (const selectedEntity of selectedEntities) {
50-
const delta = mouseLocation.subtract(centerLocation);
51-
selectedEntity.move(delta);
49+
if (selectedEntity instanceof Section && SectionMethods.isEntityInSection(entity, selectedEntity)) {
50+
Stage.effectMachine.addEffect(EntityShakeEffect.fromEntity(entity));
51+
Stage.effectMachine.addEffect(EntityShakeEffect.fromEntity(selectedEntity));
52+
Stage.effectMachine.addEffect(TextRiseEffect.default("禁止将框套入自身内部"));
53+
return;
54+
}
55+
}
56+
57+
const newSection = StageSectionPackManager.targetTextNodeToSection(entity);
58+
if (newSection && selectedEntities.length > 0) {
59+
// 获取所有选中实体的外接矩形的中心点,以便计算移动距离
60+
const centerLocation = Rectangle.getBoundingRectangle(
61+
selectedEntities.map((entity) => entity.collisionBox.getRectangle()),
62+
).center;
63+
// 最后让所有选中的实体移动
64+
for (const selectedEntity of selectedEntities) {
65+
const delta = mouseLocation.subtract(centerLocation);
66+
selectedEntity.move(delta);
67+
}
68+
StageSectionInOutManager.goInSections(StageManager.getSelectedEntities(), [newSection]);
5269
}
53-
StageSectionInOutManager.goInSections(StageManager.getSelectedEntities(), [newSection]);
70+
5471
return; // 这个return必须写
5572
}
5673

5774
// 即将跳入的sections区域
5875
const targetSections = SectionMethods.getSectionsByInnerLocation(mouseLocation);
5976
const selectedEntities = StageManager.getSelectedEntities();
77+
78+
// 防止无限循环嵌套:当跳入的实体是选中的所有内容当中任意一个Section的内部时,禁止触发该操作
79+
for (const selectedEntity of selectedEntities) {
80+
if (selectedEntity instanceof Section) {
81+
for (const targetSection of targetSections) {
82+
if (SectionMethods.isEntityInSection(targetSection, selectedEntity)) {
83+
Stage.effectMachine.addEffect(EntityShakeEffect.fromEntity(targetSection));
84+
Stage.effectMachine.addEffect(TextRiseEffect.default("禁止将框套入自身内部"));
85+
return;
86+
}
87+
}
88+
}
89+
}
90+
6091
// 移动位置
6192

6293
// 1 计算所有节点应该移动的 delta

app/src/core/stage/stageManager/concreteMethods/StageSectionPackManager.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ export namespace StageSectionPackManager {
118118
}
119119

120120
/**
121-
* 将指定的文本节点转换成Section
121+
* 将指定的文本节点转换成Section,自动删除原来的TextNode
122122
* @param textNode 要转换的节点
123123
* @param ignoreEdges 是否忽略边的影响
124124
*/

0 commit comments

Comments
 (0)