Compare commits
5 Commits
@esengine/
...
@esengine/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7f8208b6f | ||
|
|
5131ec3c52 | ||
|
|
7d74623710 | ||
|
|
044463dd5f | ||
|
|
ce2db4e48a |
15
packages/framework/behavior-tree/CHANGELOG.md
Normal file
15
packages/framework/behavior-tree/CHANGELOG.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# @esengine/behavior-tree
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d74623`](https://github.com/esengine/esengine/commit/7d746237100084ac3456f1af92ff664db4e50cc8)]:
|
||||
- @esengine/ecs-framework@2.4.4
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ce2db4e`](https://github.com/esengine/esengine/commit/ce2db4e48a7cdac44265420ef16e83f6424f4dea)]:
|
||||
- @esengine/ecs-framework@2.4.3
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@esengine/behavior-tree",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"description": "ECS-based AI behavior tree system - works with any ECS framework (ESEngine, Cocos, Laya, etc.)",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
|
||||
15
packages/framework/blueprint/CHANGELOG.md
Normal file
15
packages/framework/blueprint/CHANGELOG.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# @esengine/blueprint
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d74623`](https://github.com/esengine/esengine/commit/7d746237100084ac3456f1af92ff664db4e50cc8)]:
|
||||
- @esengine/ecs-framework@2.4.4
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ce2db4e`](https://github.com/esengine/esengine/commit/ce2db4e48a7cdac44265420ef16e83f6424f4dea)]:
|
||||
- @esengine/ecs-framework@2.4.3
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@esengine/blueprint",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.2",
|
||||
"description": "Visual scripting system - works with any ECS framework (ESEngine, Cocos, Laya, etc.)",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
|
||||
16
packages/framework/core/CHANGELOG.md
Normal file
16
packages/framework/core/CHANGELOG.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# @esengine/ecs-framework
|
||||
|
||||
## 2.4.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`7d74623`](https://github.com/esengine/esengine/commit/7d746237100084ac3456f1af92ff664db4e50cc8) Thanks [@esengine](https://github.com/esengine)! - fix(core): 修复 npm 发布目录配置,确保从 dist 目录发布以保持与 Cocos Creator 的兼容性
|
||||
|
||||
## 2.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#356](https://github.com/esengine/esengine/pull/356) [`ce2db4e`](https://github.com/esengine/esengine/commit/ce2db4e48a7cdac44265420ef16e83f6424f4dea) Thanks [@esengine](https://github.com/esengine)! - fix(core): 修复 World cleanup 在打包环境下的兼容性问题
|
||||
- 使用 forEach 替代 spread + for...of 解构模式,避免某些打包工具(如 Cocos Creator)转换后的兼容性问题
|
||||
- 重构 World 和 WorldManager 类,提升代码质量
|
||||
- 提取默认配置为常量,统一双语注释格式
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@esengine/ecs-framework",
|
||||
"version": "2.4.2",
|
||||
"version": "2.4.4",
|
||||
"description": "用于Laya、Cocos Creator等JavaScript游戏引擎的高性能ECS框架",
|
||||
"main": "dist/index.cjs",
|
||||
"module": "dist/index.mjs",
|
||||
@@ -70,7 +70,8 @@
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org/"
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"directory": "dist"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -13,7 +13,7 @@ const logger = createLogger('World');
|
||||
* @zh 全局系统是在World级别运行的系统,不依赖特定Scene
|
||||
* @en Global systems run at World level and don't depend on specific Scene
|
||||
*/
|
||||
export type IGlobalSystem = {
|
||||
export interface IGlobalSystem {
|
||||
/**
|
||||
* @zh 系统名称
|
||||
* @en System name
|
||||
@@ -49,7 +49,7 @@ export type IGlobalSystem = {
|
||||
* @zh World配置接口
|
||||
* @en World configuration interface
|
||||
*/
|
||||
export type IWorldConfig = {
|
||||
export interface IWorldConfig {
|
||||
/**
|
||||
* @zh World名称
|
||||
* @en World name
|
||||
@@ -77,12 +77,23 @@ export type IWorldConfig = {
|
||||
/**
|
||||
* @zh 自动清理阈值(毫秒),空Scene超过此时间后将被自动清理
|
||||
* @en Auto cleanup threshold (ms), empty scenes exceeding this time will be auto-cleaned
|
||||
*
|
||||
* @default 300000 (5 minutes)
|
||||
*/
|
||||
cleanupThresholdMs?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh World默认配置
|
||||
* @en World default configuration
|
||||
*/
|
||||
const DEFAULT_CONFIG: Required<IWorldConfig> = {
|
||||
name: 'World',
|
||||
debug: false,
|
||||
maxScenes: 10,
|
||||
autoCleanup: true,
|
||||
cleanupThresholdMs: 5 * 60 * 1000
|
||||
};
|
||||
|
||||
/**
|
||||
* @zh World类 - ECS世界管理器
|
||||
* @en World class - ECS world manager
|
||||
@@ -101,67 +112,66 @@ export type IWorldConfig = {
|
||||
* - World.services: World-level services (independent per World)
|
||||
* - Scene.services: Scene-level services (independent per Scene)
|
||||
*
|
||||
* @zh 这种设计允许创建独立的游戏世界,如:
|
||||
* - 游戏房间(每个房间一个World)
|
||||
* - 不同的游戏模式
|
||||
* - 独立的模拟环境
|
||||
* @en This design allows creating independent game worlds like:
|
||||
* - Game rooms (one World per room)
|
||||
* - Different game modes
|
||||
* - Independent simulation environments
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // @zh 创建游戏房间的World | @en Create World for game room
|
||||
* const roomWorld = new World({ name: 'Room_001' });
|
||||
*
|
||||
* // @zh 注册World级别的服务 | @en Register World-level service
|
||||
* roomWorld.services.registerSingleton(RoomManager);
|
||||
*
|
||||
* // @zh 在World中创建Scene | @en Create Scene in World
|
||||
* const gameScene = roomWorld.createScene('game', new Scene());
|
||||
* const uiScene = roomWorld.createScene('ui', new Scene());
|
||||
*
|
||||
* // @zh 在Scene中使用World级别的服务 | @en Use World-level service in Scene
|
||||
* const roomManager = roomWorld.services.resolve(RoomManager);
|
||||
*
|
||||
* // @zh 更新整个World | @en Update entire World
|
||||
* roomWorld.update(deltaTime);
|
||||
* const gameScene = roomWorld.createScene('game');
|
||||
* roomWorld.setSceneActive('game', true);
|
||||
* roomWorld.start();
|
||||
* ```
|
||||
*/
|
||||
export class World {
|
||||
public readonly name: string;
|
||||
private readonly _config: IWorldConfig;
|
||||
private readonly _scenes: Map<string, IScene> = new Map();
|
||||
private readonly _activeScenes: Set<string> = new Set();
|
||||
|
||||
private readonly _config: Required<IWorldConfig>;
|
||||
private readonly _scenes = new Map<string, IScene>();
|
||||
private readonly _activeScenes = new Set<string>();
|
||||
private readonly _globalSystems: IGlobalSystem[] = [];
|
||||
private readonly _services: ServiceContainer;
|
||||
private _isActive: boolean = false;
|
||||
private _createdAt: number;
|
||||
private readonly _createdAt: number;
|
||||
private _isActive = false;
|
||||
|
||||
constructor(config: IWorldConfig = {}) {
|
||||
this._config = {
|
||||
name: 'World',
|
||||
debug: false,
|
||||
maxScenes: 10,
|
||||
autoCleanup: true,
|
||||
cleanupThresholdMs: 5 * 60 * 1000,
|
||||
...config
|
||||
};
|
||||
|
||||
this.name = this._config.name!;
|
||||
this._config = { ...DEFAULT_CONFIG, ...config };
|
||||
this.name = this._config.name;
|
||||
this._createdAt = Date.now();
|
||||
this._services = new ServiceContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh World级别的服务容器,用于管理World范围内的全局服务
|
||||
* @en World-level service container for managing World-scoped global services
|
||||
* @zh World级别的服务容器
|
||||
* @en World-level service container
|
||||
*/
|
||||
public get services(): ServiceContainer {
|
||||
return this._services;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 检查World是否激活
|
||||
* @en Check if World is active
|
||||
*/
|
||||
public get isActive(): boolean {
|
||||
return this._isActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 获取Scene数量
|
||||
* @en Get scene count
|
||||
*/
|
||||
public get sceneCount(): number {
|
||||
return this._scenes.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 获取创建时间
|
||||
* @en Get creation time
|
||||
*/
|
||||
public get createdAt(): number {
|
||||
return this._createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 创建并添加Scene到World
|
||||
* @en Create and add Scene to World
|
||||
@@ -169,32 +179,21 @@ export class World {
|
||||
* @param sceneName - @zh Scene名称 @en Scene name
|
||||
* @param sceneInstance - @zh Scene实例(可选)@en Scene instance (optional)
|
||||
* @returns @zh 创建的Scene实例 @en Created Scene instance
|
||||
* @throws @zh 名称为空、重复或超出限制时抛出错误 @en Throws if name is empty, duplicate, or limit exceeded
|
||||
*/
|
||||
public createScene<T extends IScene>(sceneName: string, sceneInstance?: T): T {
|
||||
if (!sceneName || typeof sceneName !== 'string' || sceneName.trim() === '') {
|
||||
throw new Error('Scene name不能为空');
|
||||
}
|
||||
this.validateSceneName(sceneName);
|
||||
|
||||
if (this._scenes.has(sceneName)) {
|
||||
throw new Error(`Scene name '${sceneName}' 已存在于World '${this.name}' 中`);
|
||||
}
|
||||
|
||||
if (this._scenes.size >= this._config.maxScenes!) {
|
||||
throw new Error(`World '${this.name}' 已达到最大Scene数量限制: ${this._config.maxScenes}`);
|
||||
}
|
||||
|
||||
const scene = sceneInstance || (new Scene() as unknown as T);
|
||||
const scene = sceneInstance ?? new Scene() as unknown as T;
|
||||
|
||||
if (this._config.debug) {
|
||||
const performanceMonitor = new PerformanceMonitor();
|
||||
performanceMonitor.enable();
|
||||
scene.services.registerInstance(PerformanceMonitor, performanceMonitor);
|
||||
const monitor = new PerformanceMonitor();
|
||||
monitor.enable();
|
||||
scene.services.registerInstance(PerformanceMonitor, monitor);
|
||||
}
|
||||
|
||||
(scene as { id?: string }).id = sceneName;
|
||||
if (!scene.name) {
|
||||
scene.name = sceneName;
|
||||
}
|
||||
scene.name ||= sceneName;
|
||||
|
||||
this._scenes.set(sceneName, scene);
|
||||
scene.initialize();
|
||||
@@ -211,9 +210,7 @@ export class World {
|
||||
*/
|
||||
public removeScene(sceneName: string): boolean {
|
||||
const scene = this._scenes.get(sceneName);
|
||||
if (!scene) {
|
||||
return false;
|
||||
}
|
||||
if (!scene) return false;
|
||||
|
||||
if (this._activeScenes.has(sceneName)) {
|
||||
this.setSceneActive(sceneName, false);
|
||||
@@ -221,11 +218,20 @@ export class World {
|
||||
|
||||
scene.end();
|
||||
this._scenes.delete(sceneName);
|
||||
|
||||
logger.info(`从World '${this.name}' 中移除Scene: ${sceneName}`);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 移除所有Scene
|
||||
* @en Remove all Scenes
|
||||
*/
|
||||
public removeAllScenes(): void {
|
||||
this._scenes.forEach((_, name) => this.removeScene(name));
|
||||
logger.info(`从World '${this.name}' 中移除所有Scene`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 获取Scene
|
||||
* @en Get Scene
|
||||
@@ -234,36 +240,31 @@ export class World {
|
||||
* @returns @zh Scene实例或null @en Scene instance or null
|
||||
*/
|
||||
public getScene<T extends IScene>(sceneName: string): T | null {
|
||||
return this._scenes.get(sceneName) as T || null;
|
||||
return (this._scenes.get(sceneName) as T) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有Scene ID
|
||||
* @zh 获取所有Scene ID
|
||||
* @en Get all Scene IDs
|
||||
*/
|
||||
public getSceneIds(): string[] {
|
||||
return Array.from(this._scenes.keys());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有Scene
|
||||
* @zh 获取所有Scene
|
||||
* @en Get all Scenes
|
||||
*/
|
||||
public getAllScenes(): IScene[] {
|
||||
return Array.from(this._scenes.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除所有Scene
|
||||
*/
|
||||
public removeAllScenes(): void {
|
||||
const sceneNames = Array.from(this._scenes.keys());
|
||||
for (const sceneName of sceneNames) {
|
||||
this.removeScene(sceneName);
|
||||
}
|
||||
logger.info(`从World '${this.name}' 中移除所有Scene`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Scene激活状态
|
||||
* @zh 设置Scene激活状态
|
||||
* @en Set Scene active state
|
||||
*
|
||||
* @param sceneName - @zh Scene名称 @en Scene name
|
||||
* @param active - @zh 是否激活 @en Whether to activate
|
||||
*/
|
||||
public setSceneActive(sceneName: string, active: boolean): void {
|
||||
const scene = this._scenes.get(sceneName);
|
||||
@@ -283,22 +284,27 @@ export class World {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查Scene是否激活
|
||||
* @zh 检查Scene是否激活
|
||||
* @en Check if Scene is active
|
||||
*/
|
||||
public isSceneActive(sceneName: string): boolean {
|
||||
return this._activeScenes.has(sceneName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取活跃Scene数量
|
||||
* @zh 获取活跃Scene数量
|
||||
* @en Get active Scene count
|
||||
*/
|
||||
public getActiveSceneCount(): number {
|
||||
return this._activeScenes.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加全局System
|
||||
* 全局System会在所有激活Scene之前更新
|
||||
* @zh 添加全局System
|
||||
* @en Add global System
|
||||
*
|
||||
* @param system - @zh 全局System实例 @en Global System instance
|
||||
* @returns @zh 添加的System实例 @en Added System instance
|
||||
*/
|
||||
public addGlobalSystem<T extends IGlobalSystem>(system: T): T {
|
||||
if (this._globalSystems.includes(system)) {
|
||||
@@ -307,132 +313,77 @@ export class World {
|
||||
|
||||
this._globalSystems.push(system);
|
||||
system.initialize?.();
|
||||
|
||||
logger.debug(`在World '${this.name}' 中添加全局System: ${system.name}`);
|
||||
|
||||
return system;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除全局System
|
||||
* @zh 移除全局System
|
||||
* @en Remove global System
|
||||
*
|
||||
* @param system - @zh 要移除的System @en System to remove
|
||||
* @returns @zh 是否成功移除 @en Whether removal was successful
|
||||
*/
|
||||
public removeGlobalSystem(system: IGlobalSystem): boolean {
|
||||
const index = this._globalSystems.indexOf(system);
|
||||
if (index === -1) {
|
||||
return false;
|
||||
}
|
||||
if (index === -1) return false;
|
||||
|
||||
this._globalSystems.splice(index, 1);
|
||||
system.reset?.();
|
||||
|
||||
logger.debug(`从World '${this.name}' 中移除全局System: ${system.name}`);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全局System
|
||||
* @zh 获取全局System
|
||||
* @en Get global System
|
||||
*
|
||||
* @param type - @zh System类型 @en System type
|
||||
* @returns @zh System实例或null @en System instance or null
|
||||
*/
|
||||
public getGlobalSystem<T extends IGlobalSystem>(type: new (...args: any[]) => T): T | null {
|
||||
for (const system of this._globalSystems) {
|
||||
if (system instanceof type) {
|
||||
return system as T;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
public getGlobalSystem<T extends IGlobalSystem>(type: new (...args: unknown[]) => T): T | null {
|
||||
return (this._globalSystems.find(s => s instanceof type) as T) ?? null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 启动World
|
||||
* @zh 启动World
|
||||
* @en Start World
|
||||
*/
|
||||
public start(): void {
|
||||
if (this._isActive) {
|
||||
return;
|
||||
}
|
||||
if (this._isActive) return;
|
||||
|
||||
this._isActive = true;
|
||||
|
||||
for (const system of this._globalSystems) {
|
||||
system.initialize?.();
|
||||
}
|
||||
|
||||
this._globalSystems.forEach(s => s.initialize?.());
|
||||
logger.info(`启动World: ${this.name}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止World
|
||||
* @zh 停止World
|
||||
* @en Stop World
|
||||
*/
|
||||
public stop(): void {
|
||||
if (!this._isActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const sceneName of this._activeScenes) {
|
||||
this.setSceneActive(sceneName, false);
|
||||
}
|
||||
|
||||
for (const system of this._globalSystems) {
|
||||
system.reset?.();
|
||||
}
|
||||
if (!this._isActive) return;
|
||||
|
||||
this._activeScenes.forEach(name => this.setSceneActive(name, false));
|
||||
this._globalSystems.forEach(s => s.reset?.());
|
||||
this._isActive = false;
|
||||
logger.info(`停止World: ${this.name}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 更新World中的全局System
|
||||
* @en Update global systems in World
|
||||
*
|
||||
* @internal Called by Core.update()
|
||||
*/
|
||||
public updateGlobalSystems(): void {
|
||||
if (!this._isActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const system of this._globalSystems) {
|
||||
system.update?.();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 更新World中的所有激活Scene
|
||||
* @en Update all active scenes in World
|
||||
*
|
||||
* @internal Called by Core.update()
|
||||
*/
|
||||
public updateScenes(): void {
|
||||
if (!this._isActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const sceneName of this._activeScenes) {
|
||||
const scene = this._scenes.get(sceneName);
|
||||
scene?.update?.();
|
||||
}
|
||||
|
||||
if (this._config.autoCleanup) {
|
||||
this.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁World
|
||||
* @zh 销毁World
|
||||
* @en Destroy World
|
||||
*/
|
||||
public destroy(): void {
|
||||
logger.info(`销毁World: ${this.name}`);
|
||||
|
||||
this.stop();
|
||||
this.removeAllScenes();
|
||||
|
||||
for (const sceneName of Array.from(this._scenes.keys())) {
|
||||
this.removeScene(sceneName);
|
||||
}
|
||||
|
||||
for (const system of this._globalSystems) {
|
||||
if (system.destroy) {
|
||||
system.destroy();
|
||||
} else {
|
||||
system.reset?.();
|
||||
}
|
||||
}
|
||||
this._globalSystems.forEach(s => s.destroy?.() ?? s.reset?.());
|
||||
this._globalSystems.length = 0;
|
||||
|
||||
this._services.clear();
|
||||
@@ -440,10 +391,49 @@ export class World {
|
||||
this._activeScenes.clear();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取World状态
|
||||
* @zh 更新World中的全局System
|
||||
* @en Update global systems in World
|
||||
* @internal
|
||||
*/
|
||||
public updateGlobalSystems(): void {
|
||||
if (!this._isActive) return;
|
||||
this._globalSystems.forEach(s => s.update?.());
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 更新World中的所有激活Scene
|
||||
* @en Update all active scenes in World
|
||||
* @internal
|
||||
*/
|
||||
public updateScenes(): void {
|
||||
if (!this._isActive) return;
|
||||
|
||||
this._activeScenes.forEach(name => {
|
||||
this._scenes.get(name)?.update?.();
|
||||
});
|
||||
|
||||
if (this._config.autoCleanup) {
|
||||
this.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @zh 获取World状态
|
||||
* @en Get World status
|
||||
*/
|
||||
public getStatus() {
|
||||
const scenes: Array<{ id: string; name: string; isActive: boolean }> = [];
|
||||
this._scenes.forEach((scene, id) => {
|
||||
scenes.push({
|
||||
id,
|
||||
name: scene.name || id,
|
||||
isActive: this._activeScenes.has(id)
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
name: this.name,
|
||||
isActive: this._isActive,
|
||||
@@ -452,46 +442,61 @@ export class World {
|
||||
globalSystemCount: this._globalSystems.length,
|
||||
createdAt: this._createdAt,
|
||||
config: { ...this._config },
|
||||
scenes: Array.from(this._scenes.keys()).map((sceneName) => ({
|
||||
id: sceneName,
|
||||
isActive: this._activeScenes.has(sceneName),
|
||||
name: this._scenes.get(sceneName)?.name || sceneName
|
||||
}))
|
||||
scenes
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取World统计信息
|
||||
* @zh 获取World统计信息
|
||||
* @en Get World statistics
|
||||
*/
|
||||
public getStats() {
|
||||
const stats = {
|
||||
totalEntities: 0,
|
||||
totalSystems: this._globalSystems.length,
|
||||
let totalEntities = 0;
|
||||
let totalSystems = this._globalSystems.length;
|
||||
|
||||
this._scenes.forEach(scene => {
|
||||
totalEntities += scene.entities?.count ?? 0;
|
||||
totalSystems += scene.systems?.length ?? 0;
|
||||
});
|
||||
|
||||
return {
|
||||
totalEntities,
|
||||
totalSystems,
|
||||
memoryUsage: 0,
|
||||
performance: {
|
||||
averageUpdateTime: 0,
|
||||
maxUpdateTime: 0
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
for (const scene of this._scenes.values()) {
|
||||
stats.totalEntities += scene.entities?.count ?? 0;
|
||||
stats.totalSystems += scene.systems?.length ?? 0;
|
||||
|
||||
/**
|
||||
* @zh 验证Scene名称
|
||||
* @en Validate Scene name
|
||||
*/
|
||||
private validateSceneName(sceneName: string): void {
|
||||
if (!sceneName?.trim()) {
|
||||
throw new Error('Scene name不能为空');
|
||||
}
|
||||
if (this._scenes.has(sceneName)) {
|
||||
throw new Error(`Scene name '${sceneName}' 已存在于World '${this.name}' 中`);
|
||||
}
|
||||
if (this._scenes.size >= this._config.maxScenes) {
|
||||
throw new Error(`World '${this.name}' 已达到最大Scene数量限制: ${this._config.maxScenes}`);
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 检查Scene是否可以被自动清理
|
||||
* @en Check if a scene is eligible for auto cleanup
|
||||
*/
|
||||
private _isSceneCleanupCandidate(sceneName: string, scene: IScene): boolean {
|
||||
private isCleanupCandidate(sceneName: string, scene: IScene): boolean {
|
||||
const elapsed = Date.now() - this._createdAt;
|
||||
return !this._activeScenes.has(sceneName) &&
|
||||
scene.entities != null &&
|
||||
scene.entities.count === 0 &&
|
||||
elapsed > this._config.cleanupThresholdMs!;
|
||||
elapsed > this._config.cleanupThresholdMs;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -499,33 +504,18 @@ export class World {
|
||||
* @en Execute auto cleanup operation
|
||||
*/
|
||||
private cleanup(): void {
|
||||
const candidates = [...this._scenes.entries()]
|
||||
.filter(([name, scene]) => this._isSceneCleanupCandidate(name, scene));
|
||||
const toRemove: string[] = [];
|
||||
|
||||
for (const [sceneName] of candidates) {
|
||||
this.removeScene(sceneName);
|
||||
logger.debug(`自动清理空Scene: ${sceneName} from World ${this.name}`);
|
||||
}
|
||||
this._scenes.forEach((scene, name) => {
|
||||
if (this.isCleanupCandidate(name, scene)) {
|
||||
toRemove.push(name);
|
||||
}
|
||||
});
|
||||
|
||||
toRemove.forEach(name => {
|
||||
this.removeScene(name);
|
||||
logger.debug(`自动清理空Scene: ${name} from World ${this.name}`);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查World是否激活
|
||||
*/
|
||||
public get isActive(): boolean {
|
||||
return this._isActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Scene数量
|
||||
*/
|
||||
public get sceneCount(): number {
|
||||
return this._scenes.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取创建时间
|
||||
*/
|
||||
public get createdAt(): number {
|
||||
return this._createdAt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,80 +5,85 @@ import type { IService } from '../Core/ServiceContainer';
|
||||
const logger = createLogger('WorldManager');
|
||||
|
||||
/**
|
||||
* WorldManager配置接口
|
||||
* @zh WorldManager配置接口
|
||||
* @en WorldManager configuration interface
|
||||
*/
|
||||
export type IWorldManagerConfig = {
|
||||
export interface IWorldManagerConfig {
|
||||
/**
|
||||
* 最大World数量
|
||||
* @zh 最大World数量
|
||||
* @en Maximum number of worlds
|
||||
*/
|
||||
maxWorlds?: number;
|
||||
|
||||
/**
|
||||
* 是否自动清理空World
|
||||
* @zh 是否自动清理空World
|
||||
* @en Auto cleanup empty worlds
|
||||
*/
|
||||
autoCleanup?: boolean;
|
||||
|
||||
/**
|
||||
* 清理间隔(帧数)
|
||||
* @zh 清理间隔(帧数)
|
||||
* @en Cleanup interval in frames
|
||||
*/
|
||||
cleanupFrameInterval?: number;
|
||||
|
||||
/**
|
||||
* 是否启用调试模式
|
||||
* @zh 是否启用调试模式
|
||||
* @en Enable debug mode
|
||||
*/
|
||||
debug?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* World管理器 - 管理所有World实例
|
||||
* @zh WorldManager默认配置
|
||||
* @en WorldManager default configuration
|
||||
*/
|
||||
const DEFAULT_CONFIG: Required<IWorldManagerConfig> = {
|
||||
maxWorlds: 50,
|
||||
autoCleanup: true,
|
||||
cleanupFrameInterval: 1800,
|
||||
debug: false
|
||||
};
|
||||
|
||||
/**
|
||||
* @zh 清理阈值(毫秒)
|
||||
* @en Cleanup threshold in milliseconds
|
||||
*/
|
||||
const CLEANUP_THRESHOLD_MS = 10 * 60 * 1000; // 10 minutes
|
||||
|
||||
/**
|
||||
* @zh World管理器 - 管理所有World实例
|
||||
* @en World Manager - Manages all World instances
|
||||
*
|
||||
* WorldManager负责管理多个独立的World实例。
|
||||
* @zh WorldManager负责管理多个独立的World实例。
|
||||
* 每个World都是独立的ECS环境,可以包含多个Scene。
|
||||
* @en WorldManager is responsible for managing multiple independent World instances.
|
||||
* Each World is an isolated ECS environment that can contain multiple Scenes.
|
||||
*
|
||||
* 适用场景:
|
||||
* @zh 适用场景:
|
||||
* - MMO游戏的多房间管理
|
||||
* - 服务器端的多游戏实例
|
||||
* - 需要完全隔离的多个游戏环境
|
||||
* @en Use cases:
|
||||
* - Multi-room management for MMO games
|
||||
* - Multiple game instances on server-side
|
||||
* - Completely isolated game environments
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 创建WorldManager实例
|
||||
* const worldManager = new WorldManager({
|
||||
* maxWorlds: 100,
|
||||
* autoCleanup: true
|
||||
* });
|
||||
*
|
||||
* // 创建游戏房间World
|
||||
* const room1 = worldManager.createWorld('room_001', {
|
||||
* name: 'GameRoom_001',
|
||||
* maxScenes: 5
|
||||
* });
|
||||
* room1.setActive(true);
|
||||
*
|
||||
* // 游戏循环
|
||||
* function gameLoop(deltaTime: number) {
|
||||
* Core.update(deltaTime);
|
||||
* worldManager.updateAll(); // 更新所有活跃World
|
||||
* }
|
||||
* const worldManager = new WorldManager({ maxWorlds: 100 });
|
||||
* const room = worldManager.createWorld('room_001');
|
||||
* worldManager.setWorldActive('room_001', true);
|
||||
* ```
|
||||
*/
|
||||
export class WorldManager implements IService {
|
||||
private readonly _config: Required<IWorldManagerConfig>;
|
||||
private readonly _worlds: Map<string, World> = new Map();
|
||||
private _isRunning: boolean = false;
|
||||
private _framesSinceCleanup: number = 0;
|
||||
private readonly _worlds = new Map<string, World>();
|
||||
private _isRunning = true;
|
||||
private _framesSinceCleanup = 0;
|
||||
|
||||
public constructor(config: IWorldManagerConfig = {}) {
|
||||
this._config = {
|
||||
maxWorlds: 50,
|
||||
autoCleanup: true,
|
||||
cleanupFrameInterval: 1800, // 1800帧
|
||||
debug: false,
|
||||
...config
|
||||
};
|
||||
|
||||
// 默认启动运行状态
|
||||
this._isRunning = true;
|
||||
constructor(config: IWorldManagerConfig = {}) {
|
||||
this._config = { ...DEFAULT_CONFIG, ...config };
|
||||
|
||||
logger.info('WorldManager已初始化', {
|
||||
maxWorlds: this._config.maxWorlds,
|
||||
@@ -88,27 +93,57 @@ export class WorldManager implements IService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建新World
|
||||
* @zh 获取World总数
|
||||
* @en Get total world count
|
||||
*/
|
||||
public get worldCount(): number {
|
||||
return this._worlds.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 获取激活World数量
|
||||
* @en Get active world count
|
||||
*/
|
||||
public get activeWorldCount(): number {
|
||||
let count = 0;
|
||||
this._worlds.forEach(world => {
|
||||
if (world.isActive) count++;
|
||||
});
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 检查是否正在运行
|
||||
* @en Check if running
|
||||
*/
|
||||
public get isRunning(): boolean {
|
||||
return this._isRunning;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 获取配置
|
||||
* @en Get configuration
|
||||
*/
|
||||
public get config(): IWorldManagerConfig {
|
||||
return { ...this._config };
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 创建新World
|
||||
* @en Create new World
|
||||
*
|
||||
* @param worldName - @zh World名称 @en World name
|
||||
* @param config - @zh World配置 @en World configuration
|
||||
* @returns @zh 创建的World实例 @en Created World instance
|
||||
* @throws @zh 名称为空、重复或超出限制时抛出错误 @en Throws if name is empty, duplicate, or limit exceeded
|
||||
*/
|
||||
public createWorld(worldName: string, config?: IWorldConfig): World {
|
||||
if (!worldName || typeof worldName !== 'string' || worldName.trim() === '') {
|
||||
throw new Error('World name不能为空');
|
||||
}
|
||||
this.validateWorldName(worldName);
|
||||
|
||||
if (this._worlds.has(worldName)) {
|
||||
throw new Error(`World name '${worldName}' 已存在`);
|
||||
}
|
||||
|
||||
if (this._worlds.size >= this._config.maxWorlds!) {
|
||||
throw new Error(`已达到最大World数量限制: ${this._config.maxWorlds}`);
|
||||
}
|
||||
|
||||
// 优先级:config.debug > WorldManager.debug > 默认
|
||||
const worldConfig: IWorldConfig = {
|
||||
...config,
|
||||
name: worldName,
|
||||
debug: config?.debug ?? this._config.debug ?? false,
|
||||
...(config?.maxScenes !== undefined && { maxScenes: config.maxScenes }),
|
||||
...(config?.autoCleanup !== undefined && { autoCleanup: config.autoCleanup })
|
||||
debug: config?.debug ?? this._config.debug
|
||||
};
|
||||
|
||||
const world = new World(worldConfig);
|
||||
@@ -118,45 +153,56 @@ export class WorldManager implements IService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除World
|
||||
* @zh 移除World
|
||||
* @en Remove World
|
||||
*
|
||||
* @param worldName - @zh World名称 @en World name
|
||||
* @returns @zh 是否成功移除 @en Whether removal was successful
|
||||
*/
|
||||
public removeWorld(worldName: string): boolean {
|
||||
const world = this._worlds.get(worldName);
|
||||
if (!world) {
|
||||
return false;
|
||||
}
|
||||
if (!world) return false;
|
||||
|
||||
// 销毁World
|
||||
world.destroy();
|
||||
this._worlds.delete(worldName);
|
||||
|
||||
logger.info(`移除World: ${worldName}`);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取World
|
||||
* @zh 获取World
|
||||
* @en Get World
|
||||
*
|
||||
* @param worldName - @zh World名称 @en World name
|
||||
* @returns @zh World实例或null @en World instance or null
|
||||
*/
|
||||
public getWorld(worldName: string): World | null {
|
||||
return this._worlds.get(worldName) || null;
|
||||
return this._worlds.get(worldName) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有World ID
|
||||
* @zh 获取所有World ID
|
||||
* @en Get all World IDs
|
||||
*/
|
||||
public getWorldIds(): string[] {
|
||||
return Array.from(this._worlds.keys());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有World
|
||||
* @zh 获取所有World
|
||||
* @en Get all Worlds
|
||||
*/
|
||||
public getAllWorlds(): World[] {
|
||||
return Array.from(this._worlds.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置World激活状态
|
||||
* @zh 设置World激活状态
|
||||
* @en Set World active state
|
||||
*
|
||||
* @param worldName - @zh World名称 @en World name
|
||||
* @param active - @zh 是否激活 @en Whether to activate
|
||||
*/
|
||||
public setWorldActive(worldName: string, active: boolean): void {
|
||||
const world = this._worlds.get(worldName);
|
||||
@@ -175,204 +221,84 @@ export class WorldManager implements IService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查World是否激活
|
||||
* @zh 检查World是否激活
|
||||
* @en Check if World is active
|
||||
*/
|
||||
public isWorldActive(worldName: string): boolean {
|
||||
const world = this._worlds.get(worldName);
|
||||
return world?.isActive ?? false;
|
||||
return this._worlds.get(worldName)?.isActive ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新所有活跃的World
|
||||
*
|
||||
* 应该在每帧的游戏循环中调用。
|
||||
* 会自动更新所有活跃World的全局系统和场景。
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* function gameLoop(deltaTime: number) {
|
||||
* Core.update(deltaTime); // 更新全局服务
|
||||
* worldManager.updateAll(); // 更新所有World
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
public updateAll(): void {
|
||||
if (!this._isRunning) return;
|
||||
|
||||
for (const world of this._worlds.values()) {
|
||||
if (world.isActive) {
|
||||
// 更新World的全局System
|
||||
world.updateGlobalSystems();
|
||||
|
||||
// 更新World中的所有Scene
|
||||
world.updateScenes();
|
||||
}
|
||||
}
|
||||
|
||||
// 基于帧的自动清理
|
||||
if (this._config.autoCleanup) {
|
||||
this._framesSinceCleanup++;
|
||||
|
||||
if (this._framesSinceCleanup >= this._config.cleanupFrameInterval) {
|
||||
this.cleanup();
|
||||
this._framesSinceCleanup = 0; // 重置计数器
|
||||
|
||||
if (this._config.debug) {
|
||||
logger.debug(`执行定期清理World (间隔: ${this._config.cleanupFrameInterval} 帧)`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有激活的World
|
||||
* @zh 获取所有激活的World
|
||||
* @en Get all active Worlds
|
||||
*/
|
||||
public getActiveWorlds(): World[] {
|
||||
const activeWorlds: World[] = [];
|
||||
for (const world of this._worlds.values()) {
|
||||
if (world.isActive) {
|
||||
activeWorlds.push(world);
|
||||
}
|
||||
}
|
||||
return activeWorlds;
|
||||
const result: World[] = [];
|
||||
this._worlds.forEach(world => {
|
||||
if (world.isActive) result.push(world);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动所有World
|
||||
* @zh 查找满足条件的World
|
||||
* @en Find Worlds matching predicate
|
||||
*
|
||||
* @param predicate - @zh 过滤条件 @en Filter predicate
|
||||
*/
|
||||
public findWorlds(predicate: (world: World) => boolean): World[] {
|
||||
const result: World[] = [];
|
||||
this._worlds.forEach(world => {
|
||||
if (predicate(world)) result.push(world);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 根据名称查找World
|
||||
* @en Find World by name
|
||||
*
|
||||
* @param name - @zh World名称 @en World name
|
||||
*/
|
||||
public findWorldByName(name: string): World | null {
|
||||
let found: World | null = null;
|
||||
this._worlds.forEach(world => {
|
||||
if (world.name === name) found = world;
|
||||
});
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 启动所有World
|
||||
* @en Start all Worlds
|
||||
*/
|
||||
public startAll(): void {
|
||||
this._isRunning = true;
|
||||
|
||||
for (const world of this._worlds.values()) {
|
||||
world.start();
|
||||
}
|
||||
|
||||
this._worlds.forEach(world => world.start());
|
||||
logger.info('启动所有World');
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止所有World
|
||||
* @zh 停止所有World
|
||||
* @en Stop all Worlds
|
||||
*/
|
||||
public stopAll(): void {
|
||||
this._isRunning = false;
|
||||
|
||||
for (const world of this._worlds.values()) {
|
||||
world.stop();
|
||||
}
|
||||
|
||||
this._worlds.forEach(world => world.stop());
|
||||
logger.info('停止所有World');
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找满足条件的World
|
||||
*/
|
||||
public findWorlds(predicate: (world: World) => boolean): World[] {
|
||||
const results: World[] = [];
|
||||
for (const world of this._worlds.values()) {
|
||||
if (predicate(world)) {
|
||||
results.push(world);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据名称查找World
|
||||
*/
|
||||
public findWorldByName(name: string): World | null {
|
||||
for (const world of this._worlds.values()) {
|
||||
if (world.name === name) {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取WorldManager统计信息
|
||||
*/
|
||||
public getStats() {
|
||||
const stats = {
|
||||
totalWorlds: this._worlds.size,
|
||||
activeWorlds: this.activeWorldCount,
|
||||
totalScenes: 0,
|
||||
totalEntities: 0,
|
||||
totalSystems: 0,
|
||||
memoryUsage: 0,
|
||||
isRunning: this._isRunning,
|
||||
config: { ...this._config },
|
||||
worlds: [] as any[]
|
||||
};
|
||||
|
||||
for (const [worldName, world] of this._worlds) {
|
||||
const worldStats = world.getStats();
|
||||
stats.totalScenes += worldStats.totalSystems; // World的getStats可能需要调整
|
||||
stats.totalEntities += worldStats.totalEntities;
|
||||
stats.totalSystems += worldStats.totalSystems;
|
||||
|
||||
stats.worlds.push({
|
||||
id: worldName,
|
||||
name: world.name,
|
||||
isActive: world.isActive,
|
||||
sceneCount: world.sceneCount,
|
||||
...worldStats
|
||||
});
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取详细状态信息
|
||||
*/
|
||||
public getDetailedStatus() {
|
||||
return {
|
||||
...this.getStats(),
|
||||
worlds: Array.from(this._worlds.entries()).map(([worldName, world]) => ({
|
||||
id: worldName,
|
||||
isActive: world.isActive,
|
||||
status: world.getStatus()
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理空World
|
||||
*/
|
||||
public cleanup(): number {
|
||||
const worldsToRemove: string[] = [];
|
||||
|
||||
for (const [worldName, world] of this._worlds) {
|
||||
if (this.shouldCleanupWorld(world)) {
|
||||
worldsToRemove.push(worldName);
|
||||
}
|
||||
}
|
||||
|
||||
for (const worldName of worldsToRemove) {
|
||||
this.removeWorld(worldName);
|
||||
}
|
||||
|
||||
if (worldsToRemove.length > 0) {
|
||||
logger.debug(`清理了 ${worldsToRemove.length} 个World`);
|
||||
}
|
||||
|
||||
return worldsToRemove.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁WorldManager
|
||||
* @zh 销毁WorldManager
|
||||
* @en Destroy WorldManager
|
||||
*/
|
||||
public destroy(): void {
|
||||
logger.info('正在销毁WorldManager...');
|
||||
|
||||
// 停止所有World
|
||||
this.stopAll();
|
||||
|
||||
// 销毁所有World
|
||||
const worldNames = Array.from(this._worlds.keys());
|
||||
for (const worldName of worldNames) {
|
||||
this.removeWorld(worldName);
|
||||
}
|
||||
worldNames.forEach(name => this.removeWorld(name));
|
||||
|
||||
this._worlds.clear();
|
||||
this._isRunning = false;
|
||||
@@ -381,67 +307,178 @@ export class WorldManager implements IService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现 IService 接口的 dispose 方法
|
||||
* 调用 destroy 方法进行清理
|
||||
* @zh 实现 IService 接口的 dispose 方法
|
||||
* @en Implement IService dispose method
|
||||
*/
|
||||
public dispose(): void {
|
||||
this.destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断World是否应该被清理
|
||||
* 清理策略:
|
||||
* 1. World未激活
|
||||
* 2. 没有Scene或所有Scene都是空的
|
||||
* 3. 创建时间超过10分钟
|
||||
* @zh 更新所有活跃的World
|
||||
* @en Update all active Worlds
|
||||
*
|
||||
* @zh 应该在每帧的游戏循环中调用
|
||||
* @en Should be called in each frame of game loop
|
||||
*/
|
||||
private shouldCleanupWorld(world: World): boolean {
|
||||
if (world.isActive) {
|
||||
return false;
|
||||
public updateAll(): void {
|
||||
if (!this._isRunning) return;
|
||||
|
||||
this._worlds.forEach(world => {
|
||||
if (world.isActive) {
|
||||
world.updateGlobalSystems();
|
||||
world.updateScenes();
|
||||
}
|
||||
});
|
||||
|
||||
this.processAutoCleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 获取WorldManager统计信息
|
||||
* @en Get WorldManager statistics
|
||||
*/
|
||||
public getStats() {
|
||||
let totalScenes = 0;
|
||||
let totalEntities = 0;
|
||||
let totalSystems = 0;
|
||||
const worldsList: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
isActive: boolean;
|
||||
sceneCount: number;
|
||||
totalEntities: number;
|
||||
totalSystems: number;
|
||||
}> = [];
|
||||
|
||||
this._worlds.forEach((world, worldName) => {
|
||||
const worldStats = world.getStats();
|
||||
totalScenes += world.sceneCount;
|
||||
totalEntities += worldStats.totalEntities;
|
||||
totalSystems += worldStats.totalSystems;
|
||||
|
||||
worldsList.push({
|
||||
id: worldName,
|
||||
name: world.name,
|
||||
isActive: world.isActive,
|
||||
sceneCount: world.sceneCount,
|
||||
...worldStats
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
totalWorlds: this._worlds.size,
|
||||
activeWorlds: this.activeWorldCount,
|
||||
totalScenes,
|
||||
totalEntities,
|
||||
totalSystems,
|
||||
memoryUsage: 0,
|
||||
isRunning: this._isRunning,
|
||||
config: { ...this._config },
|
||||
worlds: worldsList
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 获取详细状态信息
|
||||
* @en Get detailed status information
|
||||
*/
|
||||
public getDetailedStatus() {
|
||||
const worlds: Array<{
|
||||
id: string;
|
||||
isActive: boolean;
|
||||
status: ReturnType<World['getStatus']>;
|
||||
}> = [];
|
||||
|
||||
this._worlds.forEach((world, worldName) => {
|
||||
worlds.push({
|
||||
id: worldName,
|
||||
isActive: world.isActive,
|
||||
status: world.getStatus()
|
||||
});
|
||||
});
|
||||
|
||||
return { ...this.getStats(), worlds };
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 清理空World
|
||||
* @en Cleanup empty Worlds
|
||||
*
|
||||
* @returns @zh 清理的World数量 @en Number of cleaned up Worlds
|
||||
*/
|
||||
public cleanup(): number {
|
||||
const toRemove: string[] = [];
|
||||
|
||||
this._worlds.forEach((world, worldName) => {
|
||||
if (this.isCleanupCandidate(world)) {
|
||||
toRemove.push(worldName);
|
||||
}
|
||||
});
|
||||
|
||||
toRemove.forEach(name => this.removeWorld(name));
|
||||
|
||||
if (toRemove.length > 0) {
|
||||
logger.debug(`清理了 ${toRemove.length} 个World`);
|
||||
}
|
||||
|
||||
return toRemove.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 验证World名称
|
||||
* @en Validate World name
|
||||
*/
|
||||
private validateWorldName(worldName: string): void {
|
||||
if (!worldName?.trim()) {
|
||||
throw new Error('World name不能为空');
|
||||
}
|
||||
if (this._worlds.has(worldName)) {
|
||||
throw new Error(`World name '${worldName}' 已存在`);
|
||||
}
|
||||
if (this._worlds.size >= this._config.maxWorlds) {
|
||||
throw new Error(`已达到最大World数量限制: ${this._config.maxWorlds}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 处理自动清理
|
||||
* @en Process auto cleanup
|
||||
*/
|
||||
private processAutoCleanup(): void {
|
||||
if (!this._config.autoCleanup) return;
|
||||
|
||||
this._framesSinceCleanup++;
|
||||
|
||||
if (this._framesSinceCleanup >= this._config.cleanupFrameInterval) {
|
||||
this.cleanup();
|
||||
this._framesSinceCleanup = 0;
|
||||
|
||||
if (this._config.debug) {
|
||||
logger.debug(`执行定期清理World (间隔: ${this._config.cleanupFrameInterval} 帧)`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 判断World是否应该被清理
|
||||
* @en Check if World should be cleaned up
|
||||
*
|
||||
* @zh 清理策略:未激活 + (无Scene或全空Scene) + 创建超过10分钟
|
||||
* @en Cleanup policy: inactive + (no scenes or all empty) + created over 10 minutes ago
|
||||
*/
|
||||
private isCleanupCandidate(world: World): boolean {
|
||||
if (world.isActive) return false;
|
||||
|
||||
const age = Date.now() - world.createdAt;
|
||||
const isOldEnough = age > 10 * 60 * 1000; // 10分钟
|
||||
if (age <= CLEANUP_THRESHOLD_MS) return false;
|
||||
|
||||
if (world.sceneCount === 0) {
|
||||
return isOldEnough;
|
||||
}
|
||||
if (world.sceneCount === 0) return true;
|
||||
|
||||
// 检查是否所有Scene都是空的
|
||||
const allScenes = world.getAllScenes();
|
||||
const hasEntities = allScenes.some((scene) => scene.entities && scene.entities.count > 0);
|
||||
return !hasEntities && isOldEnough;
|
||||
}
|
||||
const hasEntities = world.getAllScenes().some(
|
||||
scene => scene.entities && scene.entities.count > 0
|
||||
);
|
||||
|
||||
/**
|
||||
* 获取World总数
|
||||
*/
|
||||
public get worldCount(): number {
|
||||
return this._worlds.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取激活World数量
|
||||
*/
|
||||
public get activeWorldCount(): number {
|
||||
let count = 0;
|
||||
for (const world of this._worlds.values()) {
|
||||
if (world.isActive) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否正在运行
|
||||
*/
|
||||
public get isRunning(): boolean {
|
||||
return this._isRunning;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
*/
|
||||
public get config(): IWorldManagerConfig {
|
||||
return { ...this._config };
|
||||
return !hasEntities;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @esengine/fsm
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d74623`](https://github.com/esengine/esengine/commit/7d746237100084ac3456f1af92ff664db4e50cc8)]:
|
||||
- @esengine/ecs-framework@2.4.4
|
||||
- @esengine/blueprint@1.0.2
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ce2db4e`](https://github.com/esengine/esengine/commit/ce2db4e48a7cdac44265420ef16e83f6424f4dea)]:
|
||||
- @esengine/ecs-framework@2.4.3
|
||||
- @esengine/blueprint@1.0.1
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@esengine/fsm",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"description": "Finite State Machine for ECS Framework / ECS 框架的有限状态机",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @esengine/pathfinding
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d74623`](https://github.com/esengine/esengine/commit/7d746237100084ac3456f1af92ff664db4e50cc8)]:
|
||||
- @esengine/ecs-framework@2.4.4
|
||||
- @esengine/blueprint@1.0.2
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ce2db4e`](https://github.com/esengine/esengine/commit/ce2db4e48a7cdac44265420ef16e83f6424f4dea)]:
|
||||
- @esengine/ecs-framework@2.4.3
|
||||
- @esengine/blueprint@1.0.1
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@esengine/pathfinding",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"description": "寻路系统 | Pathfinding System - A*, Grid, NavMesh",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @esengine/procgen
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d74623`](https://github.com/esengine/esengine/commit/7d746237100084ac3456f1af92ff664db4e50cc8)]:
|
||||
- @esengine/ecs-framework@2.4.4
|
||||
- @esengine/blueprint@1.0.2
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ce2db4e`](https://github.com/esengine/esengine/commit/ce2db4e48a7cdac44265420ef16e83f6424f4dea)]:
|
||||
- @esengine/ecs-framework@2.4.3
|
||||
- @esengine/blueprint@1.0.1
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@esengine/procgen",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"description": "Procedural generation tools for ECS Framework / ECS 框架的程序化生成工具",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @esengine/spatial
|
||||
|
||||
## 1.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d74623`](https://github.com/esengine/esengine/commit/7d746237100084ac3456f1af92ff664db4e50cc8)]:
|
||||
- @esengine/ecs-framework@2.4.4
|
||||
- @esengine/blueprint@1.0.2
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ce2db4e`](https://github.com/esengine/esengine/commit/ce2db4e48a7cdac44265420ef16e83f6424f4dea)]:
|
||||
- @esengine/ecs-framework@2.4.3
|
||||
- @esengine/blueprint@1.0.1
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@esengine/spatial",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.4",
|
||||
"description": "Spatial query and indexing system for ECS Framework / ECS 框架的空间查询和索引系统",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @esengine/timer
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7d74623`](https://github.com/esengine/esengine/commit/7d746237100084ac3456f1af92ff664db4e50cc8)]:
|
||||
- @esengine/ecs-framework@2.4.4
|
||||
- @esengine/blueprint@1.0.2
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ce2db4e`](https://github.com/esengine/esengine/commit/ce2db4e48a7cdac44265420ef16e83f6424f4dea)]:
|
||||
- @esengine/ecs-framework@2.4.3
|
||||
- @esengine/blueprint@1.0.1
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@esengine/timer",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"description": "Timer and cooldown system for ECS Framework / ECS 框架的定时器和冷却系统",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# @esengine/demos
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @esengine/fsm@1.0.3
|
||||
- @esengine/pathfinding@1.0.3
|
||||
- @esengine/procgen@1.0.3
|
||||
- @esengine/spatial@1.0.4
|
||||
- @esengine/timer@1.0.3
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @esengine/fsm@1.0.2
|
||||
- @esengine/pathfinding@1.0.2
|
||||
- @esengine/procgen@1.0.2
|
||||
- @esengine/spatial@1.0.3
|
||||
- @esengine/timer@1.0.2
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@esengine/demos",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"private": true,
|
||||
"description": "Demo tests for ESEngine modules documentation",
|
||||
"type": "module",
|
||||
|
||||
85
pnpm-lock.yaml
generated
85
pnpm-lock.yaml
generated
@@ -185,7 +185,7 @@ importers:
|
||||
version: link:../../engine/ecs-engine-bindgen
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/editor-core':
|
||||
specifier: workspace:*
|
||||
version: link:../editor-core
|
||||
@@ -385,7 +385,7 @@ importers:
|
||||
version: link:../plugins/asset-system-editor
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/engine-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../engine/engine-core
|
||||
@@ -476,7 +476,7 @@ importers:
|
||||
devDependencies:
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/ecs-framework-math':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/math
|
||||
@@ -550,7 +550,7 @@ importers:
|
||||
version: link:../../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../../framework/core
|
||||
version: link:../../../framework/core/dist
|
||||
'@esengine/editor-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../editor-core
|
||||
@@ -596,7 +596,7 @@ importers:
|
||||
version: link:../../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../../framework/core
|
||||
version: link:../../../framework/core/dist
|
||||
'@esengine/editor-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../editor-core
|
||||
@@ -639,7 +639,7 @@ importers:
|
||||
version: link:../../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../../framework/core
|
||||
version: link:../../../framework/core/dist
|
||||
'@esengine/editor-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../editor-core
|
||||
@@ -676,7 +676,7 @@ importers:
|
||||
version: link:../../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../../framework/core
|
||||
version: link:../../../framework/core/dist
|
||||
'@esengine/editor-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../editor-core
|
||||
@@ -713,7 +713,7 @@ importers:
|
||||
version: link:../../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../../framework/core
|
||||
version: link:../../../framework/core/dist
|
||||
'@esengine/editor-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../editor-core
|
||||
@@ -756,7 +756,7 @@ importers:
|
||||
version: link:../../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../../framework/core
|
||||
version: link:../../../framework/core/dist
|
||||
'@esengine/editor-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../editor-core
|
||||
@@ -833,7 +833,7 @@ importers:
|
||||
version: link:../../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../../framework/core
|
||||
version: link:../../../framework/core/dist
|
||||
'@esengine/editor-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../editor-core
|
||||
@@ -876,7 +876,7 @@ importers:
|
||||
version: link:../../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../../framework/core
|
||||
version: link:../../../framework/core/dist
|
||||
'@esengine/editor-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../editor-core
|
||||
@@ -913,7 +913,7 @@ importers:
|
||||
version: link:../../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../../framework/core
|
||||
version: link:../../../framework/core/dist
|
||||
'@esengine/editor-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../editor-core
|
||||
@@ -953,7 +953,7 @@ importers:
|
||||
version: link:../../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../../framework/core
|
||||
version: link:../../../framework/core/dist
|
||||
'@esengine/editor-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../editor-core
|
||||
@@ -993,7 +993,7 @@ importers:
|
||||
version: link:../../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../../framework/core
|
||||
version: link:../../../framework/core/dist
|
||||
'@esengine/editor-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../editor-core
|
||||
@@ -1036,7 +1036,7 @@ importers:
|
||||
version: link:../../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../../framework/core
|
||||
version: link:../../../framework/core/dist
|
||||
'@esengine/editor-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../editor-core
|
||||
@@ -1079,7 +1079,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/engine-core':
|
||||
specifier: workspace:*
|
||||
version: link:../engine-core
|
||||
@@ -1100,7 +1100,7 @@ importers:
|
||||
version: link:../asset-system
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/ecs-framework-math':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/math
|
||||
@@ -1135,7 +1135,7 @@ importers:
|
||||
dependencies:
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/ecs-framework-math':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/math
|
||||
@@ -1166,7 +1166,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/engine-core':
|
||||
specifier: workspace:*
|
||||
version: link:../engine-core
|
||||
@@ -1215,7 +1215,7 @@ importers:
|
||||
version: link:../asset-system
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/engine-core':
|
||||
specifier: workspace:*
|
||||
version: link:../engine-core
|
||||
@@ -1251,7 +1251,7 @@ importers:
|
||||
dependencies:
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/platform-common':
|
||||
specifier: workspace:*
|
||||
version: link:../platform-common
|
||||
@@ -1291,7 +1291,7 @@ importers:
|
||||
version: link:../ecs-engine-bindgen
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/ecs-framework-math':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/math
|
||||
@@ -1329,7 +1329,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/engine-core':
|
||||
specifier: workspace:*
|
||||
version: link:../engine-core
|
||||
@@ -1357,7 +1357,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
version: link:../core/dist
|
||||
'@types/jest':
|
||||
specifier: ^29.5.14
|
||||
version: 29.5.14
|
||||
@@ -1391,7 +1391,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
version: link:../core/dist
|
||||
'@types/node':
|
||||
specifier: ^20.19.17
|
||||
version: 20.19.27
|
||||
@@ -1474,6 +1474,7 @@ importers:
|
||||
typescript-eslint:
|
||||
specifier: ^8.46.1
|
||||
version: 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
|
||||
publishDirectory: dist
|
||||
|
||||
packages/framework/fsm:
|
||||
dependencies:
|
||||
@@ -1489,7 +1490,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
version: link:../core/dist
|
||||
'@types/node':
|
||||
specifier: ^20.19.17
|
||||
version: 20.19.27
|
||||
@@ -1559,7 +1560,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
version: link:../core/dist
|
||||
rimraf:
|
||||
specifier: ^5.0.5
|
||||
version: 5.0.10
|
||||
@@ -1599,7 +1600,7 @@ importers:
|
||||
version: link:../blueprint
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
version: link:../core/dist
|
||||
'@esengine/ecs-framework-math':
|
||||
specifier: workspace:*
|
||||
version: link:../math
|
||||
@@ -1624,7 +1625,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
version: link:../core/dist
|
||||
'@types/node':
|
||||
specifier: ^20.19.17
|
||||
version: 20.19.27
|
||||
@@ -1652,7 +1653,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
version: link:../core/dist
|
||||
'@esengine/ecs-framework-math':
|
||||
specifier: workspace:*
|
||||
version: link:../math
|
||||
@@ -1683,7 +1684,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
version: link:../core/dist
|
||||
'@types/node':
|
||||
specifier: ^20.19.17
|
||||
version: 20.19.27
|
||||
@@ -1730,7 +1731,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/ecs-framework-math':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/math
|
||||
@@ -1766,7 +1767,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/engine-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../engine/engine-core
|
||||
@@ -1787,7 +1788,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/ecs-framework-math':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/math
|
||||
@@ -1818,7 +1819,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@types/node':
|
||||
specifier: ^20.19.17
|
||||
version: 20.19.27
|
||||
@@ -1849,7 +1850,7 @@ importers:
|
||||
version: link:../../engine/ecs-engine-bindgen
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/engine-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../engine/engine-core
|
||||
@@ -1879,7 +1880,7 @@ importers:
|
||||
version: link:../../engine/ecs-engine-bindgen
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/engine-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../engine/engine-core
|
||||
@@ -1910,7 +1911,7 @@ importers:
|
||||
version: link:../../engine/ecs-engine-bindgen
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/ecs-framework-math':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/math
|
||||
@@ -1940,7 +1941,7 @@ importers:
|
||||
version: link:../../tools/build-config
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/engine-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../engine/engine-core
|
||||
@@ -1974,7 +1975,7 @@ importers:
|
||||
version: link:../../engine/ecs-engine-bindgen
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/ecs-framework-math':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/math
|
||||
@@ -2004,7 +2005,7 @@ importers:
|
||||
dependencies:
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/engine-core':
|
||||
specifier: workspace:*
|
||||
version: link:../../engine/engine-core
|
||||
@@ -2100,7 +2101,7 @@ importers:
|
||||
version: link:../../rendering/camera
|
||||
'@esengine/ecs-framework':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/core
|
||||
version: link:../../framework/core/dist
|
||||
'@esengine/ecs-framework-math':
|
||||
specifier: workspace:*
|
||||
version: link:../../framework/math
|
||||
|
||||
Reference in New Issue
Block a user