Skip to content

Commit

Permalink
Merge pull request #124 from LiRenTech/refactor/stage-object
Browse files Browse the repository at this point in the history
Refactor/stage object
  • Loading branch information
Littlefean authored Oct 23, 2024
2 parents 63b6276 + 5816640 commit 0e8a0fe
Show file tree
Hide file tree
Showing 20 changed files with 251 additions and 177 deletions.
24 changes: 14 additions & 10 deletions src/core/controller/concrete/ControllerCutting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Controller } from "../Controller";
import { ControllerClass } from "../ControllerClass";
import { Line } from "../../dataStruct/shape/Line";
import { EdgeRenderer } from "../../render/canvas2d/entityRenderer/edge/EdgeRenderer";
import { Section } from "../../stageObject/entity/Section";

/**
* 关于斩断线的控制器
Expand Down Expand Up @@ -52,13 +53,16 @@ ControllerCutting.mousemove = (event: MouseEvent) => {
ControllerCutting.lastMoveLocation,
);

Stage.warningNodes = [];
for (const node of StageManager.getTextNodes()) {
const collidePoints = node.rectangle.getCollidePointsWithLine(
Stage.cuttingLine,
);
Stage.warningEntity = [];
for (const entity of StageManager.getEntities()) {
if (entity instanceof Section) {
continue; // Section的碰撞箱比较特殊
}
const collidePoints = entity.collisionBox
.getRectangle()
.getCollidePointsWithLine(Stage.cuttingLine);
if (collidePoints.length > 0) {
Stage.warningNodes.push(node);
Stage.warningEntity.push(entity);
for (const collidePoint of collidePoints) {
Stage.effects.push(
new CircleFlameEffect(
Expand Down Expand Up @@ -104,8 +108,8 @@ ControllerCutting.mouseup = (event: MouseEvent) => {
}
Stage.isCutting = false;

StageManager.deleteEntities(Stage.warningNodes);
Stage.warningNodes = [];
StageManager.deleteEntities(Stage.warningEntity);
Stage.warningEntity = [];

for (const edge of Stage.warningEdges) {
StageManager.deleteEdge(edge);
Expand All @@ -116,9 +120,9 @@ ControllerCutting.mouseup = (event: MouseEvent) => {
for (const section of Stage.warningSections) {
StageManager.deleteSection(section);
}

Stage.warningSections = [];

StageManager.updateReferences();

Stage.warningEdges = [];
Expand Down
55 changes: 33 additions & 22 deletions src/core/controller/concrete/ControllerNodeConnection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ControllerClass } from "../ControllerClass";
import { Controller } from "../Controller";
import { RectangleNoteEffect } from "../../effect/concrete/RectangleNoteEffect";
import { EdgeRenderer } from "../../render/canvas2d/entityRenderer/edge/EdgeRenderer";
import { ConnectableEntity } from "../../stageObject/StageObject";

/**
* 右键连线功能 的控制器
Expand All @@ -29,38 +30,46 @@ ControllerNodeConnection.mousedown = (event: MouseEvent) => {
new Vector(event.clientX, event.clientY),
);
const clickedNode = StageManager.findTextNodeByLocation(pressWorldLocation);

const clickedSection = StageManager.findSectionByLocation(pressWorldLocation);
let clickedConnectableEntity: ConnectableEntity | null = null;

if (clickedNode) {
clickedConnectableEntity = clickedNode;
}
if (clickedSection) {
clickedConnectableEntity = clickedSection;
}

if (clickedConnectableEntity) {
// 右键点击了某个节点
// Stage.isCutting = false;
Stage.connectFromNodes = [];
for (const node of StageManager.getTextNodes()) {
Stage.connectFromEntities = [];
for (const node of StageManager.getConnectableEntity()) {
if (node.isSelected) {
Stage.connectFromNodes.push(node);
Stage.connectFromEntities.push(node);
}
}
if (Stage.connectFromNodes.includes(clickedNode)) {
if (Stage.connectFromEntities.includes(clickedConnectableEntity)) {
// 多重连接
for (const node of StageManager.getTextNodes()) {
for (const node of StageManager.getConnectableEntity()) {
if (node.isSelected) {
// 特效
Stage.effects.push(
new RectangleNoteEffect(
new ProgressNumber(0, 15),
node.rectangle.clone(),
node.collisionBox.getRectangle().clone(),
new Color(0, 255, 0, 1),
),
);
}
}
} else {
// 不触发多重连接
Stage.connectFromNodes = [clickedNode];
Stage.connectFromEntities = [clickedConnectableEntity];
// 特效
Stage.effects.push(
new RectangleNoteEffect(
new ProgressNumber(0, 15),
clickedNode.rectangle.clone(),
clickedConnectableEntity.collisionBox.getRectangle().clone(),
new Color(0, 255, 0, 1),
),
);
Expand All @@ -81,9 +90,9 @@ ControllerNodeConnection.mousemove = (event: MouseEvent) => {
);
// 连接线
let isFindConnectToNode = false;
for (const node of StageManager.getTextNodes()) {
if (node.collisionBox.isPointInCollisionBox(worldLocation)) {
if (Stage.connectToNode === null) {
for (const entity of StageManager.getConnectableEntity()) {
if (entity.collisionBox.isPointInCollisionBox(worldLocation)) {
if (Stage.connectToEntity === null) {
// 特效
// Stage.effects.push(
// new RectangleNoteEffect(
Expand All @@ -93,14 +102,14 @@ ControllerNodeConnection.mousemove = (event: MouseEvent) => {
// ),
// );
}
Stage.connectToNode = node;
Stage.connectToEntity = entity;
isFindConnectToNode = true;

break;
}
}
if (!isFindConnectToNode) {
Stage.connectToNode = null;
Stage.connectToEntity = null;
}
// 由于连接线要被渲染器绘制,所以需要更新总控制里的lastMoveLocation
Controller.lastMoveLocation = worldLocation.clone();
Expand All @@ -111,30 +120,32 @@ ControllerNodeConnection.mouseup = (event: MouseEvent) => {
return;
}
// 结束连线
if (Stage.connectFromNodes.length > 0 && Stage.connectToNode !== null) {
if (Stage.connectFromEntities.length > 0 && Stage.connectToEntity !== null) {
let isHaveConnectResult = false; // 在多重链接的情况下,是否有连接成功
for (const node of Stage.connectFromNodes) {
const connectResult = StageManager.connectNode(node, Stage.connectToNode);
for (const entity of Stage.connectFromEntities) {
const connectResult = StageManager.connectNode(entity, Stage.connectToEntity);
if (connectResult) {
// 连接成功,特效
isHaveConnectResult = true;
for (const effect of EdgeRenderer.getConnectedEffects(node, Stage.connectToNode)) {
for (const effect of EdgeRenderer.getConnectedEffects(entity, Stage.connectToEntity)) {
Stage.effects.push(effect);
}
} else {
console.warn("连接失败!", entity, Stage.connectToEntity);
}
}
if (isHaveConnectResult) {
// 给连向的那个节点加特效
Stage.effects.push(
new CircleFlameEffect(
new ProgressNumber(0, 15),
Stage.connectToNode.rectangle.center,
Stage.connectToEntity.collisionBox.getRectangle().center,
80,
new Color(0, 255, 0, 1),
),
);
}
}
Stage.connectFromNodes = [];
Stage.connectToNode = null;
Stage.connectFromEntities = [];
Stage.connectToEntity = null;
};
11 changes: 2 additions & 9 deletions src/core/controller/concrete/ControllerRectangleSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,7 @@ ControllerRectangleSelect.mousemove = (event: MouseEvent) => {
if (
edge.collisionBox.isRectangleInCollisionBox(Stage.selectingRectangle)
) {
if (
Controller.lastSelectedEdge.has(
edge.target.uuid + "&" + edge.source.uuid,
)
) {
if (Controller.lastSelectedEdge.has(edge.uuid)) {
edge.isSelected = false;
} else {
edge.isSelected = true;
Expand Down Expand Up @@ -207,12 +203,9 @@ ControllerRectangleSelect.mouseup = (event: MouseEvent) => {
}
Controller.lastSelectedEdge = new Set();
for (const edge of StageManager.getEdges()) {
// TODO: 该改了,edge已经有uuid了

if (edge.isSelected) {
Controller.lastSelectedEdge.add(
edge.target.uuid + "&" + edge.source.uuid,
);
Controller.lastSelectedEdge.add(edge.uuid);
}
}
};
7 changes: 7 additions & 0 deletions src/core/render/canvas2d/entityRenderer/EntityRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ export namespace EntityRenderer {
new Color(0, 255, 0, 0.5),
);
}
// debug
RenderUtils.renderRect(
section.collisionBox.getRectangle().transformWorld2View(),
section.color,
new Color(0, 2, 255, 1),
0.5 * Camera.currentScale
)
}

export function renderNode(node: TextNode) {
Expand Down
10 changes: 5 additions & 5 deletions src/core/render/canvas2d/entityRenderer/edge/EdgeRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Color } from "../../../../dataStruct/Color";

import { Vector } from "../../../../dataStruct/Vector";
import { Edge } from "../../../../stageObject/association/Edge";
import { TextNode } from "../../../../stageObject/entity/TextNode";
import { Settings } from "../../../../Settings";

import { Renderer } from "../../renderer";
Expand All @@ -11,6 +10,7 @@ import { StraightEdgeRenderer } from "./concrete/StraightEdgeRenderer";
import { SymmetryCurveEdgeRenderer } from "./concrete/SymmetryCurveEdgeRenderer";
import { VerticalPolyEdgeRenderer } from "./concrete/VerticalPolyEdgeRenderer";
import { CollisionBoxRenderer } from "../CollisionBoxRenderer";
import { ConnectableEntity } from "../../../../stageObject/StageObject";

/**
* 边的总渲染器单例
Expand Down Expand Up @@ -73,22 +73,22 @@ export namespace EdgeRenderer {
}

export function renderVirtualEdge(
startNode: TextNode,
startNode: ConnectableEntity,
mouseLocation: Vector,
) {
currentRenderer.renderVirtualEdge(startNode, mouseLocation);
}
export function renderVirtualConfirmedEdge(
startNode: TextNode,
endNode: TextNode,
startNode: ConnectableEntity,
endNode: ConnectableEntity,
) {
currentRenderer.renderVirtualConfirmedEdge(startNode, endNode);
}

export function getCuttingEffects(edge: Edge) {
return currentRenderer.getCuttingEffects(edge);
}
export function getConnectedEffects(startNode: TextNode, toNode: TextNode) {
export function getConnectedEffects(startNode: ConnectableEntity, toNode: ConnectableEntity) {
return currentRenderer.getConnectedEffects(startNode, toNode);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Vector } from "../../../../dataStruct/Vector";
import { Edge } from "../../../../stageObject/association/Edge";
import { Effect } from "../../../../effect/effect";
import { TextNode } from "../../../../stageObject/entity/TextNode";
import { ConnectableEntity } from "../../../../stageObject/StageObject";

/**
* 不同类型的边的渲染器 基类
Expand Down Expand Up @@ -49,14 +49,14 @@ export abstract class EdgeRendererClass {
* @param startNode
* @param mouseLocation 世界坐标系
*/
public abstract renderVirtualEdge(startNode: TextNode, mouseLocation: Vector): void;
public abstract renderVirtualEdge(startNode: ConnectableEntity, mouseLocation: Vector): void;

/**
* 绘制鼠标连线移动到目标节点上吸附住 时候虚拟连线效果
* @param startNode
* @param endNode
*/
public abstract renderVirtualConfirmedEdge(startNode: TextNode, endNode: TextNode): void;
public abstract renderVirtualConfirmedEdge(startNode: ConnectableEntity, endNode: ConnectableEntity): void;
/**
* 获取这个线在切断时的特效
* 外层将在切断时根据此函数来获取特效并自动加入到渲染器中
Expand All @@ -66,5 +66,5 @@ export abstract class EdgeRendererClass {
/**
* 获取这个线在连接成功时的特效
*/
abstract getConnectedEffects(startNode: TextNode, toNode: TextNode): Effect[];
abstract getConnectedEffects(startNode: ConnectableEntity, toNode: ConnectableEntity): Effect[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import { Edge } from "../../../../../stageObject/association/Edge";
import { CircleFlameEffect } from "../../../../../effect/concrete/CircleFlameEffect";
import { LineCuttingEffect } from "../../../../../effect/concrete/LineCuttingEffect";
import { Effect } from "../../../../../effect/effect";
import { TextNode } from "../../../../../stageObject/entity/TextNode";
import { Camera } from "../../../../../stage/Camera";
import { Renderer } from "../../../renderer";
import { RenderUtils } from "../../../RenderUtils";
import { EdgeRenderer } from "../EdgeRenderer";
import { EdgeRendererClass } from "../EdgeRendererClass";
import { ConnectableEntity } from "../../../../../stageObject/StageObject";

/**
* 直线渲染器
Expand Down Expand Up @@ -45,18 +45,18 @@ export class StraightEdgeRenderer extends EdgeRendererClass {
];
}

getConnectedEffects(startNode: TextNode, toNode: TextNode): Effect[] {
getConnectedEffects(startNode: ConnectableEntity, toNode: ConnectableEntity): Effect[] {
return [
new CircleFlameEffect(
new ProgressNumber(0, 15),
startNode.rectangle.center,
startNode.collisionBox.getRectangle().center,
80,
new Color(83, 175, 29, 1),
),
new LineCuttingEffect(
new ProgressNumber(0, 30),
startNode.rectangle.center,
toNode.rectangle.center,
startNode.collisionBox.getRectangle().center,
toNode.collisionBox.getRectangle().center,
new Color(78, 201, 176, 1),
new Color(83, 175, 29, 1),
20,
Expand Down Expand Up @@ -106,9 +106,9 @@ export class StraightEdgeRenderer extends EdgeRendererClass {
// 画箭头
{
const size = 15;
const direction = edge.target.rectangle
const direction = edge.target.collisionBox.getRectangle()
.getCenter()
.subtract(edge.source.rectangle.getCenter())
.subtract(edge.source.collisionBox.getRectangle().getCenter())
.normalize();
const endPoint = edge.bodyLine.end.clone();
EdgeRenderer.renderArrowHead(endPoint, direction, size);
Expand All @@ -118,8 +118,8 @@ export class StraightEdgeRenderer extends EdgeRendererClass {
public renderCycleState(edge: Edge): void {
// 自环
RenderUtils.renderArc(
Renderer.transformWorld2View(edge.target.rectangle.location),
(edge.target.rectangle.size.y / 2) * Camera.currentScale,
Renderer.transformWorld2View(edge.target.collisionBox.getRectangle().location),
(edge.target.collisionBox.getRectangle().size.y / 2) * Camera.currentScale,
Math.PI / 2,
0,
new Color(204, 204, 204),
Expand All @@ -129,25 +129,25 @@ export class StraightEdgeRenderer extends EdgeRendererClass {
{
const size = 15;
const direction = new Vector(1, 0).rotateDegrees(15);
const endPoint = edge.target.rectangle.leftCenter;
const endPoint = edge.target.collisionBox.getRectangle().leftCenter;
EdgeRenderer.renderArrowHead(endPoint, direction, size);
}
}

public renderVirtualEdge(startNode: TextNode, mouseLocation: Vector): void {
public renderVirtualEdge(startNode: ConnectableEntity, mouseLocation: Vector): void {
RenderUtils.renderGradientLine(
Renderer.transformWorld2View(startNode.rectangle.getCenter()),
Renderer.transformWorld2View(startNode.collisionBox.getRectangle().getCenter()),
Renderer.transformWorld2View(mouseLocation),
new Color(255, 255, 255, 0),
new Color(255, 255, 255, 0.5),
2,
);
}

public renderVirtualConfirmedEdge(startNode: TextNode, endNode: TextNode): void {
public renderVirtualConfirmedEdge(startNode: ConnectableEntity, endNode: ConnectableEntity): void {
RenderUtils.renderGradientLine(
Renderer.transformWorld2View(startNode.rectangle.getCenter()),
Renderer.transformWorld2View(endNode.rectangle.getCenter()),
Renderer.transformWorld2View(startNode.collisionBox.getRectangle().getCenter()),
Renderer.transformWorld2View(endNode.collisionBox.getRectangle().getCenter()),
new Color(0, 255, 0, 0),
new Color(0, 255, 0, 0.5),
2,
Expand Down
Loading

0 comments on commit 0e8a0fe

Please sign in to comment.