对ECS系统进行注释、移除JobSystem

This commit is contained in:
yhh
2023-03-13 17:46:16 +08:00
parent 78079252c9
commit 1adc5f1729
17 changed files with 936 additions and 837 deletions

View File

@@ -1,79 +1,103 @@
module es {
/**
* 用于池任何对象
*/
export class Pool {
private static _objectQueue: Map<any, any[]> = new Map();
private static _objectQueue = new Map<new () => any, any[]>();
/**
* 预热缓存使用最大的cacheCount对象填充缓存
* @param type
* @param cacheCount
* @param type 要预热的类型
* @param cacheCount 预热缓存数量
*/
public static warmCache<T>(type: new (...args) => T, cacheCount: number) {
public static warmCache<T>(type: new (...args: any[]) => T, cacheCount: number) {
this.checkCreate(type);
cacheCount -= this._objectQueue.get(type).length;
const queue = this._objectQueue.get(type);
cacheCount -= queue.length;
// 如果需要预热更多的对象,则创建并添加到缓存
if (cacheCount > 0) {
for (let i = 0; i < cacheCount; i++) {
this._objectQueue.get(type).push(new type());
queue.push(new type());
}
}
}
/**
* 将缓存修剪为cacheCount项目
* @param cacheCount
*/
* 将缓存修剪为cacheCount项目
* @param type 要修剪的类型
* @param cacheCount 修剪后的缓存数量
*/
public static trimCache<T>(type: new (...args) => T, cacheCount: number) {
this.checkCreate(type);
while (cacheCount > this._objectQueue.get(type).length)
this._objectQueue.get(type).splice(0, 1);
const objectQueue = this._objectQueue.get(type);
// 如果需要修剪缓存,则弹出多余的对象
while (cacheCount < objectQueue.length) {
objectQueue.pop();
}
}
/**
* 清除缓存
* @param type 要清除缓存的类型
*/
public static clearCache<T>(type: new (...args) => T) {
this.checkCreate(type);
this._objectQueue.get(type).length = 0;
const objectQueue = this._objectQueue.get(type);
// 清空缓存数组
objectQueue.length = 0;
}
/**
* 如果可以的话,从堆栈中弹出一个项
* 如果可以的话,从缓存中获取一个对象
* @param type 要获取的类型
*/
public static obtain<T>(type: new (...args) => T): T {
this.checkCreate(type);
if (this._objectQueue.get(type).length > 0)
return this._objectQueue.get(type).shift();
const objectQueue = this._objectQueue.get(type);
// 如果缓存中有对象,弹出一个并返回
if (objectQueue.length > 0) {
return objectQueue.pop();
}
// 如果没有缓存对象,则创建一个新的对象并返回
return new type() as T;
}
/**
* 将项推回堆栈
* @param obj
* 将对象推回缓存
* @param type 对象的类型
* @param obj 要推回的对象
*/
public static free<T>(type: new (...args) => T, obj: T) {
this.checkCreate(type);
this._objectQueue.get(type).push(obj);
const objectQueue = this._objectQueue.get(type);
// 将对象推回缓存
objectQueue.push(obj);
// 如果对象实现了IPoolable接口则调用reset方法重置对象
if (isIPoolable(obj)) {
obj["reset"]();
obj.reset();
}
}
private static checkCreate<T>(type: new (...args) => T) {
if (!this._objectQueue.has(type))
/**
* 检查缓存中是否已存在给定类型的对象池,如果不存在则创建一个
* @param type 要检查的类型
*/
private static checkCreate<T>(type: new (...args: any[]) => T) {
if (!this._objectQueue.has(type)) {
this._objectQueue.set(type, []);
}
}
}
export interface IPoolable {
/**
* 重置对象以供重用。对象引用应该为空,字段可以设置为默认值
*/
reset();
reset(): void;
}
export var isIPoolable = (props: any): props is IPoolable => typeof (props as IPoolable)['reset'] !== 'undefined';
export const isIPoolable = (props: any): props is IPoolable => {
return typeof props.reset === 'function';
};
}

View File

@@ -3,7 +3,7 @@ module es {
* CoroutineManager用于隐藏Coroutine所需数据的内部类
*/
export class CoroutineImpl implements ICoroutine, IPoolable {
public enumerator: Generator;
public enumerator;
/**
* 每当产生一个延迟它就会被添加到跟踪延迟的waitTimer中
@@ -50,11 +50,11 @@ module es {
* 立即停止并清除所有协程
*/
public clearAllCoroutines() {
for (let i = 0; i < this._unblockedCoroutines.length; i ++) {
for (let i = 0; i < this._unblockedCoroutines.length; i++) {
Pool.free(CoroutineImpl, this._unblockedCoroutines[i]);
}
for (let i = 0; i < this._shouldRunNextFrame.length; i ++) {
for (let i = 0; i < this._shouldRunNextFrame.length; i++) {
Pool.free(CoroutineImpl, this._shouldRunNextFrame[i]);
}
@@ -67,60 +67,72 @@ module es {
* Coroutine在每一帧调用Update之前被执行
* @param enumerator
*/
public startCoroutine(enumerator: any) {
// 找到或创建一个CoroutineImpl
let coroutine = Pool.obtain<CoroutineImpl>(CoroutineImpl);
public startCoroutine<T>(enumerator: Iterator<T> | (() => Iterator<T>)): CoroutineImpl | null {
const coroutine = this.getOrCreateCoroutine();
coroutine.prepareForUse();
coroutine.enumerator = typeof enumerator === 'function' ? enumerator() : enumerator;
// 设置coroutine并添加它
coroutine.enumerator = enumerator;
let shouldContinueCoroutine = this.tickCoroutine(coroutine);
if (this.tickCoroutine(coroutine)) {
this.addCoroutine(coroutine);
return coroutine;
}
if (!shouldContinueCoroutine)
return null;
return null;
}
private getOrCreateCoroutine(): CoroutineImpl {
const coroutine = Pool.obtain<CoroutineImpl>(CoroutineImpl);
coroutine.prepareForUse();
return coroutine;
}
private addCoroutine(coroutine: CoroutineImpl) {
if (this._isInUpdate)
this._shouldRunNextFrame.push(coroutine);
else
this._unblockedCoroutines.push(coroutine);
return coroutine;
}
public update() {
this._isInUpdate = true;
for (let i = 0; i < this._unblockedCoroutines.length; i++) {
let coroutine = this._unblockedCoroutines[i];
const unblockedCoroutines = this._unblockedCoroutines;
const shouldRunNextFrame = this._shouldRunNextFrame;
for (let i = unblockedCoroutines.length - 1; i >= 0; i--) {
const coroutine = unblockedCoroutines[i];
if (coroutine.isDone) {
Pool.free(CoroutineImpl, coroutine);
unblockedCoroutines.splice(i, 1);
continue;
}
if (coroutine.waitForCoroutine != null) {
if (coroutine.waitForCoroutine.isDone) {
const waitForCoroutine = coroutine.waitForCoroutine;
if (waitForCoroutine != null) {
if (waitForCoroutine.isDone) {
coroutine.waitForCoroutine = null;
} else {
this._shouldRunNextFrame.push(coroutine);
shouldRunNextFrame.push(coroutine);
continue;
}
}
if (coroutine.waitTimer > 0) {
const waitTimer = coroutine.waitTimer;
if (waitTimer > 0) {
// 递减然后再运行下一帧确保用适当的deltaTime递减
coroutine.waitTimer -= coroutine.useUnscaledDeltaTime ? Time.unscaledDeltaTime : Time.deltaTime;
this._shouldRunNextFrame.push(coroutine);
coroutine.waitTimer = waitTimer - (coroutine.useUnscaledDeltaTime ? Time.unscaledDeltaTime : Time.deltaTime);
shouldRunNextFrame.push(coroutine);
continue;
}
if (this.tickCoroutine(coroutine))
this._shouldRunNextFrame.push(coroutine);
if (this.tickCoroutine(coroutine)) {
shouldRunNextFrame.push(coroutine);
}
}
let linqCoroutines = new es.List(this._unblockedCoroutines);
linqCoroutines.clear();
linqCoroutines.addRange(this._shouldRunNextFrame);
this._shouldRunNextFrame.length = 0;
unblockedCoroutines.push(...shouldRunNextFrame);
shouldRunNextFrame.length = 0;
this._isInUpdate = false;
}
@@ -130,47 +142,57 @@ module es {
* @param coroutine
*/
public tickCoroutine(coroutine: CoroutineImpl) {
let chain = coroutine.enumerator.next();
if (chain.done || coroutine.isDone) {
const { enumerator } = coroutine;
const { value, done } = enumerator.next();
if (done || coroutine.isDone) {
// 当协程执行完或标记为结束时,回收协程实例并返回 false。
Pool.free(CoroutineImpl, coroutine);
return false;
}
if (chain.value == null) {
// 下一帧再运行
if (!value) {
// 如果下一帧没有指定任务,返回 true 让协程继续等待下一帧执行。
return true;
}
if (chain.value instanceof WaitForSeconds) {
coroutine.waitTimer = chain.value.waitTime;
if (value instanceof WaitForSeconds) {
// 如果下一帧需要等待指定时间,则记录等待时间并返回 true。
coroutine.waitTimer = value.waitTime;
return true;
}
if (typeof chain.value == 'number') {
coroutine.waitTimer = chain.value;
if (typeof value === 'number') {
// 如果下一帧需要等待指定时间,则记录等待时间并返回 true。
coroutine.waitTimer = value;
return true;
}
if (typeof chain.value == 'string') {
if (chain.value == 'break') {
if (typeof value === 'string') {
// 如果下一帧返回 'break',标记协程为结束并返回 false。
if (value === 'break') {
Pool.free(CoroutineImpl, coroutine);
return false;
}
// 否则返回 true 让协程继续等待下一帧执行。
return true;
}
if (typeof chain.value == 'function') {
coroutine.waitForCoroutine = this.startCoroutine(chain.value);
if (typeof value === 'function') {
// 如果下一帧需要等待另一个协程完成,启动并记录另一个协程实例,并返回 true。
coroutine.waitForCoroutine = this.startCoroutine(value);
return true;
}
if (chain.value instanceof CoroutineImpl) {
coroutine.waitForCoroutine = chain.value;
return true;
} else {
if (value instanceof CoroutineImpl) {
// 如果下一帧需要等待另一个协程完成,记录另一个协程实例,并返回 true。
coroutine.waitForCoroutine = value;
return true;
}
// 否则返回 true 让协程继续等待下一帧执行。
return true;
}
}
}

View File

@@ -19,11 +19,11 @@ module es {
*/
export class Emitter<T> {
private _messageTable: Map<T, FuncPack[]>;
constructor() {
this._messageTable = new Map<T, FuncPack[]>();
}
/**
* 开始监听项
* @param eventType 监听类型
@@ -31,16 +31,17 @@ module es {
* @param context 监听上下文
*/
public addObserver(eventType: T, handler: Function, context: any) {
let list: FuncPack[] = this._messageTable.get(eventType);
let list = this._messageTable.get(eventType);
if (!list) {
list = [];
this._messageTable.set(eventType, list);
}
Insist.isFalse(list.findIndex(funcPack => funcPack.func == handler) != -1, "您试图添加相同的观察者两次");
list.push(new FuncPack(handler, context));
if (!this.hasObserver(eventType, handler)) {
list.push(new FuncPack(handler, context));
}
}
/**
* 移除监听项
* @param eventType 事件类型
@@ -48,22 +49,35 @@ module es {
*/
public removeObserver(eventType: T, handler: Function) {
let messageData = this._messageTable.get(eventType);
let index = messageData.findIndex(data => data.func == handler);
if (index != -1)
messageData.splice(index, 1);
if (messageData) {
let index = messageData.findIndex(data => data.func == handler);
if (index != -1)
messageData.splice(index, 1);
}
}
/**
* 触发该事件
* @param eventType 事件类型
* @param data 事件数据
*/
public emit(eventType: T, ...data: any[]) {
let list: FuncPack[] = this._messageTable.get(eventType);
let list = this._messageTable.get(eventType);
if (list) {
for (let i = list.length - 1; i >= 0; i--)
list[i].func.call(list[i].context, ...data);
for (let observer of list) {
observer.func.call(observer.context, ...data);
}
}
}
/**
* 判断是否存在该类型的观察者
* @param eventType 事件类型
* @param handler 事件函数
*/
public hasObserver(eventType: T, handler: Function): boolean {
let list = this._messageTable.get(eventType);
return list ? list.some(observer => observer.func === handler) : false;
}
}
}