废弃core.scene更改为setscene方法

This commit is contained in:
YHH
2025-08-12 11:08:27 +08:00
parent 86cb70a94f
commit 56dd18b983
13 changed files with 96 additions and 85 deletions

View File

@@ -54,7 +54,7 @@ import { Core, Scene, Entity, Component, EntitySystem, Matcher, Time } from '@es
// 创建核心实例 // 创建核心实例
const core = Core.create({ debug: true }); const core = Core.create({ debug: true });
const scene = new Scene(); const scene = new Scene();
Core.scene = scene; Core.setScene(scene);
// 定义组件 // 定义组件
class PositionComponent extends Component { class PositionComponent extends Component {

View File

@@ -107,7 +107,7 @@ const scene = new Scene();
scene.name = "GameScene"; scene.name = "GameScene";
// 设置为当前场景 // 设置为当前场景
Core.scene = scene; Core.setScene(scene;
// 场景生命周期 // 场景生命周期
scene.begin(); // 开始场景 scene.begin(); // 开始场景

View File

@@ -189,7 +189,7 @@ class LayaECSGame extends LayaScene {
this.ecsScene = new ECSScene(); this.ecsScene = new ECSScene();
this.ecsScene.name = "LayaGameScene"; this.ecsScene.name = "LayaGameScene";
Core.scene = this.ecsScene; Core.setScene(this.ecsScene);
this.entityManager = new EntityManager(); this.entityManager = new EntityManager();
this.setupSystems(); this.setupSystems();
@@ -264,7 +264,7 @@ export class ECSGameManager extends CocosComponent {
this.ecsScene = new ECSScene(); this.ecsScene = new ECSScene();
this.ecsScene.name = "CocosGameScene"; this.ecsScene.name = "CocosGameScene";
Core.scene = this.ecsScene; Core.setScene(this.ecsScene);
this.entityManager = new EntityManager(); this.entityManager = new EntityManager();
this.setupSystems(); this.setupSystems();
@@ -340,7 +340,7 @@ class ServerGameManager {
this.scene = new Scene(); this.scene = new Scene();
this.scene.name = "ServerScene"; this.scene.name = "ServerScene";
Core.scene = this.scene; Core.setScene(this.scene);
this.entityManager = new EntityManager(); this.entityManager = new EntityManager();
this.setupSystems(); this.setupSystems();
@@ -434,7 +434,7 @@ class BrowserGame {
this.scene = new Scene(); this.scene = new Scene();
this.scene.name = "BrowserScene"; this.scene.name = "BrowserScene";
Core.scene = this.scene; Core.setScene(this.scene);
this.entityManager = new EntityManager(); this.entityManager = new EntityManager();
this.setupSystems(); this.setupSystems();

View File

@@ -19,10 +19,12 @@ import { Scene, Core } from '@esengine/ecs-framework';
// 创建场景 // 创建场景
const gameScene = new Scene(); const gameScene = new Scene();
// 设置为当前活动场景 // 设置为当前活动场景推荐使用setScene方法
Core.scene = gameScene; Core.setScene(gameScene);
``` ```
> **注意**: `Core.scene = ` 设置方式已被标记为废弃,推荐使用 `Core.setScene()` 方法。新方法提供更好的类型安全性和可预测的激活时序。
### 场景的生命周期 ### 场景的生命周期
```typescript ```typescript
@@ -113,7 +115,7 @@ class MenuScene extends Scene {
private transitionToGame() { private transitionToGame() {
// 切换到游戏场景 // 切换到游戏场景
const gameScene = new GameScene(); const gameScene = new GameScene();
Core.scene = gameScene; Core.setScene(gameScene);
} }
} }
``` ```
@@ -251,7 +253,7 @@ class SceneManager {
// 创建新场景 // 创建新场景
this.currentScene = this.createScene(sceneType, data); this.currentScene = this.createScene(sceneType, data);
Core.scene = this.currentScene; Core.setScene(this.currentScene);
console.log(`切换到场景: ${sceneType}`); console.log(`切换到场景: ${sceneType}`);
} }
@@ -265,7 +267,7 @@ class SceneManager {
} }
this.currentScene = previousScene; this.currentScene = previousScene;
Core.scene = this.currentScene; Core.setScene(this.currentScene);
return true; return true;
} }
return false; return false;
@@ -280,7 +282,7 @@ class SceneManager {
} }
this.currentScene = this.createScene(sceneType, data); this.currentScene = this.createScene(sceneType, data);
Core.scene = this.currentScene; Core.setScene(this.currentScene);
} }
popScene() { popScene() {
@@ -291,7 +293,7 @@ class SceneManager {
this.currentScene = this.sceneHistory.pop()!; this.currentScene = this.sceneHistory.pop()!;
this.resumeScene(this.currentScene); this.resumeScene(this.currentScene);
Core.scene = this.currentScene; Core.setScene(this.currentScene);
} }
} }
@@ -359,7 +361,7 @@ class TransitionManager {
// 切换场景 // 切换场景
fromScene.onDestroy(); fromScene.onDestroy();
Core.scene = toScene; Core.setScene(toScene);
// 淡入新场景 // 淡入新场景
await this.fadeIn(overlay, duration / 2); await this.fadeIn(overlay, duration / 2);
@@ -382,7 +384,7 @@ class TransitionManager {
// 切换场景 // 切换场景
fromScene.onDestroy(); fromScene.onDestroy();
Core.scene = toScene; Core.setScene(toScene);
// 从相反方向滑入新场景 // 从相反方向滑入新场景
await this.slideScene(toScene, -slideDistance); await this.slideScene(toScene, -slideDistance);

View File

@@ -491,7 +491,7 @@ if (renderSystem) {
} }
// 设置为当前场景 // 设置为当前场景
Core.scene = scene; Core.setScene(scene;
``` ```
### 系统的启用和禁用 ### 系统的启用和禁用

View File

@@ -71,7 +71,7 @@ export class ECSManager extends Component {
const gameScene = new GameScene(); const gameScene = new GameScene();
// 3. 设置为当前场景会自动调用scene.begin() // 3. 设置为当前场景会自动调用scene.begin()
Core.scene = gameScene; Core.setScene(gameScene);
this.isInitialized = true; this.isInitialized = true;
// ECS框架初始化完成 // ECS框架初始化完成

4
package-lock.json generated
View File

@@ -11400,7 +11400,7 @@
}, },
"packages/core": { "packages/core": {
"name": "@esengine/ecs-framework", "name": "@esengine/ecs-framework",
"version": "2.1.31", "version": "2.1.34",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^28.0.3", "@rollup/plugin-commonjs": "^28.0.3",
@@ -11532,7 +11532,7 @@
}, },
"packages/network-shared": { "packages/network-shared": {
"name": "@esengine/ecs-framework-network-shared", "name": "@esengine/ecs-framework-network-shared",
"version": "1.0.14", "version": "1.0.15",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"protobufjs": "^7.5.3", "protobufjs": "^7.5.3",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@esengine/ecs-framework", "name": "@esengine/ecs-framework",
"version": "2.1.31", "version": "2.1.34",
"description": "用于Laya、Cocos Creator等JavaScript游戏引擎的高性能ECS框架", "description": "用于Laya、Cocos Creator等JavaScript游戏引擎的高性能ECS框架",
"type": "module", "type": "module",
"main": "bin/index.js", "main": "bin/index.js",

View File

@@ -205,11 +205,23 @@ export class Core {
} }
/** /**
* 设置当前活动的场景 * 设置当前场景(已废弃)
*
* @deprecated 请使用 Core.setScene() 方法代替。scene setter 可能导致场景延迟激活的时序问题,
* 而 setScene() 提供更好的类型安全性和可预测的激活时序。
*
* 迁移示例:
* ```typescript
* // 旧方式(已废弃)
* Core.scene = myScene;
*
* // 新方式(推荐)
* Core.setScene(myScene);
* ```
* *
* 如果当前没有场景,会立即切换;否则会在下一帧切换。 * 如果当前没有场景,会立即切换;否则会在下一帧切换。
* *
* @param value - 要设置的场景实例 * @param value - 场景实例
*/ */
public static set scene(value: IScene | null) { public static set scene(value: IScene | null) {
if (!value) return; if (!value) return;
@@ -222,10 +234,24 @@ export class Core {
} }
/** /**
* 类型安全的场景设置方法 * 类型安全的场景设置方法(推荐)
*
* 这是设置场景的推荐方法,提供更好的类型安全性和可预测的激活时序。
* 相比于 scene setter此方法能确保场景正确初始化和激活。
*
* 如果当前没有场景,会立即切换;否则会在下一帧切换。
* *
* @param scene - 要设置的场景实例 * @param scene - 要设置的场景实例
* @returns 设置的场景实例 * @returns 设置的场景实例,便于链式调用
*
* @example
* ```typescript
* const myScene = new MyScene();
* Core.setScene(myScene);
*
* // 链式调用
* const scene = Core.setScene(new MyScene()).addSystem(new MySystem());
* ```
*/ */
public static setScene<T extends IScene>(scene: T): T { public static setScene<T extends IScene>(scene: T): T {
if (this._instance._scene == null) { if (this._instance._scene == null) {
@@ -447,6 +473,7 @@ export class Core {
private setSceneInternal(scene: IScene): void { private setSceneInternal(scene: IScene): void {
this._scene = scene; this._scene = scene;
this.onSceneChanged(); this.onSceneChanged();
this._scene.initialize();
this._scene.begin(); this._scene.begin();
} }

View File

@@ -16,7 +16,7 @@ export interface IScene {
/** /**
* 场景名称 * 场景名称
*/ */
readonly name: string; name: string;
/** /**
* 场景中的实体集合 * 场景中的实体集合
@@ -147,10 +147,6 @@ export interface ISceneConfig {
* 场景名称 * 场景名称
*/ */
name?: string; name?: string;
/**
* 是否自动开始
*/
autoStart?: boolean;
/** /**
* 调试配置 * 调试配置
*/ */

View File

@@ -14,27 +14,6 @@ import { IScene, ISceneConfig } from './IScene';
* *
* 实现IScene接口提供场景的基础功能。 * 实现IScene接口提供场景的基础功能。
* 推荐使用组合而非继承的方式来构建自定义场景。 * 推荐使用组合而非继承的方式来构建自定义场景。
*
* @example
* ```typescript
* // 推荐的组合方式
* class GameScene implements IScene {
* private scene = new Scene();
*
* public initialize(): void {
* this.scene.initialize();
* // 自定义初始化逻辑
* }
* }
*
* // 仍然支持继承方式
* class GameScene extends Scene {
* public initialize(): void {
* super.initialize();
* // 自定义逻辑
* }
* }
* ```
*/ */
export class Scene implements IScene { export class Scene implements IScene {
/** /**
@@ -98,10 +77,6 @@ export class Scene implements IScene {
return this.entityProcessors.processors; return this.entityProcessors.processors;
} }
/**
* 是否已完成基础初始化
*/
private _isBaseInitialized = false;
/** /**
* 创建场景实例 * 创建场景实例
@@ -128,16 +103,6 @@ export class Scene implements IScene {
this.eventSystem.emitSync('component:added', data); this.eventSystem.emitSync('component:added', data);
}); });
} }
// 标记基础初始化完成
this._isBaseInitialized = true;
// 立即调用初始化,但确保在基础设施就绪后
this.initialize();
if (config?.autoStart) {
this.begin();
}
} }
/** /**
@@ -284,27 +249,6 @@ export class Scene implements IScene {
return entities; return entities;
} }
/**
* 批量创建实体
* @param count 要创建的实体数量
* @param namePrefix 实体名称前缀
* @returns 创建的实体列表
*/
public createEntitiesOld(count: number, namePrefix: string = "Entity"): Entity[] {
const entities: Entity[] = [];
// 批量创建实体,延迟缓存清理
for (let i = 0; i < count; i++) {
const entity = new Entity(`${namePrefix}_${i}`, this.identifierPool.checkOut());
entities.push(entity);
this.addEntity(entity, true); // 延迟缓存清理
}
// 最后统一清理缓存
this.querySystem.clearCache();
return entities;
}
/** /**
* 从场景中删除所有实体 * 从场景中删除所有实体

View File

@@ -137,6 +137,14 @@ describe('Core - 核心管理系统测试', () => {
expect(testScene.beginCalled).toBe(true); expect(testScene.beginCalled).toBe(true);
}); });
test('应该能够使用推荐的setScene方法设置场景', () => {
const scene = Core.setScene(testScene);
expect(Core.scene).toBe(testScene);
expect(testScene.beginCalled).toBe(true);
expect(scene).toBe(testScene); // 应该返回场景实例
});
test('设置新场景应该触发场景切换', () => { test('设置新场景应该触发场景切换', () => {
const firstScene = new TestScene(); const firstScene = new TestScene();
const secondScene = new TestScene(); const secondScene = new TestScene();

View File

@@ -142,6 +142,27 @@ describe('Scene - 场景管理系统测试', () => {
expect(scene.entities.count).toBe(0); expect(scene.entities.count).toBe(0);
expect(scene.entityProcessors.count).toBe(0); expect(scene.entityProcessors.count).toBe(0);
}); });
test('应该能够使用配置创建场景', () => {
const configScene = new Scene({ name: "ConfigScene" });
expect(configScene.name).toBe("ConfigScene");
});
test('应该能够获取调试信息', () => {
scene.name = "DebugScene";
scene.createEntity("TestEntity");
scene.addEntityProcessor(new MovementSystem());
const debugInfo = scene.getDebugInfo();
expect(debugInfo.name).toBe("Scene");
expect(debugInfo.entityCount).toBe(1);
expect(debugInfo.processorCount).toBe(1);
expect(debugInfo.isRunning).toBe(false);
expect(debugInfo.entities).toBeDefined();
expect(debugInfo.processors).toBeDefined();
expect(debugInfo.componentStats).toBeDefined();
});
}); });
describe('实体管理', () => { describe('实体管理', () => {
@@ -446,6 +467,19 @@ describe('Scene - 场景管理系统测试', () => {
expect(stats.queryStats.totalQueries).toBeGreaterThan(0); expect(stats.queryStats.totalQueries).toBeGreaterThan(0);
expect(parseFloat(stats.cacheStats.hitRate)).toBeGreaterThanOrEqual(0); expect(parseFloat(stats.cacheStats.hitRate)).toBeGreaterThanOrEqual(0);
}); });
test('应该能够压缩组件存储', () => {
// 创建一些实体和组件
const entities = scene.createEntities(10, "Entity");
entities.forEach(entity => {
entity.addComponent(new PositionComponent(Math.random() * 100, Math.random() * 100));
});
// 压缩组件存储应该不抛出异常
expect(() => {
scene.compactComponentStorage();
}).not.toThrow();
});
}); });
describe('内存管理和性能', () => { describe('内存管理和性能', () => {