Merge remote-tracking branch 'origin/master' into issue-94-响应式查询(Reactive_Query_System)/_Event-driven_Query
This commit is contained in:
@@ -15,7 +15,7 @@ import { IncrementalSerializer, IncrementalSnapshot, IncrementalSerializationOpt
|
||||
import { ComponentPoolManager } from './Core/ComponentPool';
|
||||
import { PerformanceMonitor } from '../Utils/PerformanceMonitor';
|
||||
import { ServiceContainer, type ServiceType } from '../Core/ServiceContainer';
|
||||
import { createInstance, isInjectable } from '../Core/DI';
|
||||
import { createInstance, isInjectable, injectProperties } from '../Core/DI';
|
||||
import { isUpdatable, getUpdatableMetadata } from '../Core/DI/Decorators';
|
||||
import { createLogger } from '../Utils/Logger';
|
||||
|
||||
@@ -578,6 +578,8 @@ export class Scene implements IScene {
|
||||
|
||||
this._services.registerInstance(constructor, system);
|
||||
|
||||
injectProperties(system, this._services);
|
||||
|
||||
system.initialize();
|
||||
|
||||
return system;
|
||||
@@ -742,10 +744,10 @@ export class Scene implements IScene {
|
||||
/**
|
||||
* 序列化场景
|
||||
*
|
||||
* 将场景及其所有实体、组件序列化为JSON字符串或二进制Buffer
|
||||
* 将场景及其所有实体、组件序列化为JSON字符串或二进制Uint8Array
|
||||
*
|
||||
* @param options 序列化选项
|
||||
* @returns 序列化后的数据(JSON字符串或二进制Buffer)
|
||||
* @returns 序列化后的数据(JSON字符串或二进制Uint8Array)
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
@@ -761,7 +763,7 @@ export class Scene implements IScene {
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
public serialize(options?: SceneSerializationOptions): string | Buffer {
|
||||
public serialize(options?: SceneSerializationOptions): string | Uint8Array {
|
||||
return SceneSerializer.serialize(this, options);
|
||||
}
|
||||
|
||||
@@ -770,7 +772,7 @@ export class Scene implements IScene {
|
||||
*
|
||||
* 从序列化数据恢复场景状态
|
||||
*
|
||||
* @param saveData 序列化的数据(JSON字符串或二进制Buffer)
|
||||
* @param saveData 序列化的数据(JSON字符串或二进制Uint8Array)
|
||||
* @param options 反序列化选项
|
||||
*
|
||||
* @example
|
||||
@@ -786,7 +788,7 @@ export class Scene implements IScene {
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
public deserialize(saveData: string | Buffer, options?: SceneDeserializationOptions): void {
|
||||
public deserialize(saveData: string | Uint8Array, options?: SceneDeserializationOptions): void {
|
||||
SceneSerializer.deserialize(this, saveData, options);
|
||||
}
|
||||
|
||||
@@ -858,7 +860,7 @@ export class Scene implements IScene {
|
||||
/**
|
||||
* 应用增量变更到场景
|
||||
*
|
||||
* @param incremental 增量快照数据(IncrementalSnapshot对象、JSON字符串或二进制Buffer)
|
||||
* @param incremental 增量快照数据(IncrementalSnapshot对象、JSON字符串或二进制Uint8Array)
|
||||
* @param componentRegistry 组件类型注册表(可选,默认使用全局注册表)
|
||||
*
|
||||
* @example
|
||||
@@ -870,21 +872,20 @@ export class Scene implements IScene {
|
||||
* const jsonData = IncrementalSerializer.serializeIncremental(snapshot, { format: 'json' });
|
||||
* scene.applyIncremental(jsonData);
|
||||
*
|
||||
* // 从二进制Buffer应用
|
||||
* // 从二进制Uint8Array应用
|
||||
* const binaryData = IncrementalSerializer.serializeIncremental(snapshot, { format: 'binary' });
|
||||
* scene.applyIncremental(binaryData);
|
||||
* ```
|
||||
*/
|
||||
public applyIncremental(
|
||||
incremental: IncrementalSnapshot | string | Buffer,
|
||||
incremental: IncrementalSnapshot | string | Uint8Array,
|
||||
componentRegistry?: Map<string, any>
|
||||
): void {
|
||||
const isSerializedData = typeof incremental === 'string' ||
|
||||
(typeof Buffer !== 'undefined' && Buffer.isBuffer(incremental)) ||
|
||||
incremental instanceof Uint8Array;
|
||||
|
||||
const snapshot = isSerializedData
|
||||
? IncrementalSerializer.deserializeIncremental(incremental as string | Buffer)
|
||||
? IncrementalSerializer.deserializeIncremental(incremental as string | Uint8Array)
|
||||
: incremental as IncrementalSnapshot;
|
||||
|
||||
const registry = componentRegistry || ComponentRegistry.getAllComponentNames() as Map<string, any>;
|
||||
|
||||
@@ -3,10 +3,7 @@ import { ECSFluentAPI, createECSAPI } from './Core/FluentAPI';
|
||||
import { Time } from '../Utils/Time';
|
||||
import { createLogger } from '../Utils/Logger';
|
||||
import type { IService } from '../Core/ServiceContainer';
|
||||
import type { IUpdatable } from '../Types/IUpdatable';
|
||||
import { World } from './World';
|
||||
import { WorldManager } from './WorldManager';
|
||||
import { Injectable, Inject, Updatable } from '../Core/DI';
|
||||
|
||||
/**
|
||||
* 单场景管理器
|
||||
@@ -21,13 +18,15 @@ import { Injectable, Inject, Updatable } from '../Core/DI';
|
||||
* - 简单直观的API
|
||||
* - 支持延迟场景切换
|
||||
* - 自动管理ECS API
|
||||
* - 通过依赖注入获取WorldManager的默认World
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 初始化Core
|
||||
* Core.create({ debug: true });
|
||||
*
|
||||
* // 创建场景管理器
|
||||
* const sceneManager = new SceneManager();
|
||||
*
|
||||
* // 设置场景
|
||||
* class GameScene extends Scene {
|
||||
* initialize() {
|
||||
@@ -36,22 +35,21 @@ import { Injectable, Inject, Updatable } from '../Core/DI';
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* Core.setScene(new GameScene());
|
||||
* sceneManager.setScene(new GameScene());
|
||||
*
|
||||
* // 游戏循环
|
||||
* function gameLoop(deltaTime: number) {
|
||||
* Core.update(deltaTime); // 自动更新所有服务(包括SceneManager)
|
||||
* Core.update(deltaTime); // 更新全局服务
|
||||
* sceneManager.update(); // 更新场景
|
||||
* }
|
||||
*
|
||||
* // 延迟切换场景(下一帧生效)
|
||||
* Core.loadScene(new MenuScene());
|
||||
* sceneManager.loadScene(new MenuScene());
|
||||
* ```
|
||||
*/
|
||||
@Injectable()
|
||||
@Updatable(10)
|
||||
export class SceneManager implements IService, IUpdatable {
|
||||
export class SceneManager implements IService {
|
||||
/**
|
||||
* 内部默认World(从WorldManager获取)
|
||||
* 内部默认World
|
||||
*/
|
||||
private _defaultWorld: World;
|
||||
|
||||
@@ -80,18 +78,9 @@ export class SceneManager implements IService, IUpdatable {
|
||||
*/
|
||||
private static readonly DEFAULT_SCENE_ID = '__main__';
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
* WorldManager通过依赖注入自动传入
|
||||
*
|
||||
* @param worldManager WorldManager实例,用于获取默认World
|
||||
*/
|
||||
constructor(
|
||||
@Inject(WorldManager) worldManager: WorldManager
|
||||
) {
|
||||
// 使用WorldManager管理的默认World
|
||||
this._defaultWorld = worldManager.getDefaultWorld();
|
||||
constructor() {
|
||||
this._defaultWorld = new World({ name: '__default__' });
|
||||
this._defaultWorld.start();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Component } from '../Component';
|
||||
import { ComponentSerializer, SerializedComponent } from './ComponentSerializer';
|
||||
import { SerializedEntity } from './EntitySerializer';
|
||||
import { ComponentType } from '../Core/ComponentStorage';
|
||||
import * as msgpack from 'msgpack-lite';
|
||||
import { encode, decode } from '@msgpack/msgpack';
|
||||
|
||||
/**
|
||||
* 变更操作类型
|
||||
@@ -609,7 +609,7 @@ export class IncrementalSerializer {
|
||||
*
|
||||
* @param incremental 增量快照
|
||||
* @param options 序列化选项
|
||||
* @returns 序列化后的数据(JSON字符串或二进制Buffer)
|
||||
* @returns 序列化后的数据(JSON字符串或二进制Uint8Array)
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
@@ -631,7 +631,7 @@ export class IncrementalSerializer {
|
||||
public static serializeIncremental(
|
||||
incremental: IncrementalSnapshot,
|
||||
options?: { format?: IncrementalSerializationFormat; pretty?: boolean }
|
||||
): string | Buffer {
|
||||
): string | Uint8Array {
|
||||
const opts = {
|
||||
format: 'json' as IncrementalSerializationFormat,
|
||||
pretty: false,
|
||||
@@ -639,7 +639,7 @@ export class IncrementalSerializer {
|
||||
};
|
||||
|
||||
if (opts.format === 'binary') {
|
||||
return msgpack.encode(incremental);
|
||||
return encode(incremental);
|
||||
} else {
|
||||
return opts.pretty
|
||||
? JSON.stringify(incremental, null, 2)
|
||||
@@ -650,7 +650,7 @@ export class IncrementalSerializer {
|
||||
/**
|
||||
* 反序列化增量快照
|
||||
*
|
||||
* @param data 序列化的数据(JSON字符串或二进制Buffer)
|
||||
* @param data 序列化的数据(JSON字符串或二进制Uint8Array)
|
||||
* @returns 增量快照
|
||||
*
|
||||
* @example
|
||||
@@ -662,13 +662,13 @@ export class IncrementalSerializer {
|
||||
* const snapshot = IncrementalSerializer.deserializeIncremental(buffer);
|
||||
* ```
|
||||
*/
|
||||
public static deserializeIncremental(data: string | Buffer): IncrementalSnapshot {
|
||||
public static deserializeIncremental(data: string | Uint8Array): IncrementalSnapshot {
|
||||
if (typeof data === 'string') {
|
||||
// JSON格式
|
||||
return JSON.parse(data);
|
||||
} else {
|
||||
// 二进制格式(MessagePack)
|
||||
return msgpack.decode(data);
|
||||
return decode(data) as IncrementalSnapshot;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ComponentType, ComponentRegistry } from '../Core/ComponentStorage';
|
||||
import { EntitySerializer, SerializedEntity } from './EntitySerializer';
|
||||
import { getComponentTypeName } from '../Decorators';
|
||||
import { getSerializationMetadata } from './SerializationDecorators';
|
||||
import * as msgpack from 'msgpack-lite';
|
||||
import { encode, decode } from '@msgpack/msgpack';
|
||||
|
||||
/**
|
||||
* 场景序列化格式
|
||||
@@ -154,9 +154,9 @@ export class SceneSerializer {
|
||||
*
|
||||
* @param scene 要序列化的场景
|
||||
* @param options 序列化选项
|
||||
* @returns 序列化后的数据(JSON字符串或二进制Buffer)
|
||||
* @returns 序列化后的数据(JSON字符串或二进制Uint8Array)
|
||||
*/
|
||||
public static serialize(scene: IScene, options?: SceneSerializationOptions): string | Buffer {
|
||||
public static serialize(scene: IScene, options?: SceneSerializationOptions): string | Uint8Array {
|
||||
const opts: SceneSerializationOptions = {
|
||||
systems: false,
|
||||
format: 'json',
|
||||
@@ -207,7 +207,7 @@ export class SceneSerializer {
|
||||
: JSON.stringify(serializedScene);
|
||||
} else {
|
||||
// 二进制格式(使用 MessagePack)
|
||||
return msgpack.encode(serializedScene);
|
||||
return encode(serializedScene);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,12 +215,12 @@ export class SceneSerializer {
|
||||
* 反序列化场景
|
||||
*
|
||||
* @param scene 目标场景
|
||||
* @param saveData 序列化的数据(JSON字符串或二进制Buffer)
|
||||
* @param saveData 序列化的数据(JSON字符串或二进制Uint8Array)
|
||||
* @param options 反序列化选项
|
||||
*/
|
||||
public static deserialize(
|
||||
scene: IScene,
|
||||
saveData: string | Buffer,
|
||||
saveData: string | Uint8Array,
|
||||
options?: SceneDeserializationOptions
|
||||
): void {
|
||||
const opts: SceneDeserializationOptions = {
|
||||
@@ -237,7 +237,7 @@ export class SceneSerializer {
|
||||
serializedScene = JSON.parse(saveData);
|
||||
} else {
|
||||
// 二进制格式(MessagePack)
|
||||
serializedScene = msgpack.decode(saveData);
|
||||
serializedScene = decode(saveData) as SerializedScene;
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to parse save data: ${error}`);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { World, IWorldConfig } from './World';
|
||||
import { createLogger } from '../Utils/Logger';
|
||||
import type { IService } from '../Core/ServiceContainer';
|
||||
import type { IUpdatable } from '../Types/IUpdatable';
|
||||
import { Injectable, Updatable } from '../Core/DI';
|
||||
|
||||
const logger = createLogger('WorldManager');
|
||||
|
||||
@@ -14,28 +12,21 @@ export interface IWorldManagerConfig {
|
||||
* 最大World数量
|
||||
*/
|
||||
maxWorlds?: number;
|
||||
|
||||
|
||||
/**
|
||||
* 是否自动清理空World
|
||||
*/
|
||||
autoCleanup?: boolean;
|
||||
|
||||
|
||||
/**
|
||||
* 清理间隔(毫秒)
|
||||
*/
|
||||
cleanupInterval?: number;
|
||||
|
||||
|
||||
/**
|
||||
* 是否启用调试模式
|
||||
*/
|
||||
debug?: boolean;
|
||||
|
||||
/**
|
||||
* 是否创建默认World(默认true)
|
||||
*
|
||||
* 当通过Core使用时应该为true,直接使用WorldManager时可设为false
|
||||
*/
|
||||
createDefaultWorld?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,18 +57,12 @@ export interface IWorldManagerConfig {
|
||||
*
|
||||
* // 游戏循环
|
||||
* function gameLoop(deltaTime: number) {
|
||||
* Core.update(deltaTime); // 自动更新所有@Updatable服务(包括WorldManager)
|
||||
* Core.update(deltaTime);
|
||||
* worldManager.updateAll(); // 更新所有活跃World
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
@Injectable()
|
||||
@Updatable(5)
|
||||
export class WorldManager implements IService, IUpdatable {
|
||||
/**
|
||||
* 默认World的ID
|
||||
*/
|
||||
public static readonly DEFAULT_WORLD_ID = '__default__';
|
||||
|
||||
export class WorldManager implements IService {
|
||||
private readonly _config: IWorldManagerConfig;
|
||||
private readonly _worlds: Map<string, World> = new Map();
|
||||
private readonly _activeWorlds: Set<string> = new Set();
|
||||
@@ -90,26 +75,16 @@ export class WorldManager implements IService, IUpdatable {
|
||||
autoCleanup: true,
|
||||
cleanupInterval: 30000, // 30秒
|
||||
debug: false,
|
||||
createDefaultWorld: true, // 默认创建
|
||||
...config
|
||||
};
|
||||
|
||||
// 默认启动运行状态
|
||||
this._isRunning = true;
|
||||
|
||||
// 如果配置要求,创建并注册默认World
|
||||
if (this._config.createDefaultWorld) {
|
||||
const defaultWorld = new World({ name: WorldManager.DEFAULT_WORLD_ID });
|
||||
this._worlds.set(WorldManager.DEFAULT_WORLD_ID, defaultWorld);
|
||||
this._activeWorlds.add(WorldManager.DEFAULT_WORLD_ID);
|
||||
defaultWorld.start();
|
||||
}
|
||||
|
||||
logger.info('WorldManager已初始化', {
|
||||
maxWorlds: this._config.maxWorlds,
|
||||
autoCleanup: this._config.autoCleanup,
|
||||
cleanupInterval: this._config.cleanupInterval,
|
||||
defaultWorldCreated: this._config.createDefaultWorld
|
||||
cleanupInterval: this._config.cleanupInterval
|
||||
});
|
||||
|
||||
this.startCleanupTimer();
|
||||
@@ -117,22 +92,6 @@ export class WorldManager implements IService, IUpdatable {
|
||||
|
||||
// ===== World管理 =====
|
||||
|
||||
/**
|
||||
* 获取默认World
|
||||
*
|
||||
* 默认World由WorldManager自动创建,供SceneManager使用。
|
||||
* 此方法主要供SceneManager内部使用。
|
||||
*
|
||||
* @returns 默认World实例
|
||||
*/
|
||||
public getDefaultWorld(): World {
|
||||
const defaultWorld = this._worlds.get(WorldManager.DEFAULT_WORLD_ID);
|
||||
if (!defaultWorld) {
|
||||
throw new Error('默认World不存在,这不应该发生');
|
||||
}
|
||||
return defaultWorld;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建新World
|
||||
*/
|
||||
@@ -164,16 +123,8 @@ export class WorldManager implements IService, IUpdatable {
|
||||
|
||||
/**
|
||||
* 移除World
|
||||
*
|
||||
* 注意:默认World不能被删除
|
||||
*/
|
||||
public removeWorld(worldId: string): boolean {
|
||||
// 防止删除默认World
|
||||
if (worldId === WorldManager.DEFAULT_WORLD_ID) {
|
||||
logger.warn('无法删除默认World');
|
||||
return false;
|
||||
}
|
||||
|
||||
const world = this._worlds.get(worldId);
|
||||
if (!world) {
|
||||
return false;
|
||||
@@ -246,12 +197,18 @@ export class WorldManager implements IService, IUpdatable {
|
||||
/**
|
||||
* 更新所有活跃的World
|
||||
*
|
||||
* 此方法由ServiceContainer自动调用(@Updatable装饰器)
|
||||
* 应该在每帧的游戏循环中调用。
|
||||
* 会自动更新所有活跃World的全局系统和场景。
|
||||
*
|
||||
* @param deltaTime 帧时间间隔(未使用,保留用于接口兼容)
|
||||
* @example
|
||||
* ```typescript
|
||||
* function gameLoop(deltaTime: number) {
|
||||
* Core.update(deltaTime); // 更新全局服务
|
||||
* worldManager.updateAll(); // 更新所有World
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
public update(deltaTime?: number): void {
|
||||
public updateAll(): void {
|
||||
if (!this._isRunning) return;
|
||||
|
||||
for (const worldId of this._activeWorlds) {
|
||||
|
||||
Reference in New Issue
Block a user