chore: 删除 IDirectionMapper,全换成 IFaceHandler

This commit is contained in:
unanmed 2026-09-18 08:26:57 +08:00
parent 943659e2d1
commit ae5a956492
18 changed files with 129 additions and 145 deletions

View File

@ -0,0 +1,45 @@
# Phase 7 — 接力说明(07-16 暂缓,等数据端改完再启动)
**更新:** 2026-09-17(晚)
**HEAD:** 见 `git log -1`(分支 `refactor/data`)
## 当前状态:**Phase 7 暂缓**
- `07-01..07-15` 全部已执行并提交。
- `07-16`(寻路重构后的测试对齐)**已完成规划,但暂缓(DEFERRED)** —— 用户仍在手工重构数据端,接口/形状还会继续变,测试会持续报错。
## 为什么暂缓(用户原话)
> 「数据端还有很多内容需要我手动修改,还会导致大量的测试文件报错。所以此计划暂缓,等待我把数据端全部修改完毕后再进行。」
## 恢复时的第一件事(重要)
1. **重新测量**:跑一次 `pnpm test:ci`,得到**最新**的失败清单。
2. **重新核对 / 重规划**:
- `07-VERIFICATION.md` 的 `### Post-Refactor Test Breakage`(2026-09-17 快照,**很可能已过期**)
- `07-16-PLAN.md`(很可能需要按新清单重规划,而不是直接执行)
3. 重规划走:`/gsd-plan-phase 7 --gaps`(必要时先更新缺口清单)。
4. 执行走:`/gsd-execute-phase 7 --gaps-only`(Task 0 的 Q1..Q4/R1..R3 需用户逐条裁决)。
5. 收尾走:`/gsd-verify-work 7` 重出验证。
## 已知的 07-16 规划要点(供重规划参考)
- 目标:把失败测试文件**对齐到已发布的接口**,**只改测试、不改生产代码**。
- 已查明的真实替代接口(规划时从源码读出,非猜测):
- 寻路:`useMapState` 已删除且无替代(宽度改由 `MapGraphBuilder.useMapLayer` → `indexer.setWidth(layer.width)`);`useDirGroup(number)` → `useFaceHandler(IFaceHandler<number>)`(`Dir4FaceHandler`/`Dir8FaceHandler`);builder `face` 默认改为 `null`,每个 `build()/find()` 需显式注入;`DefaultPassPredicateImpl(state.maps)` → `(state)`。
- 录像:`ReplaySystem.array`;`onRecordCommand(code, array.length - 1, …)` → 首步索引期望 `1`→`0`;测试本地 `ReplaySystemStub` 的 `route` 需改 `array`。
- 位置/楼层:`setFloor(map: IGameMap)` + 新增 `location.map`(`location.ts:24/49`);`IHeroChangeFloorInfo.target: IGameMap`;16 处残留 `setFloor(<string>)`。
- `CoreState.initMapState` 已全仓删除(仅 `coreEventLayer.test.ts` 引用)→ 需裁决「改指向 `MapState.fromRaw` 还是退役」。
- 07-16 初版 `files_modified`:17 个测试文件 + `data-state/test/fixtures/closed-loop.ts`(共 18 条,均已跟踪)。
## 仍待处理的遗留
1. **07-15 的 CR-01 见证仍红**:唯一原因是你 `a2a8e6e` 把 `ReplaySystem.route` 改名 `array` 时漏了 `hero/equipment.test.ts` 的本地 `ReplaySystemStub`。生产修复(`53f067a`)已提交并经反向验证正确。**07-16 恢复时会顺带修好**。
2. `07-VERIFICATION.md` 状态为 `gaps_found`(含已暂缓的测试缺口)→ Phase 7 最终必须 `/gsd-verify-work 7`。
3. `ROADMAP.md` 的 Phase 7 进度行为 `15/16 · 暂缓 (Deferred)`。
## 未提交的用户在途改动(**禁止纳入任何提交**)
- 执行 `git status --short` 查看;当前可能含 `packages-user/data-state/src/core.ts`、`packages/common/src/dirtyTracker.ts` 等。
- **提交时只 stage 计划声明的文件**,绝不 `git add -A` / `git commit -a` / `git stash`。
## 长期纪律(用户 2026-09-17)
- 并行改动导致的**类型错误**与**测试失败**,若不落在本计划声明的路径上:**不理会、不修、不登记**。
- 不得 amend 已推送提交。
- 任何方法/字段命名,执行前须经用户批准。
- 执行任何计划前,先向用户汇报计划内容并取得确认。

View File

@ -2,12 +2,12 @@ import {
Hookable,
HookController,
IHookController,
logger
logger,
IFaceHandler
} from '@motajs/common';
import {
FaceDirection,
IDataCommon,
IFaceHandler,
IFacedTileLocator,
SaveCompression
} from '@user/data-common';

View File

@ -1,8 +1,12 @@
import { Hookable, HookController, IHookController } from '@motajs/common';
import {
Hookable,
HookController,
IHookController,
IFaceHandler
} from '@motajs/common';
import {
FaceDirection,
IDataCommon,
IFaceHandler,
IFacedTileLocator
} from '@user/data-common';
import { HeroMover } from './mover';

View File

@ -1,7 +1,6 @@
import { ITileLocator, logger } from '@motajs/common';
import { ITileLocator, logger, IFaceHandler } from '@motajs/common';
import {
FaceDirection,
IFaceHandler,
IMoverController,
ObjectMoveStep,
ObjectMover,

View File

@ -20,11 +20,15 @@ import {
import {
FaceDirection,
IDataCommon,
IFaceHandler,
IFacedTileLocator,
SaveCompression
} from '@user/data-common';
import { Hookable, HookController, IHookController } from '@motajs/common';
import {
Hookable,
HookController,
IHookController,
IFaceHandler
} from '@motajs/common';
export class HeroState<THero>
extends Hookable<IHeroStateHooks>

View File

@ -1,8 +1,12 @@
import { IHookBase, IHookable, ITileLocator } from '@motajs/common';
import {
IHookBase,
IHookable,
ITileLocator,
IFaceHandler
} from '@motajs/common';
import {
FaceDirection,
IDataCommonExtended,
IFaceHandler,
IFacedTileLocator,
IItemRawData,
IObjectMovable,

View File

@ -1,3 +1,4 @@
import { IFaceDescriptor, IFaceHandler } from '@motajs/common';
import { FaceDirection } from './types';
//#region 接口与枚举
@ -9,60 +10,6 @@ export const enum FaceGroup {
Dir8
}
export interface IFaceDescriptor {
/** 横坐标增量 */
readonly x: number;
/** 纵坐标增量 */
readonly y: number;
}
export interface IFaceHandler<T extends number> {
/**
* 将任意朝向值降级为本组支持的方向。
* 对于无法合理降级的方向(包括 `Unknown`),返回 `FaceDirection.Unknown`
* @param dir 任意朝向值
*/
degrade(dir: number): T;
/**
* 获取指定方向的单步坐标偏移量,输入先经过 `degrade`
* @param dir 朝向
*/
movement(dir: number): IFaceDescriptor;
/**
* 获取指定方向走 `count` 步的坐标偏移量,等价于 `movement * count`。
* `count` 允许为负数,表示反向位移,输入先经过 `degrade`
* @param dir 朝向
* @param count 步数,允许为负
*/
move(dir: number, count: number): IFaceDescriptor;
/**
* 获取本组内的反方向,输入先经过 `degrade`,`Unknown` 返回 `Unknown`
* @param dir 朝向
*/
opposite(dir: number): T;
/**
* 在本组方向集合内顺时针(默认)或逆时针旋转一步,输入先经过 `degrade`,
* `Unknown` 返回 `Unknown`
* @param dir 朝向
* @param anticlockwise 是否逆时针,默认顺时针
*/
next(dir: number, anticlockwise?: boolean): T;
/**
* 迭代本组支持的所有朝向,包含 `Unknown`
*/
mapDirection(): Iterable<T>;
/**
* 迭代本组所有朝向及其对应的坐标描述器,包含 `Unknown`(对应 `{ x: 0, y: 0 }`)
*/
mapMovement(): Iterable<[T, IFaceDescriptor]>;
}
export interface IFaceManager {
/**
* 以数字 key 注册一个 handler

View File

@ -4,10 +4,10 @@ import {
IHookable,
IHookBase,
IHookController,
ITileLocator
ITileLocator,
IFaceHandler
} from '@motajs/common';
import { FaceDirection } from './types';
import { IFaceHandler } from './faceManager';
//#region 对象移动

View File

@ -1,4 +1,4 @@
import { DirectionMapper, IDirectionMapper, logger } from '@motajs/common';
import { logger } from '@motajs/common';
import { ILoadProgressTotal, LoadProgressTotal } from '@motajs/loader';
import {
IRoleFaceBinder,
@ -79,7 +79,6 @@ export class CoreState implements ICoreState {
readonly itemStore: IItemStore<IHeroAttr>;
readonly mapStore: IMapStore;
readonly eventStore: IGameEventStore;
readonly directionMapper: IDirectionMapper;
readonly replaySystem: IReplaySystem;
// Layer 1 数据层,所有可存档内容都在这,一般用于数据存储
@ -128,7 +127,6 @@ export class CoreState implements ICoreState {
this.mapStore = new MapStore();
// 游戏事件
this.eventStore = new GameEventStore();
this.directionMapper = new DirectionMapper();
//#endregion

View File

@ -7,7 +7,8 @@ import {
RayRange,
RectRange,
ITileLocator,
IDirectionDescriptor
IFaceHandler,
IFaceDescriptor
} from '@motajs/common';
import {
IEnemyContext,
@ -26,7 +27,7 @@ import {
import { IZoneValue } from './special';
import { MapDamageType } from './types';
import { IHeroAttr, IEnemyAttr } from '@user/data-common';
import { IFaceHandler, FaceGroup } from '@user/data-common';
import { FaceGroup } from '@user/data-common';
const RECT_RANGE = new RectRange();
const MANHATTAN_RANGE = new ManhattanRange();
@ -153,7 +154,7 @@ export class RepulseDamageView extends BaseMapDamageView<IManhattanRangeParam> {
export class LaserDamageView extends BaseMapDamageView<IRayRangeParam> {
/** 激光方向列表 */
private readonly dirs: IDirectionDescriptor[];
private readonly dirs: IFaceDescriptor[];
constructor(
context: IEnemyContext<IEnemyAttr, IHeroAttr>,

View File

@ -1,4 +1,4 @@
import { ITileLocator, logger } from '@motajs/common';
import { ITileLocator, logger, IFaceHandler } from '@motajs/common';
import { IMapLayer, IPassPredicate, IStateBase } from '@user/data-base';
import { isNil } from 'lodash-es';
import { MapGraphBuilder } from './graph';
@ -11,7 +11,6 @@ import {
IPathfindingResult,
PathfindingStatus
} from './types';
import { IFaceHandler } from '@user/data-common';
interface IDistanceHeapEntry {
/** 条目的键值,堆中键值最小的条目最先取出 */

View File

@ -1,9 +1,5 @@
import { ITileLocator, logger } from '@motajs/common';
import {
IFaceHandler,
ILocationIndexer,
MapLocIndexer
} from '@user/data-common';
import { ITileLocator, logger, IFaceHandler } from '@motajs/common';
import { ILocationIndexer, MapLocIndexer } from '@user/data-common';
import {
ILayerLocation,
IMapLayer,

View File

@ -1,4 +1,4 @@
import { ITileLocator } from '@motajs/common';
import { ITileLocator, IFaceHandler } from '@motajs/common';
import {
IDataBaseExtended,
ILayerLocation,
@ -6,7 +6,6 @@ import {
IPassPredicate
} from '@user/data-base';
import {
IFaceHandler,
ILocationHelper,
IMoverController,
IObjectMovable,

View File

@ -41,9 +41,9 @@ export class PrivateBooleanDirtyTracker implements IDirtyTracker<boolean> {
/**
* 列表的脏标记追踪器。当传入 `dirtySince` 的标记不属于当前的追踪器时,会返回空集合
*/
export class PrivateListDirtyTracker<T extends number>
implements IDirtyTracker<Set<T>>
{
export class PrivateListDirtyTracker<T extends number> implements IDirtyTracker<
Set<T>
> {
/** 标记映射,键表示在索引,值表示其对应的标记数字 */
private readonly markMap: Map<T, number> = new Map();
/** 标记 symbol 映射,值表示这个 symbol 对应的标记数字 */
@ -89,9 +89,9 @@ export class PrivateListDirtyTracker<T extends number>
}
}
export class PrivateMapDirtyTracker<T extends string>
implements IDirtyTracker<Record<T, boolean>>
{
export class PrivateMapDirtyTracker<T extends string> implements IDirtyTracker<
Record<T, boolean>
> {
/** 标记映射,键表示名称,值表示其对应的标记数字 */
private readonly markMap: Map<T, number> = new Map();
/** 标记 symbol 映射,值表示这个 symbol 对应的标记数字 */

View File

@ -1,36 +0,0 @@
import {
IDirectionDescriptor,
IDirectionMapper,
InternalDirectionGroup
} from './types';
export class DirectionMapper implements IDirectionMapper {
private readonly groups: Map<number, IDirectionDescriptor[]> = new Map();
constructor() {
this.registerGroup(InternalDirectionGroup.Dir4, [
{ x: 0, y: -1 },
{ x: 0, y: 1 },
{ x: -1, y: 0 },
{ x: 1, y: 0 }
]);
this.registerGroup(InternalDirectionGroup.Dir8, [
{ x: 0, y: -1 },
{ x: 0, y: 1 },
{ x: -1, y: 0 },
{ x: 1, y: 0 },
{ x: -1, y: -1 },
{ x: 1, y: -1 },
{ x: -1, y: 1 },
{ x: 1, y: 1 }
]);
}
registerGroup(group: number, dir: Iterable<IDirectionDescriptor>): void {
this.groups.set(group, [...dir]);
}
map(group: number): Iterable<IDirectionDescriptor> {
return this.groups.get(group) ?? [];
}
}

View File

@ -1,4 +1,3 @@
export * from './dir';
export * from './func';
export * from './range';
export * from './types';

View File

@ -1,11 +1,11 @@
import { clamp } from 'lodash-es';
import {
IDirectionDescriptor,
IManhattanRangeParam,
IRangeHost,
IRange,
IRayRangeParam,
IRectRangeParam
IRectRangeParam,
IFaceDescriptor
} from './types';
export abstract class BaseRange<T> implements IRange<T> {
@ -156,7 +156,7 @@ export class RayRange extends BaseRange<IRayRangeParam> {
private isPointOnRay(
x: number,
y: number,
direction: IDirectionDescriptor,
direction: IFaceDescriptor,
param: Readonly<IRayRangeParam>
): boolean {
if (direction.x === 0 && direction.y === 0) {

View File

@ -128,7 +128,7 @@ export interface IRayRangeParam {
/** 中心点纵坐标 */
cy: number;
/** 方向列表 */
dir: IDirectionDescriptor[];
dir: IFaceDescriptor[];
}
//#endregion
@ -142,33 +142,58 @@ export interface ITileLocator {
y: number;
}
export const enum InternalDirectionGroup {
/** 上下左右四方向 */
Dir4,
/** 上下左右+左上+右上+左下+右下八方向 */
Dir8
}
export interface IDirectionDescriptor {
export interface IFaceDescriptor {
/** 横坐标增量 */
readonly x: number;
/** 纵坐标增量 */
readonly y: number;
}
export interface IDirectionMapper {
export interface IFaceHandler<T extends number> {
/**
* 注册一个方向组别
* @param group 方向组别
* @param dir 方向锁包含的描述器
* 将任意朝向值降级为本组支持的方向。
* 对于无法合理降级的方向(包括 `Unknown`),返回 `FaceDirection.Unknown`
* @param dir 任意朝向值
*/
registerGroup(group: number, dir: Iterable<IDirectionDescriptor>): void;
degrade(dir: number): T;
/**
* 根据指定方向组别进行遍历
* @param group 方向组别
* 获取指定方向的单步坐标偏移量,输入先经过 `degrade`
* @param dir 朝向
*/
map(group: number): Iterable<IDirectionDescriptor>;
movement(dir: number): IFaceDescriptor;
/**
* 获取指定方向走 `count` 步的坐标偏移量,等价于 `movement * count`。
* `count` 允许为负数,表示反向位移,输入先经过 `degrade`
* @param dir 朝向
* @param count 步数,允许为负
*/
move(dir: number, count: number): IFaceDescriptor;
/**
* 获取本组内的反方向,输入先经过 `degrade`,`Unknown` 返回 `Unknown`
* @param dir 朝向
*/
opposite(dir: number): T;
/**
* 在本组方向集合内顺时针(默认)或逆时针旋转一步,输入先经过 `degrade`,
* `Unknown` 返回 `Unknown`
* @param dir 朝向
* @param anticlockwise 是否逆时针,默认顺时针
*/
next(dir: number, anticlockwise?: boolean): T;
/**
* 迭代本组支持的所有朝向,包含 `Unknown`
*/
mapDirection(): Iterable<T>;
/**
* 迭代本组所有朝向及其对应的坐标描述器,包含 `Unknown`(对应 `{ x: 0, y: 0 }`)
*/
mapMovement(): Iterable<[T, IFaceDescriptor]>;
}
//#endregion