199 lines
6.2 KiB
TypeScript
199 lines
6.2 KiB
TypeScript
import { CoroutineV2 } from "../CatanEngine/CoroutineV2/CoroutineV2";
|
|
import { ActionWithType } from "../CatanEngine/CSharp/System/ActionWithType";
|
|
import { NumberEx } from "../Utils/Number/NumberEx";
|
|
|
|
class TimerEvent extends ActionWithType<number, any> { }
|
|
|
|
/**
|
|
* 計時器(使用CoroutineV2)
|
|
*/
|
|
export class Timer {
|
|
|
|
//#region public
|
|
|
|
/** 訊息資料 */
|
|
public static Component: cc.Component;
|
|
|
|
//#endregion
|
|
|
|
//#region private
|
|
|
|
/** 訊息資料 */
|
|
private static Group: Map<any, TimerDataClass> = new Map<any, TimerDataClass>();
|
|
|
|
//#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<any, void, any> = function* (): Generator<any, void, any> {
|
|
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<any> {
|
|
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
|