Files
esengine/packages/network/src/Core/SyncVarManager.ts

222 lines
6.3 KiB
TypeScript
Raw Normal View History

/**
*
*
* SyncVar
*/
import { createLogger } from '@esengine/ecs-framework';
import { NetworkBehaviour } from '../NetworkBehaviour';
import { getSyncVarMetadata, SYNCVAR_METADATA_KEY } from '../decorators/SyncVar';
import { SyncVarMessage, SyncVarMetadata } from '../Types/NetworkTypes';
const logger = createLogger('SyncVarManager');
/**
* SyncVar
*/
interface SyncVarChange {
networkId: number;
componentType: string;
propertyName: string;
oldValue: any;
newValue: any;
timestamp: number;
}
export class SyncVarManager {
private static _instance: SyncVarManager | null = null;
/** 待同步的变化列表 */
private pendingChanges: SyncVarChange[] = [];
/** 已注册的网络组件实例 */
private registeredComponents: Map<string, NetworkBehaviour[]> = new Map();
public static get instance(): SyncVarManager {
if (!SyncVarManager._instance) {
SyncVarManager._instance = new SyncVarManager();
}
return SyncVarManager._instance;
}
private constructor() {}
/**
* SyncVar
*/
public registerComponent(component: NetworkBehaviour): void {
const componentType = component.constructor.name;
// 获取 SyncVar 元数据
const metadata = getSyncVarMetadata(component.constructor);
if (metadata.length === 0) {
return; // 没有 SyncVar无需处理
}
// 添加到注册列表
if (!this.registeredComponents.has(componentType)) {
this.registeredComponents.set(componentType, []);
}
this.registeredComponents.get(componentType)!.push(component);
// 为组件添加变化通知方法
this.addSyncVarSupport(component, metadata);
logger.debug(`注册网络组件: ${componentType},包含 ${metadata.length} 个 SyncVar`);
}
/**
*
*/
public unregisterComponent(component: NetworkBehaviour): void {
const componentType = component.constructor.name;
const components = this.registeredComponents.get(componentType);
if (components) {
const index = components.indexOf(component);
if (index !== -1) {
components.splice(index, 1);
}
if (components.length === 0) {
this.registeredComponents.delete(componentType);
}
}
logger.debug(`注销网络组件: ${componentType}`);
}
/**
* SyncVar
*/
public handleSyncVarMessage(message: SyncVarMessage): void {
const components = this.registeredComponents.get(message.componentType);
if (!components) {
logger.warn(`收到未知组件类型的 SyncVar 消息: ${message.componentType}`);
return;
}
// 找到对应的网络对象
const targetComponent = components.find(c => c.networkId === message.networkId);
if (!targetComponent) {
logger.warn(`找不到网络ID为 ${message.networkId} 的组件: ${message.componentType}`);
return;
}
// 应用同步值
this.applySyncVar(targetComponent, message.propertyName, message.value);
}
/**
* SyncVar
*/
public getPendingMessages(): SyncVarMessage[] {
const messages: SyncVarMessage[] = [];
for (const change of this.pendingChanges) {
messages.push({
type: 'syncvar',
networkId: change.networkId,
componentType: change.componentType,
propertyName: change.propertyName,
value: change.newValue,
data: change.newValue,
timestamp: change.timestamp
});
}
// 清空待同步列表
this.pendingChanges.length = 0;
return messages;
}
/**
* SyncVar
*/
private addSyncVarSupport(component: NetworkBehaviour, metadata: SyncVarMetadata[]): void {
// 添加变化通知方法
(component as any).notifySyncVarChanged = (propertyName: string, oldValue: any, newValue: any) => {
this.onSyncVarChanged(component, propertyName, oldValue, newValue, metadata);
};
}
/**
* SyncVar
*/
private onSyncVarChanged(
component: NetworkBehaviour,
propertyName: string,
oldValue: any,
newValue: any,
metadata: SyncVarMetadata[]
): void {
// 找到对应的元数据
const syncVarMeta = metadata.find(m => m.propertyName === propertyName);
if (!syncVarMeta) {
return;
}
// 权限检查
if (syncVarMeta.authorityOnly && !component.hasAuthority) {
logger.warn(`权限不足,无法修改 SyncVar: ${component.constructor.name}.${propertyName}`);
// 回滚值
(component as any)[`_${propertyName}`] = oldValue;
return;
}
// 记录变化
const change: SyncVarChange = {
networkId: component.networkId,
componentType: component.constructor.name,
propertyName,
oldValue,
newValue,
timestamp: Date.now()
};
this.pendingChanges.push(change);
logger.debug(`SyncVar 变化: ${change.componentType}.${propertyName} = ${newValue}`);
}
/**
*
*/
private applySyncVar(component: NetworkBehaviour, propertyName: string, value: any): void {
try {
// 直接设置内部值,跳过 setter 的权限检查
(component as any)[`_${propertyName}`] = value;
// 获取并调用变化回调
const metadata = getSyncVarMetadata(component.constructor);
const syncVarMeta = metadata.find(m => m.propertyName === propertyName);
if (syncVarMeta?.onChanged && typeof (component as any)[syncVarMeta.onChanged] === 'function') {
(component as any)[syncVarMeta.onChanged](undefined, value);
}
logger.debug(`应用 SyncVar: ${component.constructor.name}.${propertyName} = ${value}`);
} catch (error) {
logger.error(`应用 SyncVar 失败: ${component.constructor.name}.${propertyName}`, error);
}
}
/**
*
*/
public clearPendingChanges(): void {
this.pendingChanges.length = 0;
}
/**
*
*/
public getStats() {
return {
registeredComponents: this.registeredComponents.size,
pendingChanges: this.pendingChanges.length,
totalInstances: Array.from(this.registeredComponents.values())
.reduce((sum, components) => sum + components.length, 0)
};
}
}