import { CoroutineV2 } from "../CatanEngine/CoroutineV2/CoroutineV2"; import { ActionWithType } from "../CatanEngine/CSharp/System/ActionWithType"; import { NumberEx } from "../Utils/Number/NumberEx"; class TimerEvent extends ActionWithType { } /** * 計時器(使用CoroutineV2) */ export class Timer { //#region public /** 訊息資料 */ public static Component: cc.Component; //#endregion //#region private /** 訊息資料 */ private static Group: Map = new Map(); //#endregion //#region static /** * 啟動計時 * @param {number} time 計時(seconds) * @param {Function} callback Function * @param {any} type (選填) 可以識別的東西 * @param {any} bindTarget (選填) 回呼時this綁定的對象 * @example * Timer.Start(1, () => { console.log(`example`); }); * Timer.Start(1, () => { console.log(`example`); }, "example"); * Timer.Start(1, () => { console.log(`example`); }, "example", this); */ public static Start(time: number, callback: Function, bindTarget?: any, type?: any): void { let self: typeof Timer = this; let thistype: any = type; if (!type) { thistype = callback; } if (Timer.Group.has(thistype)) { cc.error(`Timer Start Error Timer.Group.has(${thistype})`); return; } let timerData: TimerDataClass = new TimerDataClass(thistype, time, callback, bindTarget); Timer.Group.set(thistype, timerData); let Coroutine_F: Generator = function* (): Generator { yield CoroutineV2.WaitTime(time).Start(bindTarget); if (Timer.Group.has(thistype)) { self._callback(timerData.Type, timerData.Callback, timerData.BindTarget); } }(); CoroutineV2.Single(Coroutine_F).Start(bindTarget); } /** * 刪除計時 By Target * @param {any} target target * @example * Timer.ClearByTarget(this); */ public static ClearByTarget(target: any): void { let timerData_Group: TimerDataClass[] = []; Timer.Group.forEach(timerData => { if (timerData.BindTarget === target) { timerData_Group.push(timerData); } }); if (timerData_Group.length === 0) { cc.warn(`Timer Clear Error Timer.Group.has not target`); return; } for (let i: number = 0; i < timerData_Group.length; i++) { let timerData: TimerDataClass = timerData_Group[i]; let type: any = timerData.Type; Timer.Group.delete(type); timerData = null; } CoroutineV2.StopCoroutinesBy(target); } /** * 刪除計時 By Type * @param PS 還是會吃效能在倒數 只是時間到不會執行 * @param {any} type type * @example * Timer.ClearByType("example"); */ public static ClearByType(type: any): void { let timerData_Group: TimerDataClass[] = []; Timer.Group.forEach(timerData => { if (timerData.Type === type) { timerData_Group.push(timerData); } }); if (timerData_Group.length === 0) { cc.warn(`Timer Clear Error Timer.Group.has not type`); return; } for (let i: number = 0; i < timerData_Group.length; i++) { let timerData: TimerDataClass = timerData_Group[i]; let type: any = timerData.Type; Timer.Group.delete(type); } } /** * 結束計時時callback * @param {Function} callback Function */ private static _callback(type: any, callback: Function, bindTarget: any): void { if (Timer.Group.has(type)) { Timer.Group.delete(type); } if (bindTarget) { callback.bind(bindTarget)(); } else { callback(); } } /** * 定時事件(時間用 updateTime秒跑一次fn) * @param startNum 起始index * @param endNum 結束index * @param updateTime 事件刷新間隔 * @param callbackfn 事件 * @example * let startNum: number = 10; * let endNum: number = 0; * let updateTime: number = 1; * yield CoroutineV2.Single(Timer.Timing( * startNum, * endNum, * updateTime, * (x: number) => { * console.log(`x: ${x}`); * } * )).Start(this); */ public static *Timing(startNum: number, endNum: number, updateTime: number, callbackfn: Function): IterableIterator { let isIncrease: boolean = endNum >= startNum; let totalCount: number = Math.abs(endNum - startNum) + 1; let nowCount: number = NumberEx.divide(totalCount, updateTime); let diff: number = NumberEx.divide(totalCount, nowCount) * (isIncrease ? 1 : -1); let tempScore: number = startNum; callbackfn(startNum); while (true) { if (endNum !== tempScore) { yield CoroutineV2.WaitTime(updateTime); tempScore += diff; // 遞增 if (isIncrease && tempScore > endNum) { tempScore = endNum; } // 遞減 if (!isIncrease && tempScore < endNum) { tempScore = endNum; } callbackfn(Math.floor(tempScore)); } else { break; } } } //#endregion } //#region Class /** Timer資料 */ export class TimerDataClass { /** Type */ public Type: any = null; /** Time */ public Time: number = null; /** Callback */ public Callback: Function = null; /** BindTarget */ public BindTarget?: any = null; constructor(type: any, time: number, callback: Function, bindTarget?: any) { this.Type = type; this.Time = time; this.Callback = callback; this.BindTarget = bindTarget; } } // //#endregion