Files
esengine/packages/network/src/SyncVar/SyncVarFactory.ts

84 lines
2.6 KiB
TypeScript
Raw Normal View History

import { createSyncVarProxy } from './SyncVarProxy';
import { getSyncVarMetadata } from './SyncVarDecorator';
import { INetworkSyncable } from '../types/NetworkTypes';
import { createLogger } from '@esengine/ecs-framework';
/**
* SyncVar工厂函数
*
* NetworkComponent创建带有SyncVar代理的实例
* TypeScript类构造函数不能直接返回代理对象
*/
/**
* SyncVar支持的NetworkComponent实例
*
* @param ComponentClass -
* @param args -
* @returns
*/
const logger = createLogger('SyncVarFactory');
export function createNetworkComponent<T extends INetworkSyncable>(
ComponentClass: new (...args: any[]) => T,
...args: any[]
): T {
// 创建组件实例
const instance = new ComponentClass(...args);
// 检查是否有SyncVar字段
const metadata = getSyncVarMetadata(ComponentClass);
if (metadata.length === 0) {
// 没有SyncVar直接返回原实例
return instance;
}
// 创建代理包装实例
const proxy = createSyncVarProxy(instance, {
debugLog: false // 可以根据需要启用调试
});
logger.debug(`${ComponentClass.name} 创建了SyncVar代理包含 ${metadata.length} 个同步字段`);
return proxy;
}
/**
* SyncVar组件装饰器
*
* SyncVar支持
* TypeScript装饰器的限制
*
* @param options -
*/
export function NetworkComponentWithSyncVar(options: { debugLog?: boolean } = {}) {
return function <T extends new (...args: any[]) => INetworkSyncable>(constructor: T) {
return class extends constructor {
constructor(...args: any[]) {
super(...args);
// 检查是否需要创建代理
const metadata = getSyncVarMetadata(constructor);
if (metadata.length > 0) {
// 返回代理实例
return createSyncVarProxy(this as INetworkSyncable, {
debugLog: options.debugLog || false
}) as this;
}
return this;
}
} as T;
};
}
/**
* 便使SyncVar工厂创建
*
* @param instance -
* @returns 使SyncVar工厂
*/
export function isNetworkComponentWithSyncVar(instance: any): boolean {
return instance && (instance._syncVarProxied === true || instance.hasSyncVars?.() === true);
}