diff --git a/dev.md b/dev.md index 44c3686..86aa9bf 100644 --- a/dev.md +++ b/dev.md @@ -73,7 +73,7 @@ - 公共方法、接口必须在**源头处**(多数情况下为 `interface`)添加 `jsDoc` 注释;其他常用成员、方法、类型也必须添加注释(含义极为明确或极少使用的可例外,但建议全部添加)。接口中每个方法之间必须添加空行,成员之间应根据成员功能添加换行。 - 继承或 `implements` 而来的 API(方法、成员等),若注释说明无需变更,则**不应重复添加** `jsDoc` 注释。 - 不对构造器添加注释。若构造器使用了属性声明语法(`constructor(public prop: T)`)且成员需要说明,可仅对该成员添加参数注释,不写构造器描述。**在这种情况下**建议避免在构造器中使用属性声明语法,将成员单独声明并在构造器中赋值。此条建议**并非**要求不使用构造器的属性声明语法,而是仅在这一情况下不建议使用,常规情况下推荐使用此语法来缩短代码长度并提高可读性。 -- 长文件可使用 `#region` / `#endregion` 分段以支持折叠。 +- 长文件可使用 `#region` / `#endregion` 分段以支持折叠,分区应以功能进行划分,即这个 region 负责某个功能,而不是按照修饰符等内容划分。 - TODO 使用 `// TODO:` 或 `// todo:` 格式。 - 单行注释的 `//` 与注释内容之间留一个空格;不允许出现非 jsDoc 的多行注释,如需多行注释,使用多个单行注释代替。 - 注释合理换行:考虑中文字符较宽,建议每 40–60 个字符在标点符号后换行,不要频繁换行,每行长度应差不多,不要过短也不要过长,不允许在句中换行;参数注释换行后保持对齐。 @@ -115,6 +115,8 @@ - 换行使用 `CRLF` 格式。 - 不得将一个对象上的函数声明为一个临时变量/常量,哪怕其没有 `this` 指向问题。 - 通常情况下,一个文件应只包含一个类,但如果一个类仅是另一个类的依赖,或一个类的长度远远小于另一个类等特殊情况时,允许将多个类放在同一个文件中。 +- 私有方法应该放到调用之的方法之前,同时保证其处在合理的 region 内。 +- 对象的非空判断用 `!obj`,字面量的非空判断用 `!isNil(value)`。 ## 双端分离 diff --git a/packages-user/data-system/src/path/finder.ts b/packages-user/data-system/src/path/finder.ts index 5dec29b..73fdf7a 100644 --- a/packages-user/data-system/src/path/finder.ts +++ b/packages-user/data-system/src/path/finder.ts @@ -55,14 +55,13 @@ export class PathfindingFinder implements IPathfinder { } /** - * 获取进入指定位置节点的损失,损失值非有限数或负数时 - * 告警并按默认损失 1 处理 + * 获取进入指定位置节点的损失,损失值为负数时抛出警告并按损失 1 处理 * @param block 位置信息 */ private getNodeCost(block: ILayerLocation): number { if (!this.cost) return 1; const value = this.cost(block); - if (!Number.isFinite(value) || value < 0) { + if (value < 0) { logger.warn(174); return 1; } @@ -70,8 +69,7 @@ export class PathfindingFinder implements IPathfinder { } /** - * 在有向图上执行最小损失搜索, - * 终端节点仅可作为路径终点,不可作为中间节点 + * 在有向图上执行最小损失搜索,终端节点仅可作为路径终点,不可作为中间节点 * @param graph 寻路有向图 * @param start 寻路起始位置 * @param target 寻路目标位置 diff --git a/packages-user/data-system/src/path/graph.ts b/packages-user/data-system/src/path/graph.ts index 03395d4..3623fb4 100644 --- a/packages-user/data-system/src/path/graph.ts +++ b/packages-user/data-system/src/path/graph.ts @@ -91,7 +91,7 @@ export class PathfindingGraphBuilder implements IPathfindingGraphBuilder { const width = layer.width; const height = layer.height; const floorId = this.resolveFloorId(); - const state: IDataCommon = layer.state; + const state = layer.state; const blocks: (ILayerLocation | null)[] = new Array( width * height ).fill(null); diff --git a/packages-user/data-system/src/path/system.ts b/packages-user/data-system/src/path/system.ts index 4162b30..a418fc7 100644 --- a/packages-user/data-system/src/path/system.ts +++ b/packages-user/data-system/src/path/system.ts @@ -34,10 +34,6 @@ export class PathfindingSystem implements IPathfindingSystem { this.policy = policy; } - /** - * 未绑定移动器时告警并返回空数组 - * @param target 目标坐标 - */ getPath(target: ITileLocator): IPathfindingStep[] { const mover = this.mover; if (isNil(mover)) { @@ -49,8 +45,7 @@ export class PathfindingSystem implements IPathfindingSystem { } /** - * 按指定移动方式启动寻路移动,返回控制器包装。 - * 已有移动进行中时返回 `null` + * 按指定移动方式启动寻路移动,返回控制器包装。已有移动进行中时返回 `null` * @param path 寻路步骤序列 * @param teleport 是否瞬移 */ @@ -64,7 +59,7 @@ export class PathfindingSystem implements IPathfindingSystem { if (current && !current.controller.done) return null; if (teleport) { - const last = path[path.length - 1]; + const last = path.at(-1)!; mover.tp(last.to.x, last.to.y); } else { for (const step of path) { @@ -72,7 +67,6 @@ export class PathfindingSystem implements IPathfindingSystem { } } - // 移动器移动中时启动失败,对应已有移动进行中的契约 const controller = mover.start(); if (!controller) return null; const result: IPathfindingController = { controller, path }; @@ -89,10 +83,11 @@ export class PathfindingSystem implements IPathfindingSystem { teleportTo(target: ITileLocator): IPathfindingController | null { const path = this.getPath(target); if (path.length === 0) return null; - if (isNil(this.policy) || this.policy(path)) { + if (!this.policy || this.policy(path)) { return this.startMove(path, false); + } else { + return this.startMove(path, true); } - return this.startMove(path, true); } async interrupt(): Promise { diff --git a/packages-user/data-system/src/path/types.ts b/packages-user/data-system/src/path/types.ts index e97d03f..8060930 100644 --- a/packages-user/data-system/src/path/types.ts +++ b/packages-user/data-system/src/path/types.ts @@ -13,6 +13,8 @@ import { IObjectMover } from '@user/data-common'; +//#region 寻路系统 + export interface IPathfindingStep { /** 移动方向 */ readonly dir: FaceDirection; @@ -105,14 +107,12 @@ export interface IPathfindingSystem extends IDataBaseExtended { /** * 逐步寻路至目标位置,触发途经事件 * @param target 目标坐标 - * @returns 移动控制器。无法寻路、无路径或已有移动进行中时返回 `null` */ moveTo(target: ITileLocator): IPathfindingController | null; /** * 瞬移至目标位置。瞬移前经回退策略判定,判定需要回退则自动退为逐步寻路 * @param target 目标坐标 - * @returns 移动控制器;无法寻路、无路径或已有移动进行中时返回 `null` */ teleportTo(target: ITileLocator): IPathfindingController | null; @@ -122,6 +122,10 @@ export interface IPathfindingSystem extends IDataBaseExtended { interrupt(): Promise; } +//#endregion + +//#region 路径图 + export interface IPathGraphEdge { /** 本条边对应的移动方向 */ readonly dir: FaceDirection; @@ -156,19 +160,19 @@ export interface IPathGraph { export interface IPathfindingGraphBuilder { /** * 绑定地图状态对象,用于解析图层所属楼层 id - * @param maps 地图状态对象,传入 `null` 解绑 + * @param maps 地图状态对象 */ useMapState(maps: IMapState | null): void; /** * 绑定构建有向图所用的地图图层 - * @param layer 地图图层对象,传入 `null` 解绑 + * @param layer 地图图层对象 */ useMapLayer(layer: IMapLayer | null): void; /** * 注入判定边可行性的通行性谓词 - * @param predicate 通行性谓词,传入 `null` 解绑 + * @param predicate 通行性谓词 */ usePassPredicate(predicate: IPassPredicate | null): void; @@ -179,9 +183,9 @@ export interface IPathfindingGraphBuilder { useDirGroup(group: number): void; /** - * 构建有向图。图层未绑定时告警并返回空图, - * 不包含任何节点与边 - * @returns 构建的有向图 + * 构建有向图。图层未绑定时告警并返回空图,不包含任何节点与边 */ build(): IPathGraph; } + +//#endregion diff --git a/packages/common/src/logger.json b/packages/common/src/logger.json index 2719398..56f051d 100644 --- a/packages/common/src/logger.json +++ b/packages/common/src/logger.json @@ -239,6 +239,6 @@ "171": "Event id '$1' not found in event store, event will be skipped.", "172": "Event returned non-boolean value '$1' during reduction. JavaScript short-circuit semantics will be used.", "173": "Pathfinding input is invalid or a required binding (map state, map layer) is missing. An empty result will be returned.", - "174": "Pathfinding cost function returned a non-finite or negative value. Default cost 1 will be used instead." + "174": "Pathfinding cost function returned a negative value. Default cost 1 will be used instead." } }