[add] Engine
This commit is contained in:
		
							
								
								
									
										12
									
								
								assets/Script/Engine/CatanEngine/CSharp.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								assets/Script/Engine/CatanEngine/CSharp.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.1.2",
 | 
			
		||||
  "uuid": "f9edb32f-c4ab-4e5d-8270-71fa609e1db7",
 | 
			
		||||
  "isBundle": false,
 | 
			
		||||
  "bundleName": "",
 | 
			
		||||
  "priority": 1,
 | 
			
		||||
  "compressionType": {},
 | 
			
		||||
  "optimizeHotUpdate": {},
 | 
			
		||||
  "inlineSpriteFrames": {},
 | 
			
		||||
  "isRemoteBundle": {},
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								assets/Script/Engine/CatanEngine/CSharp/String.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								assets/Script/Engine/CatanEngine/CSharp/String.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
interface StringConstructor {  
 | 
			
		||||
    IsNullOrEmpty: (value: string) => boolean;
 | 
			
		||||
    Format: (format: string, ...args: any[]) => string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String.IsNullOrEmpty = function (value: string): boolean {  
 | 
			
		||||
    return value === undefined || value === null || value.trim() === '';
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
String.Format = function (format: string, ...args: any[]): string {
 | 
			
		||||
    return format.replace(/{(\d+)}/g, (match, index) => {
 | 
			
		||||
        let value = args[index];
 | 
			
		||||
        if (value === null || value === undefined) return '';
 | 
			
		||||
        return '' + value;
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								assets/Script/Engine/CatanEngine/CSharp/String.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								assets/Script/Engine/CatanEngine/CSharp/String.ts.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "0c3d1ca6-bdaf-4a00-b209-6ef460802cdc",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								assets/Script/Engine/CatanEngine/CSharp/System.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								assets/Script/Engine/CatanEngine/CSharp/System.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.1.2",
 | 
			
		||||
  "uuid": "01b35dee-e6e0-4a6e-a73c-3b49c37f1c5f",
 | 
			
		||||
  "isBundle": false,
 | 
			
		||||
  "bundleName": "",
 | 
			
		||||
  "priority": 1,
 | 
			
		||||
  "compressionType": {},
 | 
			
		||||
  "optimizeHotUpdate": {},
 | 
			
		||||
  "inlineSpriteFrames": {},
 | 
			
		||||
  "isRemoteBundle": {},
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										125
									
								
								assets/Script/Engine/CatanEngine/CSharp/System/Action.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								assets/Script/Engine/CatanEngine/CSharp/System/Action.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,125 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 回呼函數: fnname (arg: TArg): void
 | 
			
		||||
 */
 | 
			
		||||
interface ActionCallback<TArg> {
 | 
			
		||||
    (arg: TArg): void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface Struct<TArg> {
 | 
			
		||||
    callback: ActionCallback<TArg>;
 | 
			
		||||
    target: any;
 | 
			
		||||
    once?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class Action<TArg> {
 | 
			
		||||
    private _queue: Struct<TArg>[] = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 監聽事件
 | 
			
		||||
     * @param callback 回呼函數: fnname (arg: TArg): void
 | 
			
		||||
     * @param bindTarget 回呼時this綁定的對象
 | 
			
		||||
     */
 | 
			
		||||
    AddCallback(callback: ActionCallback<TArg>, bindTarget?: any) {
 | 
			
		||||
        let q = <Struct<TArg>> {
 | 
			
		||||
            callback: callback,
 | 
			
		||||
            target: bindTarget
 | 
			
		||||
        };
 | 
			
		||||
        this._queue.push(q);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 監聽事件 (一次性)
 | 
			
		||||
     * @param callback 回呼函數: fnname (arg: TArg): void
 | 
			
		||||
     * @param bindTarget 回呼時this綁定的對象
 | 
			
		||||
     */
 | 
			
		||||
    AddCallbackOnce(callback: ActionCallback<TArg>, bindTarget?: any) {
 | 
			
		||||
        let q = <Struct<TArg>> {
 | 
			
		||||
            callback: callback,
 | 
			
		||||
            target: bindTarget,
 | 
			
		||||
            once: true
 | 
			
		||||
        };
 | 
			
		||||
        this._queue.push(q);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除事件
 | 
			
		||||
     * @param callback 
 | 
			
		||||
     */
 | 
			
		||||
    RemoveByCallback(callback: ActionCallback<TArg>) {
 | 
			
		||||
        let index = this._queue.length;
 | 
			
		||||
        if (index > 0) {
 | 
			
		||||
            while (index--) {
 | 
			
		||||
                let q = this._queue[index];
 | 
			
		||||
                if (!q.callback || q.callback === callback) {
 | 
			
		||||
                    q.callback = undefined;
 | 
			
		||||
                    this._queue.splice(index, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除事件
 | 
			
		||||
     * @param bindTarget 回呼時this綁定的對象
 | 
			
		||||
     */
 | 
			
		||||
    RemoveByBindTarget(bindTarget: any) {
 | 
			
		||||
        let index = this._queue.length;
 | 
			
		||||
        if (index > 0) {
 | 
			
		||||
            while (index--) {
 | 
			
		||||
                let q = this._queue[index];
 | 
			
		||||
                if (!q.callback || q.target === bindTarget) {
 | 
			
		||||
                    q.callback = undefined;
 | 
			
		||||
                    this._queue.splice(index, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除全部事件
 | 
			
		||||
     */
 | 
			
		||||
    RemoveAllCallbacks() {
 | 
			
		||||
        this._queue.forEach(q => q.callback = undefined);
 | 
			
		||||
        this._queue.length = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 發送事件
 | 
			
		||||
     * @param arg 參數
 | 
			
		||||
     */
 | 
			
		||||
    DispatchCallback(arg: TArg) {
 | 
			
		||||
        let index = this._queue.length;
 | 
			
		||||
        if (index > 0) {
 | 
			
		||||
            let cleanRemoved = false;
 | 
			
		||||
            this._queue.slice().forEach(q => {
 | 
			
		||||
                if (!q.callback) {
 | 
			
		||||
                    cleanRemoved = true;
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (q.target) {
 | 
			
		||||
                    q.callback.call(q.target, arg);
 | 
			
		||||
                } else {
 | 
			
		||||
                    q.callback(arg);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (q.once) {
 | 
			
		||||
                    q.callback = undefined;
 | 
			
		||||
                    cleanRemoved = true;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            if (cleanRemoved) {
 | 
			
		||||
                index = this._queue.length;
 | 
			
		||||
                if (index > 0) {
 | 
			
		||||
                    while (index--) {
 | 
			
		||||
                        let q = this._queue[index];
 | 
			
		||||
                        if (!q.callback) {
 | 
			
		||||
                            this._queue.splice(index, 1);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "ea9bf762-40a7-4bab-b949-8d5b3d4289e2",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,85 @@
 | 
			
		||||
import { Action } from "./Action";
 | 
			
		||||
import { ActionWithType } from "./ActionWithType";
 | 
			
		||||
import { ActionWithType2 } from "./ActionWithType2";
 | 
			
		||||
 | 
			
		||||
const {ccclass, property} = cc._decorator;
 | 
			
		||||
 | 
			
		||||
enum CustomType {
 | 
			
		||||
    Ex1, Ex2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class CustomEvent extends ActionWithType<CustomType, number> {}
 | 
			
		||||
class CustomEvent2 extends ActionWithType2<CustomType, number> {}
 | 
			
		||||
 | 
			
		||||
@ccclass
 | 
			
		||||
export default class NewClass extends cc.Component {
 | 
			
		||||
    callback: Action<number> = new Action<number>();
 | 
			
		||||
    customCallback: CustomEvent = new CustomEvent();
 | 
			
		||||
    customCallback2: CustomEvent2 = new CustomEvent2();
 | 
			
		||||
 | 
			
		||||
    private num: number = 0;
 | 
			
		||||
 | 
			
		||||
    start () {
 | 
			
		||||
        this.callback.AddCallback(this.CB, this);
 | 
			
		||||
        this.callback.AddCallbackOnce(this.OnceCB, this);
 | 
			
		||||
 | 
			
		||||
        this.customCallback.AddCallback(CustomType.Ex1, this.CBType, this);
 | 
			
		||||
        this.customCallback.AddCallbackOnce(CustomType.Ex2, this.OnceCBType, this);
 | 
			
		||||
 | 
			
		||||
        this.customCallback2.AddCallback(CustomType.Ex2, this.CBTypeAllin1, this);
 | 
			
		||||
        this.customCallback2.AddCallbackOnce(CustomType.Ex1, this.CBTypeAllin1, this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DispatchClick() {
 | 
			
		||||
        this.num++;
 | 
			
		||||
 | 
			
		||||
        this.callback.DispatchCallback(this.num);
 | 
			
		||||
 | 
			
		||||
        this.customCallback.DispatchCallback(CustomType.Ex1, this.num);
 | 
			
		||||
        this.customCallback.DispatchCallback(CustomType.Ex2, this.num);
 | 
			
		||||
 | 
			
		||||
        this.customCallback2.DispatchCallback(CustomType.Ex1, this.num);
 | 
			
		||||
        this.customCallback2.DispatchCallback(CustomType.Ex2, this.num);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    RemoveEventClick() {
 | 
			
		||||
        this.callback.RemoveByCallback(this.CB);
 | 
			
		||||
        // this.callback.RemoveByCallback(this.OnceCB);
 | 
			
		||||
        // this.callback.RemoveByBindTarget(this);
 | 
			
		||||
        // this.callback.RemoveAll();
 | 
			
		||||
 | 
			
		||||
        // this.callbackWithType.RemoveByCallback(this.CBType);
 | 
			
		||||
        // this.callbackWithType.RemoveByCallback(this.OnceCBType);
 | 
			
		||||
        this.customCallback.RemoveByType(CustomType.Ex1);
 | 
			
		||||
        // this.callbackWithType.RemoveByType(CustomType.Ex2);
 | 
			
		||||
        // this.callbackWithType.RemoveByBindTarget(this);
 | 
			
		||||
        // this.callbackWithType.RemoveAll();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    OnceCB(x: number) {
 | 
			
		||||
        cc.log(`OnceCB [${this.num}]`);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
    CB(x: number) {
 | 
			
		||||
        cc.log(`CB [${this.num}]`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    OnceCBType(x: number) {
 | 
			
		||||
        cc.log(`OnceCBType [${this.num}]`);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    CBType(x: number) {
 | 
			
		||||
        cc.log(`CBType [${this.num}]`);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    CBTypeAllin1(type: CustomType,x: number) {
 | 
			
		||||
        // switch (type) {
 | 
			
		||||
        //     case CustomType.Ex1:
 | 
			
		||||
        //         break;
 | 
			
		||||
        //     case CustomType.Ex2:
 | 
			
		||||
        //         break;
 | 
			
		||||
        // }
 | 
			
		||||
        
 | 
			
		||||
        cc.log(`CBTypeAllin1 [${CustomType[type]}][${this.num}]`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "cc645b73-6192-414d-a5bc-4220c24e322d",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										166
									
								
								assets/Script/Engine/CatanEngine/CSharp/System/ActionWithType.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								assets/Script/Engine/CatanEngine/CSharp/System/ActionWithType.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,166 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 回呼函數: fnname (arg: TArg): void
 | 
			
		||||
 */
 | 
			
		||||
interface ActionCallback<TArg> {
 | 
			
		||||
    (arg: TArg): void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface Struct<TType, TArg> {
 | 
			
		||||
    callback: ActionCallback<TArg>;
 | 
			
		||||
    target: any;
 | 
			
		||||
    type: TType;
 | 
			
		||||
    once?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ActionWithType<TType, TArg> {
 | 
			
		||||
    private _queue: Struct<TType, TArg>[] = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 監聽事件
 | 
			
		||||
     * @param callback 回呼函數: fnname (arg: TArg): void
 | 
			
		||||
     * @param bindTarget 回呼時this綁定的對象
 | 
			
		||||
     */
 | 
			
		||||
    AddCallback(type: TType, callback: ActionCallback<TArg>, bindTarget?: any) {
 | 
			
		||||
        let q = <Struct<TType, TArg>> {
 | 
			
		||||
            callback: callback,
 | 
			
		||||
            target: bindTarget,
 | 
			
		||||
            type: type
 | 
			
		||||
        };
 | 
			
		||||
        this._queue.push(q);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 監聽事件 (一次性)
 | 
			
		||||
     * @param callback 回呼函數: fnname (arg: TArg): void
 | 
			
		||||
     * @param bindTarget 回呼時this綁定的對象
 | 
			
		||||
     */
 | 
			
		||||
    AddCallbackOnce(type: TType, callback: ActionCallback<TArg>, bindTarget?: any) {
 | 
			
		||||
        let q = <Struct<TType, TArg>> {
 | 
			
		||||
            callback: callback,
 | 
			
		||||
            target: bindTarget,
 | 
			
		||||
            type: type,
 | 
			
		||||
            once: true
 | 
			
		||||
        };
 | 
			
		||||
        this._queue.push(q);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除事件
 | 
			
		||||
     * @param callback 
 | 
			
		||||
     */
 | 
			
		||||
    RemoveByCallback(callback: ActionCallback<TArg>) {
 | 
			
		||||
        let index = this._queue.length;
 | 
			
		||||
        if (index > 0) {
 | 
			
		||||
            while (index--) {
 | 
			
		||||
                let q = this._queue[index];
 | 
			
		||||
                if (!q.callback || q.callback === callback) {
 | 
			
		||||
                    q.callback = undefined;
 | 
			
		||||
                    this._queue.splice(index, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除事件
 | 
			
		||||
     * @param bindTarget 回呼時this綁定的對象
 | 
			
		||||
     */
 | 
			
		||||
    RemoveByBindTarget(bindTarget: any) {
 | 
			
		||||
        let index = this._queue.length;
 | 
			
		||||
        if (index > 0) {
 | 
			
		||||
            while (index--) {
 | 
			
		||||
                let q = this._queue[index];
 | 
			
		||||
                if (!q.callback || q.target === bindTarget) {
 | 
			
		||||
                    q.callback = undefined;
 | 
			
		||||
                    this._queue.splice(index, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除事件
 | 
			
		||||
     * @param type 事件類型
 | 
			
		||||
     */
 | 
			
		||||
    RemoveByType(type: TType) {
 | 
			
		||||
        let index = this._queue.length;
 | 
			
		||||
        if (index > 0) {
 | 
			
		||||
            while (index--) {
 | 
			
		||||
                let q = this._queue[index];
 | 
			
		||||
                if (!q.callback || q.type === type) {
 | 
			
		||||
                    q.callback = undefined;
 | 
			
		||||
                    this._queue.splice(index, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除事件
 | 
			
		||||
     * @param type 事件類型
 | 
			
		||||
     * @param callback 
 | 
			
		||||
     */
 | 
			
		||||
    RemoveCallback(type:TType, callback: ActionCallback<TArg>) {
 | 
			
		||||
        let index = this._queue.length;
 | 
			
		||||
        if (index > 0) {
 | 
			
		||||
            while (index--) {
 | 
			
		||||
                let q = this._queue[index];
 | 
			
		||||
                if (!q.callback || (q.type === type && q.callback === callback)) {
 | 
			
		||||
                    q.callback = undefined;
 | 
			
		||||
                    this._queue.splice(index, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除全部事件
 | 
			
		||||
     */
 | 
			
		||||
    RemoveAllCallbacks() {
 | 
			
		||||
        this._queue.forEach(q => q.callback = undefined);
 | 
			
		||||
        this._queue.length = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 發送事件
 | 
			
		||||
     * @param type 事件類型
 | 
			
		||||
     * @param arg 參數
 | 
			
		||||
     */
 | 
			
		||||
    DispatchCallback(type: TType, arg: TArg) {
 | 
			
		||||
        let index = this._queue.length;
 | 
			
		||||
        if (index > 0) {
 | 
			
		||||
            let cleanRemoved = false;
 | 
			
		||||
            this._queue.slice().forEach(q => {
 | 
			
		||||
                if (!q.callback)
 | 
			
		||||
                {
 | 
			
		||||
                    cleanRemoved = true;
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (q.type !== type) return;
 | 
			
		||||
 | 
			
		||||
                if (q.target) {
 | 
			
		||||
                    q.callback.call(q.target, arg);
 | 
			
		||||
                } else {
 | 
			
		||||
                    q.callback(arg);
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                if (q.once) {
 | 
			
		||||
                    q.callback = undefined;
 | 
			
		||||
                    cleanRemoved = true;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            if (cleanRemoved) {
 | 
			
		||||
                index = this._queue.length;
 | 
			
		||||
                if (index > 0) {
 | 
			
		||||
                    while (index--) {
 | 
			
		||||
                        let q = this._queue[index];
 | 
			
		||||
                        if (!q.callback) {
 | 
			
		||||
                            this._queue.splice(index, 1);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "61d770ec-24e2-425b-b66b-2b03e192e45b",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,166 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 回呼函數: fnname (type: TType, arg: TArg): void
 | 
			
		||||
 */
 | 
			
		||||
interface ActionCallback<TType, TArg> {
 | 
			
		||||
    (type: TType, arg: TArg): void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface Struct<TType, TArg> {
 | 
			
		||||
    callback: ActionCallback<TType, TArg>;
 | 
			
		||||
    target: any;
 | 
			
		||||
    type: TType;
 | 
			
		||||
    once?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ActionWithType2<TType, TArg> {
 | 
			
		||||
    private _queue: Struct<TType, TArg>[] = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 監聽事件
 | 
			
		||||
     * @param callback 回呼函數: fnname (type: TType, arg: TArg): void
 | 
			
		||||
     * @param bindTarget 回呼時this綁定的對象
 | 
			
		||||
     */
 | 
			
		||||
    AddCallback(type: TType, callback: ActionCallback<TType, TArg>, bindTarget?: any) {
 | 
			
		||||
        let q = <Struct<TType, TArg>> {
 | 
			
		||||
            callback: callback,
 | 
			
		||||
            target: bindTarget,
 | 
			
		||||
            type: type
 | 
			
		||||
        };
 | 
			
		||||
        this._queue.push(q);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 監聽事件 (一次性)
 | 
			
		||||
     * @param callback 回呼函數: fnname (type: TType, arg: TArg): void
 | 
			
		||||
     * @param bindTarget 回呼時this綁定的對象
 | 
			
		||||
     */
 | 
			
		||||
    AddCallbackOnce(type: TType, callback: ActionCallback<TType, TArg>, bindTarget?: any) {
 | 
			
		||||
        let q = <Struct<TType, TArg>> {
 | 
			
		||||
            callback: callback,
 | 
			
		||||
            target: bindTarget,
 | 
			
		||||
            type: type,
 | 
			
		||||
            once: true
 | 
			
		||||
        };
 | 
			
		||||
        this._queue.push(q);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除事件
 | 
			
		||||
     * @param callback 
 | 
			
		||||
     */
 | 
			
		||||
    RemoveByCallback(callback: ActionCallback<TType, TArg>) {
 | 
			
		||||
        let index = this._queue.length;
 | 
			
		||||
        if (index > 0) {
 | 
			
		||||
            while (index--) {
 | 
			
		||||
                let q = this._queue[index];
 | 
			
		||||
                if (!q.callback || q.callback === callback) {
 | 
			
		||||
                    q.callback = undefined;
 | 
			
		||||
                    this._queue.splice(index, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除事件
 | 
			
		||||
     * @param bindTarget 回呼時this綁定的對象
 | 
			
		||||
     */
 | 
			
		||||
    RemoveByBindTarget(bindTarget: any) {
 | 
			
		||||
        let index = this._queue.length;
 | 
			
		||||
        if (index > 0) {
 | 
			
		||||
            while (index--) {
 | 
			
		||||
                let q = this._queue[index];
 | 
			
		||||
                if (!q.callback || q.target === bindTarget) {
 | 
			
		||||
                    q.callback = undefined;
 | 
			
		||||
                    this._queue.splice(index, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除事件
 | 
			
		||||
     * @param type 事件類型
 | 
			
		||||
     */
 | 
			
		||||
    RemoveByType(type: TType) {
 | 
			
		||||
        let index = this._queue.length;
 | 
			
		||||
        if (index > 0) {
 | 
			
		||||
            while (index--) {
 | 
			
		||||
                let q = this._queue[index];
 | 
			
		||||
                if (!q.callback || q.type === type) {
 | 
			
		||||
                    q.callback = undefined;
 | 
			
		||||
                    this._queue.splice(index, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除事件
 | 
			
		||||
     * @param type 事件類型
 | 
			
		||||
     * @param callback 
 | 
			
		||||
     */
 | 
			
		||||
    RemoveCallback(type:TType, callback: ActionCallback<TType, TArg>) {
 | 
			
		||||
        let index = this._queue.length;
 | 
			
		||||
        if (index > 0) {
 | 
			
		||||
            while (index--) {
 | 
			
		||||
                let q = this._queue[index];
 | 
			
		||||
                if (!q.callback || (q.type === type && q.callback === callback)) {
 | 
			
		||||
                    q.callback = undefined;
 | 
			
		||||
                    this._queue.splice(index, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除全部事件
 | 
			
		||||
     */
 | 
			
		||||
    RemoveAllCallbacks() {
 | 
			
		||||
        this._queue.forEach(q => q.callback = undefined);
 | 
			
		||||
        this._queue.length = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 發送事件
 | 
			
		||||
     * @param type 事件類型
 | 
			
		||||
     * @param arg 參數
 | 
			
		||||
     */
 | 
			
		||||
    DispatchCallback(type: TType, arg: TArg) {
 | 
			
		||||
        let index = this._queue.length;
 | 
			
		||||
        if (index > 0) {
 | 
			
		||||
            let cleanRemoved = false;
 | 
			
		||||
            this._queue.slice().forEach(q => {
 | 
			
		||||
                if (!q.callback)
 | 
			
		||||
                {
 | 
			
		||||
                    cleanRemoved = true;
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (q.type !== type) return;
 | 
			
		||||
 | 
			
		||||
                if (q.target) {
 | 
			
		||||
                    q.callback.call(q.target, type, arg);
 | 
			
		||||
                } else {
 | 
			
		||||
                    q.callback(type, arg);
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                if (q.once) {
 | 
			
		||||
                    q.callback = undefined;
 | 
			
		||||
                    cleanRemoved = true;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            if (cleanRemoved) {
 | 
			
		||||
                index = this._queue.length;
 | 
			
		||||
                if (index > 0) {
 | 
			
		||||
                    while (index--) {
 | 
			
		||||
                        let q = this._queue[index];
 | 
			
		||||
                        if (!q.callback) {
 | 
			
		||||
                            this._queue.splice(index, 1);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "ed703ebd-efd4-4ec9-9b84-de748ef8f9e8",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								assets/Script/Engine/CatanEngine/CSharp/System/Text.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								assets/Script/Engine/CatanEngine/CSharp/System/Text.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.1.2",
 | 
			
		||||
  "uuid": "09d69d12-a6d1-4bb1-bcfe-faa811632467",
 | 
			
		||||
  "isBundle": false,
 | 
			
		||||
  "bundleName": "",
 | 
			
		||||
  "priority": 1,
 | 
			
		||||
  "compressionType": {},
 | 
			
		||||
  "optimizeHotUpdate": {},
 | 
			
		||||
  "inlineSpriteFrames": {},
 | 
			
		||||
  "isRemoteBundle": {},
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,86 @@
 | 
			
		||||
export module Encoding.UTF8 {
 | 
			
		||||
 | 
			
		||||
	export function GetBytes(str: string) {
 | 
			
		||||
		let len = str.length, resPos = -1;
 | 
			
		||||
		let resArr = new Uint8Array(len * 3);
 | 
			
		||||
		for (let point = 0, nextcode = 0, i = 0; i !== len;) {
 | 
			
		||||
			point = str.charCodeAt(i), i += 1;
 | 
			
		||||
			if (point >= 0xD800 && point <= 0xDBFF) {
 | 
			
		||||
				if (i === len) {
 | 
			
		||||
					resArr[resPos += 1] = 0xef;
 | 
			
		||||
					resArr[resPos += 1] = 0xbf;
 | 
			
		||||
					resArr[resPos += 1] = 0xbd;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				nextcode = str.charCodeAt(i);
 | 
			
		||||
				if (nextcode >= 0xDC00 && nextcode <= 0xDFFF) {
 | 
			
		||||
					point = (point - 0xD800) * 0x400 + nextcode - 0xDC00 + 0x10000;
 | 
			
		||||
					i += 1;
 | 
			
		||||
					if (point > 0xffff) {
 | 
			
		||||
						resArr[resPos += 1] = (0x1e << 3) | (point >>> 18);
 | 
			
		||||
						resArr[resPos += 1] = (0x2 << 6) | ((point >>> 12) & 0x3f);
 | 
			
		||||
						resArr[resPos += 1] = (0x2 << 6) | ((point >>> 6) & 0x3f);
 | 
			
		||||
						resArr[resPos += 1] = (0x2 << 6) | (point & 0x3f);
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					resArr[resPos += 1] = 0xef;
 | 
			
		||||
					resArr[resPos += 1] = 0xbf;
 | 
			
		||||
					resArr[resPos += 1] = 0xbd;
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (point <= 0x007f) {
 | 
			
		||||
				resArr[resPos += 1] = (0x0 << 7) | point;
 | 
			
		||||
			} else if (point <= 0x07ff) {
 | 
			
		||||
				resArr[resPos += 1] = (0x6 << 5) | (point >>> 6);
 | 
			
		||||
				resArr[resPos += 1] = (0x2 << 6) | (point & 0x3f);
 | 
			
		||||
			} else {
 | 
			
		||||
				resArr[resPos += 1] = (0xe << 4) | (point >>> 12);
 | 
			
		||||
				resArr[resPos += 1] = (0x2 << 6) | ((point >>> 6) & 0x3f);
 | 
			
		||||
				resArr[resPos += 1] = (0x2 << 6) | (point & 0x3f);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return resArr.subarray(0, resPos + 1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	export function GetString(array: Uint8Array) {
 | 
			
		||||
		let str = "";
 | 
			
		||||
		let i = 0, len = array.length;
 | 
			
		||||
		while (i < len) {
 | 
			
		||||
			let c = array[i++];
 | 
			
		||||
			switch (c >> 4) {
 | 
			
		||||
				case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
 | 
			
		||||
					str += String.fromCharCode(c);
 | 
			
		||||
					break;
 | 
			
		||||
				case 12: case 13:
 | 
			
		||||
					str += String.fromCharCode(((c & 0x1F) << 6) | (array[i++] & 0x3F));
 | 
			
		||||
					break;
 | 
			
		||||
				case 14:
 | 
			
		||||
					str += String.fromCharCode(((c & 0x0F) << 12) | ((array[i++] & 0x3F) << 6) | ((array[i++] & 0x3F) << 0));
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return str;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	export function b64EncodeUnicode(str) {
 | 
			
		||||
		return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
 | 
			
		||||
			return String.fromCharCode('0x' + p1);
 | 
			
		||||
		}));
 | 
			
		||||
	}
 | 
			
		||||
	export function b64DecodeUnicode(str) {
 | 
			
		||||
		return decodeURIComponent(atob(str).split('').map(function (c) {
 | 
			
		||||
			return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
 | 
			
		||||
		}).join(''));
 | 
			
		||||
	}
 | 
			
		||||
	export function isBase64(str) {
 | 
			
		||||
		if (str === '' || str.trim() === '') { return false; }
 | 
			
		||||
		try {
 | 
			
		||||
			return btoa(atob(str)) == str;
 | 
			
		||||
		} catch (err) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "43bf5724-e939-4189-b981-c32ef694e5a5",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								assets/Script/Engine/CatanEngine/CoroutineV2.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								assets/Script/Engine/CatanEngine/CoroutineV2.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.1.2",
 | 
			
		||||
  "uuid": "9f510f2b-83d8-4097-8683-32d6134323fb",
 | 
			
		||||
  "isBundle": false,
 | 
			
		||||
  "bundleName": "",
 | 
			
		||||
  "priority": 1,
 | 
			
		||||
  "compressionType": {},
 | 
			
		||||
  "optimizeHotUpdate": {},
 | 
			
		||||
  "inlineSpriteFrames": {},
 | 
			
		||||
  "isRemoteBundle": {},
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,43 @@
 | 
			
		||||
const CANCEL = Symbol();
 | 
			
		||||
 | 
			
		||||
export interface CancellationToken {
 | 
			
		||||
    readonly IsCancellationRequested: boolean;
 | 
			
		||||
    ThrowIfCancellationRequested(): void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class CancellationTokenSource {
 | 
			
		||||
    readonly Token: CancellationToken;
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.Token = new CancellationTokenImpl();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Cancel() {
 | 
			
		||||
        this.Token[CANCEL]();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class TaskCancelledException extends Error {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super("Task Cancelled");
 | 
			
		||||
        Reflect.setPrototypeOf(this, TaskCancelledException.prototype);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class CancellationTokenImpl implements CancellationToken {
 | 
			
		||||
    IsCancellationRequested: boolean;
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.IsCancellationRequested = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ThrowIfCancellationRequested() {
 | 
			
		||||
        if (this.IsCancellationRequested) {
 | 
			
		||||
            throw new TaskCancelledException();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [CANCEL]() {
 | 
			
		||||
        this.IsCancellationRequested = true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "9a414131-91a8-4d02-9921-9d1ee01764c3",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								assets/Script/Engine/CatanEngine/CoroutineV2/Core.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								assets/Script/Engine/CatanEngine/CoroutineV2/Core.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.1.2",
 | 
			
		||||
  "uuid": "fbfe97a8-24ca-4f67-b049-323652c7194b",
 | 
			
		||||
  "isBundle": false,
 | 
			
		||||
  "bundleName": "",
 | 
			
		||||
  "priority": 1,
 | 
			
		||||
  "compressionType": {},
 | 
			
		||||
  "optimizeHotUpdate": {},
 | 
			
		||||
  "inlineSpriteFrames": {},
 | 
			
		||||
  "isRemoteBundle": {},
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,17 @@
 | 
			
		||||
import { BaseEnumerator } from "./BaseEnumerator";
 | 
			
		||||
 | 
			
		||||
export class ActionEnumerator extends BaseEnumerator {
 | 
			
		||||
    private _action: Function;
 | 
			
		||||
 | 
			
		||||
    constructor(action: Function) {
 | 
			
		||||
        super();
 | 
			
		||||
        this._action = action;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    next(value?: any): IteratorResult<any> {
 | 
			
		||||
        if (this._action) {
 | 
			
		||||
            this._action();
 | 
			
		||||
        }
 | 
			
		||||
        return { done: true, value: undefined };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "3cf9e5c3-520f-48a9-8821-9be76d519765",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,87 @@
 | 
			
		||||
import { IEnumeratorV2, IEnumeratorV2Started } from "../IEnumeratorV2";
 | 
			
		||||
import { CoroutineExecutor } from "./CoroutineExecutor";
 | 
			
		||||
 | 
			
		||||
export abstract class BaseEnumerator implements IEnumeratorV2 {
 | 
			
		||||
    public nextEnumerator: BaseEnumerator;
 | 
			
		||||
 | 
			
		||||
    abstract next(value?: any): IteratorResult<any>;
 | 
			
		||||
    
 | 
			
		||||
    Start(target?: any): IEnumeratorV2Started {
 | 
			
		||||
        let executor = LazyLoad.EnumeratorExecutor(this, target);
 | 
			
		||||
        CoroutineExecutor.instance.StartCoroutine(executor);
 | 
			
		||||
        return executor;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Then(iterator: Iterator<any>): IEnumeratorV2 {
 | 
			
		||||
        if (!iterator) return this;
 | 
			
		||||
 | 
			
		||||
        if (iterator instanceof BaseEnumerator) {
 | 
			
		||||
            BaseEnumerator.getLastEnumerator(this).nextEnumerator = iterator;
 | 
			
		||||
            return this;
 | 
			
		||||
        } else {
 | 
			
		||||
            let enumerator = LazyLoad.SingleEnumerator(iterator);
 | 
			
		||||
            BaseEnumerator.getLastEnumerator(this).nextEnumerator = enumerator;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    ThenSerial(...iterators: Iterator<any>[]): IEnumeratorV2 {
 | 
			
		||||
        let last = BaseEnumerator.getLastEnumerator(this);
 | 
			
		||||
        for (let iterator of iterators) {
 | 
			
		||||
            if (iterator instanceof BaseEnumerator) {
 | 
			
		||||
                last.nextEnumerator = iterator;
 | 
			
		||||
            } else {
 | 
			
		||||
                let enumerator = LazyLoad.SingleEnumerator(iterator);
 | 
			
		||||
                last.nextEnumerator = enumerator;
 | 
			
		||||
            }
 | 
			
		||||
            last = last.nextEnumerator;
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ThenParallel(...iterators: Iterator<any>[]): IEnumeratorV2 {
 | 
			
		||||
        return this.Then(LazyLoad.ParallelEnumerator(...iterators));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ThenAction(action: Function, delaySeconds?:number): IEnumeratorV2 {
 | 
			
		||||
        if (delaySeconds > 0) {
 | 
			
		||||
            return this.ThenSerial(LazyLoad.WaitTimeEnumerator(delaySeconds), LazyLoad.ActionEnumerator(action));
 | 
			
		||||
        } else {
 | 
			
		||||
            return this.Then(LazyLoad.ActionEnumerator(action));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ThenWaitTime(seconds: number): IEnumeratorV2 {
 | 
			
		||||
        return this.Then(LazyLoad.WaitTimeEnumerator(seconds));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static getLastEnumerator(enumerator: BaseEnumerator): BaseEnumerator {
 | 
			
		||||
        let next = enumerator;
 | 
			
		||||
        while (next.nextEnumerator) {
 | 
			
		||||
            next = next.nextEnumerator;
 | 
			
		||||
        }
 | 
			
		||||
        return next;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module LazyLoad {
 | 
			
		||||
    export function EnumeratorExecutor(enumerator: BaseEnumerator, target: any) {
 | 
			
		||||
        return new (require("./EnumeratorExecutor") as typeof import("./EnumeratorExecutor")).EnumeratorExecutor(enumerator, target);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function SingleEnumerator(iterator: Iterator<any>) {
 | 
			
		||||
        return new (require("./SingleEnumerator") as typeof import("./SingleEnumerator")).SingleEnumerator(iterator);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function ParallelEnumerator(...iterators: Iterator<any>[]) {
 | 
			
		||||
        return new (require("./ParallelEnumerator") as typeof import("./ParallelEnumerator")).ParallelEnumerator(iterators);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function WaitTimeEnumerator(seconds: number) {
 | 
			
		||||
        return new (require("./WaitTimeEnumerator") as typeof import("./WaitTimeEnumerator")).WaitTimeEnumerator(seconds);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function ActionEnumerator(action: Function) {
 | 
			
		||||
        return new (require("./ActionEnumerator") as typeof import("./ActionEnumerator")).ActionEnumerator(action);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "4084537c-c7e8-4d47-b283-39be77ef9685",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,95 @@
 | 
			
		||||
import { EnumeratorExecutor } from "./EnumeratorExecutor";
 | 
			
		||||
 | 
			
		||||
export class CoroutineExecutor {
 | 
			
		||||
    private static _instance: CoroutineExecutor; 
 | 
			
		||||
    static get instance() {
 | 
			
		||||
        return CoroutineExecutor._instance = CoroutineExecutor._instance || new CoroutineExecutor();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private _executors: EnumeratorExecutor[] = [];
 | 
			
		||||
    private _nextExecutors: EnumeratorExecutor[] = [];
 | 
			
		||||
    private _isRunning: boolean = false;
 | 
			
		||||
    private _cleanRemoved: boolean = false;
 | 
			
		||||
    private _scheduler: cc.Scheduler;
 | 
			
		||||
    
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._scheduler = cc.director.getScheduler();
 | 
			
		||||
        this._scheduler.enableForTarget(this);
 | 
			
		||||
        this._scheduler.scheduleUpdate(this, 0, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    StartCoroutine(executor: EnumeratorExecutor) {
 | 
			
		||||
        executor.next(0);
 | 
			
		||||
        //TODO: 這邊要考量next後馬上接BaseEnumerator/Iterator的情形
 | 
			
		||||
        
 | 
			
		||||
        if (!this._isRunning) {
 | 
			
		||||
            this._executors.push(executor);
 | 
			
		||||
 | 
			
		||||
            if (this._scheduler.isTargetPaused(this)) {
 | 
			
		||||
                this._scheduler.resumeTarget(this);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            this._nextExecutors.push(executor);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    StopCoroutineBy(target: any) {
 | 
			
		||||
        if (!target) return;
 | 
			
		||||
 | 
			
		||||
        for (let r of this._executors) {
 | 
			
		||||
            if (target === r.target) {
 | 
			
		||||
                r.Stop();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        for (let r of this._nextExecutors) {
 | 
			
		||||
            if (target === r.target) {
 | 
			
		||||
                r.Stop();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    update(delta: number) {
 | 
			
		||||
        if (this._nextExecutors.length) {
 | 
			
		||||
            this._executors.push(...this._nextExecutors);
 | 
			
		||||
            this._nextExecutors.length = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._cleanRemoved) {
 | 
			
		||||
            // 移除[doneFlag=true]的協程
 | 
			
		||||
            let index = this._executors.length;
 | 
			
		||||
            while (index--) {
 | 
			
		||||
                let r = this._executors[index];
 | 
			
		||||
                if (r.doneFlag) {
 | 
			
		||||
                    this._executors.splice(index, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            this._cleanRemoved = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._executors.length == 0) {
 | 
			
		||||
            if (CC_DEBUG) {
 | 
			
		||||
                cc.log("[CoroutineV2] All coroutines done");
 | 
			
		||||
            }
 | 
			
		||||
            this._scheduler.pauseTarget(this);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._isRunning = true;
 | 
			
		||||
 | 
			
		||||
        // 執行協程
 | 
			
		||||
        for (let r of this._executors) {
 | 
			
		||||
            if (r.doneFlag || r.pauseFlag || r.childFlag) 
 | 
			
		||||
            {
 | 
			
		||||
                if (r.doneFlag) {
 | 
			
		||||
                    this._cleanRemoved = true;
 | 
			
		||||
                }
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            r.next(delta);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._isRunning = false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "f25b1e42-90d8-4fc0-9925-6e7e92296d57",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,169 @@
 | 
			
		||||
import { IEnumeratorV2Started } from "../IEnumeratorV2";
 | 
			
		||||
import { BaseEnumerator } from "./BaseEnumerator";
 | 
			
		||||
import { SingleEnumerator } from "./SingleEnumerator";
 | 
			
		||||
 | 
			
		||||
export class EnumeratorExecutor implements IEnumeratorV2Started {
 | 
			
		||||
    public Current: any;
 | 
			
		||||
 | 
			
		||||
    public target: any;
 | 
			
		||||
    public pauseFlag: boolean;
 | 
			
		||||
    public doneFlag: boolean;
 | 
			
		||||
    public childFlag: boolean;
 | 
			
		||||
    public asyncFlag: boolean;
 | 
			
		||||
    public error: any;
 | 
			
		||||
 | 
			
		||||
    private _executor: EnumeratorExecutor;
 | 
			
		||||
    private _enumerator: BaseEnumerator;
 | 
			
		||||
 | 
			
		||||
    constructor(enumerator: BaseEnumerator, target: any) {
 | 
			
		||||
        this.target = target;
 | 
			
		||||
        this._enumerator = enumerator;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    next(delta?: any): IteratorResult<any> {
 | 
			
		||||
        if (this._executor && this._executor.doneFlag) {
 | 
			
		||||
            this._executor = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.doneFlag || (!this._enumerator && !this._executor)) {
 | 
			
		||||
            this.doneFlag = true;
 | 
			
		||||
            return { done: true, value: undefined };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.asyncFlag || this.pauseFlag) return { done: false, value: undefined };
 | 
			
		||||
 | 
			
		||||
        let result: IteratorResult<any>;
 | 
			
		||||
 | 
			
		||||
        if (this._executor) {
 | 
			
		||||
            result = this._executor.next(delta);
 | 
			
		||||
            this.Current = this._executor.Current;
 | 
			
		||||
            if (this._executor.doneFlag) {
 | 
			
		||||
                this._executor = null;
 | 
			
		||||
            } else {
 | 
			
		||||
                result.done = false;
 | 
			
		||||
                return result;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (!this._enumerator) {
 | 
			
		||||
            this.doneFlag = true;
 | 
			
		||||
            return { done: true, value: undefined };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            result = this._enumerator.next(delta);
 | 
			
		||||
            let value = result.value;
 | 
			
		||||
            let done = result.done;
 | 
			
		||||
 | 
			
		||||
            if (value) {
 | 
			
		||||
                // Iterator
 | 
			
		||||
                if (typeof value[Symbol.iterator] === 'function') {
 | 
			
		||||
                    value = new SingleEnumerator(<Iterator<any>>value);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (value instanceof BaseEnumerator) {
 | 
			
		||||
                    if (!done) {
 | 
			
		||||
                        BaseEnumerator.getLastEnumerator(value).nextEnumerator = this._enumerator;
 | 
			
		||||
                    }
 | 
			
		||||
                    this._enumerator = value;
 | 
			
		||||
                    result = this._enumerator.next(delta);
 | 
			
		||||
                    value = result.value;
 | 
			
		||||
                    done = result.done;
 | 
			
		||||
                    
 | 
			
		||||
                    if (value) {
 | 
			
		||||
                        // Iterator again
 | 
			
		||||
                        if (typeof value[Symbol.iterator] === 'function') {
 | 
			
		||||
                            value = new SingleEnumerator(<Iterator<any>>value);
 | 
			
		||||
                        } 
 | 
			
		||||
                        
 | 
			
		||||
                        if (value instanceof BaseEnumerator) {
 | 
			
		||||
                            if (!done) {
 | 
			
		||||
                                BaseEnumerator.getLastEnumerator(value).nextEnumerator = this._enumerator;
 | 
			
		||||
                            }
 | 
			
		||||
                            this._enumerator = value;
 | 
			
		||||
                            result.done = false;
 | 
			
		||||
                            done = false;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                if (value instanceof EnumeratorExecutor) {
 | 
			
		||||
                    if (done) {
 | 
			
		||||
                        this._enumerator = this._enumerator.nextEnumerator;
 | 
			
		||||
                    }
 | 
			
		||||
                    value.childFlag = true;
 | 
			
		||||
                    result.done = false;
 | 
			
		||||
                    done = false;
 | 
			
		||||
                    this._executor = value;
 | 
			
		||||
                } else if (Promise.resolve(value) === value) {
 | 
			
		||||
                    this.asyncFlag = true;
 | 
			
		||||
                    result.done = false;
 | 
			
		||||
                    done = false;
 | 
			
		||||
                    (<Promise<any>>value)
 | 
			
		||||
                        .then(v => {
 | 
			
		||||
                            this.asyncFlag = false;
 | 
			
		||||
                            this.Current = v;
 | 
			
		||||
                            if (done) {
 | 
			
		||||
                                this._enumerator = this._enumerator.nextEnumerator;
 | 
			
		||||
                            }
 | 
			
		||||
                        })
 | 
			
		||||
                        .catch(e => {
 | 
			
		||||
                            this.asyncFlag = false;
 | 
			
		||||
                            this.doneFlag = true;
 | 
			
		||||
                            this._enumerator = null;
 | 
			
		||||
                            this.error = e;
 | 
			
		||||
                            if (e instanceof Error) {
 | 
			
		||||
                                cc.error(e.stack);
 | 
			
		||||
                            } else {
 | 
			
		||||
                                cc.error(`Error: ${JSON.stringify(e)}`);
 | 
			
		||||
                            }
 | 
			
		||||
                        });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                this.Current = value;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            if (done) {
 | 
			
		||||
                this._enumerator = this._enumerator.nextEnumerator;
 | 
			
		||||
                if (this._enumerator) {
 | 
			
		||||
                    result.done = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (e)
 | 
			
		||||
        {
 | 
			
		||||
            this.doneFlag = true;
 | 
			
		||||
            this.error = e;
 | 
			
		||||
            if (e instanceof Error) {
 | 
			
		||||
                cc.error(e.stack);
 | 
			
		||||
            } else {
 | 
			
		||||
                cc.error(`Error: ${JSON.stringify(e)}`);
 | 
			
		||||
            }
 | 
			
		||||
            result = { done: true, value: e };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Stop(): void {
 | 
			
		||||
        this.doneFlag = true;
 | 
			
		||||
        if (this._executor) {
 | 
			
		||||
            this._executor.Stop();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Pause(): void {
 | 
			
		||||
        this.pauseFlag = true;
 | 
			
		||||
        if (this._executor) {
 | 
			
		||||
            this._executor.Pause();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Resume(): void {
 | 
			
		||||
        this.pauseFlag = false;
 | 
			
		||||
        if (this._executor) {
 | 
			
		||||
            this._executor.Resume();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "91cb70ed-e6f9-4ce0-b7c5-1720087b3bd7",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,46 @@
 | 
			
		||||
import { BaseEnumerator } from "./BaseEnumerator";
 | 
			
		||||
import { EnumeratorExecutor } from "./EnumeratorExecutor";
 | 
			
		||||
import { SingleEnumerator } from "./SingleEnumerator";
 | 
			
		||||
 | 
			
		||||
export class ParallelEnumerator extends BaseEnumerator {
 | 
			
		||||
    private _executors: EnumeratorExecutor[] = [];
 | 
			
		||||
 | 
			
		||||
    constructor(iterators: Iterator<any>[]) {
 | 
			
		||||
        super();
 | 
			
		||||
        if (iterators && iterators.length) {
 | 
			
		||||
            for (let iterator of iterators) {
 | 
			
		||||
                if (iterator instanceof BaseEnumerator) {
 | 
			
		||||
                    this._executors.push(new EnumeratorExecutor(iterator, null));
 | 
			
		||||
                } else {
 | 
			
		||||
                    this._executors.push(new EnumeratorExecutor(new SingleEnumerator(iterator), null));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    next(value?: any): IteratorResult<any> {
 | 
			
		||||
        if (this._executors.length) {
 | 
			
		||||
            // 先移除[doneFlag=true]協程
 | 
			
		||||
            let index = this._executors.length;
 | 
			
		||||
            while (index--) {
 | 
			
		||||
                let r = this._executors[index];
 | 
			
		||||
                if (r.doneFlag) {
 | 
			
		||||
                    this._executors.splice(index, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (this._executors.length == 0) {
 | 
			
		||||
                return { done: true, value: undefined };
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 執行協程
 | 
			
		||||
            for (let r of this._executors) {
 | 
			
		||||
                r.next(value);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return { done: false, value: undefined };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return { done: true, value: undefined };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "017ebc9a-5152-4f94-bbaf-e3b914e87b41",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,18 @@
 | 
			
		||||
import { BaseEnumerator } from "./BaseEnumerator";
 | 
			
		||||
 | 
			
		||||
export class SingleEnumerator extends BaseEnumerator {
 | 
			
		||||
    private _iterator: Iterator<any>;
 | 
			
		||||
 | 
			
		||||
    constructor(iterator: Iterator<any>) {
 | 
			
		||||
        super();
 | 
			
		||||
        this._iterator = iterator;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    next(value?: any): IteratorResult<any> {
 | 
			
		||||
        if (!this._iterator) {
 | 
			
		||||
            return { done: true, value: undefined };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return this._iterator.next(value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "c439d019-2da8-48b8-a65b-bff928d0fda8",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,21 @@
 | 
			
		||||
import { BaseEnumerator } from "./BaseEnumerator";
 | 
			
		||||
 | 
			
		||||
export class WaitTimeEnumerator extends BaseEnumerator {
 | 
			
		||||
    private _seconds: number;
 | 
			
		||||
 | 
			
		||||
    constructor(seconds: number) {
 | 
			
		||||
        super();
 | 
			
		||||
        this._seconds = seconds;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    next(value?: any): IteratorResult<any> {
 | 
			
		||||
        let delta = value as number;
 | 
			
		||||
        this._seconds -= delta;
 | 
			
		||||
 | 
			
		||||
        if (this._seconds <= 0) {
 | 
			
		||||
            return { done: true, value: 0 };
 | 
			
		||||
        } else {
 | 
			
		||||
            return { done: false, value: this._seconds };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "a3038e6f-1bb4-4aff-a686-b69209df3592",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										199
									
								
								assets/Script/Engine/CatanEngine/CoroutineV2/CoroutineExample.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								assets/Script/Engine/CatanEngine/CoroutineV2/CoroutineExample.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,199 @@
 | 
			
		||||
import { CoroutineV2 } from "./CoroutineV2";
 | 
			
		||||
import { IEnumeratorV2Started } from "./IEnumeratorV2";
 | 
			
		||||
 | 
			
		||||
const {ccclass, property} = cc._decorator;
 | 
			
		||||
 | 
			
		||||
class A {
 | 
			
		||||
    private numbers: number[] = [1, 2];
 | 
			
		||||
    private index = 0;
 | 
			
		||||
 | 
			
		||||
    [Symbol.iterator](): IterableIterator<any> {
 | 
			
		||||
        return this;
 | 
			
		||||
    }    
 | 
			
		||||
    
 | 
			
		||||
    next(value?: any): IteratorResult<any> {
 | 
			
		||||
        if (this.index < this.numbers.length) {
 | 
			
		||||
            let value = this.numbers[this.index++];
 | 
			
		||||
            cc.log(`A=> ${value}`);
 | 
			
		||||
            return {
 | 
			
		||||
                done: false,
 | 
			
		||||
                value: value
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return { done: true, value: undefined };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ccclass
 | 
			
		||||
export default class CoroutineExample extends cc.Component {
 | 
			
		||||
    private _routine: IEnumeratorV2Started;
 | 
			
		||||
    private _obj: Object = { "a": true };
 | 
			
		||||
    private _obj2: Object = { "b": true };
 | 
			
		||||
 | 
			
		||||
    private _num: number = 3;
 | 
			
		||||
 | 
			
		||||
    button1Clicked() {
 | 
			
		||||
        // this._routine = CoroutineV2
 | 
			
		||||
        //                     .Parallel(this.Coroutine1(1, 3), this.Coroutine1(4, 6))
 | 
			
		||||
        //                     .ThenWaitTime(2)
 | 
			
		||||
        //                     .Then(this.Coroutine1(7, 9))
 | 
			
		||||
        //                     .ThenWaitTime(2)
 | 
			
		||||
        //                     .ThenAction(() => cc.log("action callback 1"))
 | 
			
		||||
        //                     .ThenWaitTime(2)
 | 
			
		||||
        //                     .ThenAction(this.actionCallback)
 | 
			
		||||
        //                     //.Start(this);
 | 
			
		||||
        //                     .Start(this);
 | 
			
		||||
        // this._routine = CoroutineV2.Single(this.FunA()).Start(this);
 | 
			
		||||
 | 
			
		||||
        this._routine = CoroutineV2.Single(this.Test1_1()).Start(this);
 | 
			
		||||
        // this._routine = CoroutineV2.Single(this.Test2_1()).Start(this);
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
    *Test1_1() {
 | 
			
		||||
        yield null;
 | 
			
		||||
        yield *this.Test1_2();
 | 
			
		||||
        // CoroutineV2.Single(this.Test1_3()).Start(this);
 | 
			
		||||
        yield this.Test1_3();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *Test1_2() {
 | 
			
		||||
        yield null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *Test1_3() {
 | 
			
		||||
        yield this.Test1_3_1();
 | 
			
		||||
        yield CoroutineV2.Single(this.Test1_4()).Start(this._obj);
 | 
			
		||||
        // yield CoroutineV2.Single(this.Test1_4()); //.Start(this);
 | 
			
		||||
        // yield *this.Test1_4();
 | 
			
		||||
        cc.log("main wait 3");
 | 
			
		||||
        yield CoroutineV2.WaitTime(2);
 | 
			
		||||
        cc.log("done");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *Test1_3_1() {
 | 
			
		||||
        yield this.Test1_3_2();
 | 
			
		||||
        yield CoroutineV2.WaitTime(1);
 | 
			
		||||
        cc.log("Test1_3_1.1");
 | 
			
		||||
        yield CoroutineV2.WaitTime(1);
 | 
			
		||||
        cc.log("Test1_3_1.2");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *Test1_3_2() {
 | 
			
		||||
        yield this.Test1_3_3();
 | 
			
		||||
        yield CoroutineV2.WaitTime(1);
 | 
			
		||||
        cc.log("Test1_3_2.1");
 | 
			
		||||
        yield CoroutineV2.WaitTime(1);
 | 
			
		||||
        cc.log("Test1_3_2.2");
 | 
			
		||||
        yield CoroutineV2.WaitTime(1);
 | 
			
		||||
        cc.log("Test1_3_2.3");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    *Test1_3_3() {
 | 
			
		||||
        yield CoroutineV2.WaitTime(1);
 | 
			
		||||
        cc.log("Test1_3_3.1");
 | 
			
		||||
        yield CoroutineV2.WaitTime(1);
 | 
			
		||||
        cc.log("Test1_3_3.2");
 | 
			
		||||
        yield CoroutineV2.WaitTime(1);
 | 
			
		||||
        cc.log("Test1_3_3.3");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *Test1_4() {
 | 
			
		||||
        this._num++;
 | 
			
		||||
        cc.log(`WaitTime2 ${this._num}`);
 | 
			
		||||
        yield CoroutineV2.WaitTime(2).Start(this._obj2);
 | 
			
		||||
        this._num++;
 | 
			
		||||
        cc.log(`WaitTime2 ${this._num}`);
 | 
			
		||||
        yield CoroutineV2.WaitTime(2).Start(this._obj2);
 | 
			
		||||
        this._num++;
 | 
			
		||||
        cc.log(`WaitTime2 ${this._num}`);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    *Test2_1() {
 | 
			
		||||
        cc.log("111");
 | 
			
		||||
        CoroutineV2.Single(this.Test2_2()).Start(this);
 | 
			
		||||
        cc.log("333");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *Test2_2() {
 | 
			
		||||
        cc.log("222");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    button2Clicked() {
 | 
			
		||||
        // this._routine && this._routine.Stop();
 | 
			
		||||
        if (this._obj2) {
 | 
			
		||||
            CoroutineV2.StopCoroutinesBy(this._obj2);
 | 
			
		||||
            this._obj2 = null;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (this._obj) {
 | 
			
		||||
            CoroutineV2.StopCoroutinesBy(this._obj);
 | 
			
		||||
            this._obj = null;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        CoroutineV2.StopCoroutinesBy(this);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    button3Clicked() {
 | 
			
		||||
        // CoroutineV2.StopCoroutinesBy(this);
 | 
			
		||||
        this._routine && this._routine.Pause();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    button4Clicked() {
 | 
			
		||||
        // CoroutineV2.StopCoroutinesBy(this);
 | 
			
		||||
        this._routine && this._routine.Resume();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *Coroutine1(start:number, end: number)
 | 
			
		||||
    {
 | 
			
		||||
        for (let i = start; i <= end; i++) {
 | 
			
		||||
            // yield CoroutineV2.WaitTime(1).Start(); // Start()可以省略, 會由外層啟動
 | 
			
		||||
            // yield CoroutineV2.WaitTime(1).Start(this); // target也可以省略, 由外層的target控制
 | 
			
		||||
            
 | 
			
		||||
            yield CoroutineV2.WaitTime(1).Start();
 | 
			
		||||
            cc.log(`C1 => ${i}`);
 | 
			
		||||
 | 
			
		||||
            // 嵌套
 | 
			
		||||
            yield CoroutineV2
 | 
			
		||||
                        .WaitTime(1)
 | 
			
		||||
                        .ThenParallel(
 | 
			
		||||
                            // 再嵌套
 | 
			
		||||
                            CoroutineV2.Action(() => cc.log("start parallel")),
 | 
			
		||||
                            this.Coroutine2(10, 2), 
 | 
			
		||||
                            this.Coroutine2(20, 2), 
 | 
			
		||||
                            new A())
 | 
			
		||||
                        .ThenAction(() => cc.log("end parallel"))
 | 
			
		||||
                        .Start();
 | 
			
		||||
 | 
			
		||||
            // Promise
 | 
			
		||||
            yield this.loadItemAsync("settings.json");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *Coroutine2(num: number, repeat: number)
 | 
			
		||||
    {
 | 
			
		||||
        for (let i = 0; i < repeat; i++) {
 | 
			
		||||
            //yield CoroutineV2.WaitTime(2);
 | 
			
		||||
            yield 0;
 | 
			
		||||
            cc.log(`C2: ${num}`);
 | 
			
		||||
            // yield CoroutineV2.WaitTime(1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actionCallback() {
 | 
			
		||||
        cc.log("action callback 2");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    loadItemAsync(id: string): Promise<{id: string}> {
 | 
			
		||||
        return new Promise((resolve) => {
 | 
			
		||||
            cc.log('loading item start:', id);
 | 
			
		||||
            setTimeout(() => {
 | 
			
		||||
                resolve({ id: id });
 | 
			
		||||
                cc.log('loading item done:', id);
 | 
			
		||||
            }, 3000);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "dfd32c11-76f6-4e38-9272-1d7966d1ef3c",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										75
									
								
								assets/Script/Engine/CatanEngine/CoroutineV2/CoroutineV2.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								assets/Script/Engine/CatanEngine/CoroutineV2/CoroutineV2.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
import { IEnumeratorV2, IEnumeratorV2Started } from "./IEnumeratorV2";
 | 
			
		||||
import { BaseEnumerator } from "./Core/BaseEnumerator";
 | 
			
		||||
import { SingleEnumerator } from "./Core/SingleEnumerator";
 | 
			
		||||
import { ParallelEnumerator } from "./Core/ParallelEnumerator";
 | 
			
		||||
import { WaitTimeEnumerator } from "./Core/WaitTimeEnumerator";
 | 
			
		||||
import { ActionEnumerator } from "./Core/ActionEnumerator";
 | 
			
		||||
import { CoroutineExecutor } from "./Core/CoroutineExecutor";
 | 
			
		||||
 | 
			
		||||
export module CoroutineV2 {
 | 
			
		||||
    /**
 | 
			
		||||
     * 啟動一般協程
 | 
			
		||||
     */
 | 
			
		||||
    export function StartCoroutine(iterator: Iterator<any>, target?: any): IEnumeratorV2Started {
 | 
			
		||||
        return Single(iterator).Start(target);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 依據IEnumeratorV2.Start(target)綁定的目標, 來停止協程
 | 
			
		||||
     * @param target 
 | 
			
		||||
     */
 | 
			
		||||
    export function StopCoroutinesBy(target: any) {
 | 
			
		||||
        CoroutineExecutor.instance.StopCoroutineBy(target);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 單一協程
 | 
			
		||||
     */
 | 
			
		||||
    export function Single(iterator: Iterator<any>): IEnumeratorV2 {
 | 
			
		||||
        if (iterator instanceof BaseEnumerator) {
 | 
			
		||||
            return iterator;
 | 
			
		||||
        } else {
 | 
			
		||||
            return new SingleEnumerator(iterator);
 | 
			
		||||
        } 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 平行協程
 | 
			
		||||
     */
 | 
			
		||||
    export function Parallel(...iterators: Iterator<any>[]): IEnumeratorV2 {
 | 
			
		||||
        return new ParallelEnumerator(iterators);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 序列協程
 | 
			
		||||
     */
 | 
			
		||||
    export function Serial(...iterators: Iterator<any>[]): IEnumeratorV2 {
 | 
			
		||||
        let [iterator, ...others] = iterators;
 | 
			
		||||
        if (iterator instanceof BaseEnumerator) {
 | 
			
		||||
            return iterator.ThenSerial(...others);
 | 
			
		||||
        } else {
 | 
			
		||||
            return new SingleEnumerator(iterator).ThenSerial(...others);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 執行方法協程
 | 
			
		||||
     * @param action 方法
 | 
			
		||||
     * @param delaySeconds 延遲秒數
 | 
			
		||||
     */
 | 
			
		||||
    export function Action(action: Function, delaySeconds?: number): IEnumeratorV2 {
 | 
			
		||||
        if (delaySeconds > 0) {
 | 
			
		||||
            return new WaitTimeEnumerator(delaySeconds).Then(new ActionEnumerator(action));
 | 
			
		||||
        } else {
 | 
			
		||||
            return new ActionEnumerator(action);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 等待時間協程
 | 
			
		||||
     * @param seconds 秒數
 | 
			
		||||
     */
 | 
			
		||||
    export function WaitTime(seconds: number): IEnumeratorV2 {
 | 
			
		||||
        return new WaitTimeEnumerator(seconds);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "fc38e505-bd37-44c3-9e0a-fd463bb88c51",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,16 @@
 | 
			
		||||
export interface IEnumeratorV2 extends Iterator<any> {
 | 
			
		||||
    Start(target?: any): IEnumeratorV2Started;
 | 
			
		||||
    Then(iterator: Iterator<any>): IEnumeratorV2;
 | 
			
		||||
    ThenSerial(...iterators: Iterator<any>[]): IEnumeratorV2;
 | 
			
		||||
    ThenParallel(...iterators: Iterator<any>[]): IEnumeratorV2;
 | 
			
		||||
    ThenAction(action: Function, delaySeconds?: number): IEnumeratorV2;
 | 
			
		||||
    ThenWaitTime(seconds: number): IEnumeratorV2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IEnumeratorV2Started {
 | 
			
		||||
    readonly Current: any;
 | 
			
		||||
 | 
			
		||||
    Pause(): void;
 | 
			
		||||
    Resume(): void;
 | 
			
		||||
    Stop(): void;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "df3ab07d-3d2b-4552-b454-29b95223ea85",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								assets/Script/Engine/CatanEngine/NetManagerV2.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								assets/Script/Engine/CatanEngine/NetManagerV2.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.1.2",
 | 
			
		||||
  "uuid": "6f870efd-e869-4415-9cf2-138ab667cd5d",
 | 
			
		||||
  "isBundle": false,
 | 
			
		||||
  "bundleName": "",
 | 
			
		||||
  "priority": 1,
 | 
			
		||||
  "compressionType": {},
 | 
			
		||||
  "optimizeHotUpdate": {},
 | 
			
		||||
  "inlineSpriteFrames": {},
 | 
			
		||||
  "isRemoteBundle": {},
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								assets/Script/Engine/CatanEngine/NetManagerV2/Core.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								assets/Script/Engine/CatanEngine/NetManagerV2/Core.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.1.2",
 | 
			
		||||
  "uuid": "5e6c027f-ce4b-47fa-968c-f3bb6059ad81",
 | 
			
		||||
  "isBundle": false,
 | 
			
		||||
  "bundleName": "",
 | 
			
		||||
  "priority": 1,
 | 
			
		||||
  "compressionType": {},
 | 
			
		||||
  "optimizeHotUpdate": {},
 | 
			
		||||
  "inlineSpriteFrames": {},
 | 
			
		||||
  "isRemoteBundle": {},
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
import { Action } from "../../CSharp/System/Action";
 | 
			
		||||
import { INetRequest } from "./INetRequest";
 | 
			
		||||
import { INetResponse } from "./INetResponse";
 | 
			
		||||
 | 
			
		||||
export interface INetConnector {
 | 
			
		||||
    readonly OnDataReceived: Action<INetResponse<any>>;
 | 
			
		||||
    readonly OnDisconnected: Action<void>;
 | 
			
		||||
    readonly IsConnected: boolean;
 | 
			
		||||
    
 | 
			
		||||
    SendAsync<TRequest, TResponse>(req: INetRequest<TRequest, TResponse>): Iterator<any>;
 | 
			
		||||
    Send<TRequest, TResponse>(req: INetRequest<TRequest, TResponse>);
 | 
			
		||||
    Logout();
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "f97991b5-0da6-4220-ab29-13c8f8f7e405",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
import { INetResponse } from "./INetResponse";
 | 
			
		||||
 | 
			
		||||
export interface INetRequest<TRequest, TResponse> {
 | 
			
		||||
    readonly Method: string;
 | 
			
		||||
    readonly MethodBack: string;
 | 
			
		||||
    
 | 
			
		||||
    Data: TRequest;
 | 
			
		||||
    Result: INetResponse<TResponse>;
 | 
			
		||||
    
 | 
			
		||||
    SendAsync(): Iterator<any>;
 | 
			
		||||
    Send();
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "339fcf27-bdb9-4b8f-ae18-dd54c9500145",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,6 @@
 | 
			
		||||
export interface INetResponse<TResponse> {
 | 
			
		||||
    readonly Method: string;
 | 
			
		||||
    readonly Status: number;
 | 
			
		||||
    readonly Data: TResponse;
 | 
			
		||||
    readonly IsValid: boolean;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "c4cb0cd4-b98c-4f8e-b1e6-ac3b51281b28",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								assets/Script/Engine/CatanEngine/NetManagerV2/Examples.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								assets/Script/Engine/CatanEngine/NetManagerV2/Examples.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.1.2",
 | 
			
		||||
  "uuid": "94e55972-723c-4dab-9ebc-870bd5043fca",
 | 
			
		||||
  "isBundle": false,
 | 
			
		||||
  "bundleName": "",
 | 
			
		||||
  "priority": 1,
 | 
			
		||||
  "compressionType": {},
 | 
			
		||||
  "optimizeHotUpdate": {},
 | 
			
		||||
  "inlineSpriteFrames": {},
 | 
			
		||||
  "isRemoteBundle": {},
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,69 @@
 | 
			
		||||
import { CoroutineV2 } from "../../CoroutineV2/CoroutineV2";
 | 
			
		||||
import { INetResponse } from "../Core/INetResponse";
 | 
			
		||||
import { NetConnector } from "../NetConnector";
 | 
			
		||||
import { NetManager } from "../NetManager";
 | 
			
		||||
import { Slot1_SpinRequestExample } from "./Slot1_SpinRequestExample";
 | 
			
		||||
 | 
			
		||||
const {ccclass, property} = cc._decorator;
 | 
			
		||||
 | 
			
		||||
@ccclass
 | 
			
		||||
export default class NetTester extends cc.Component {
 | 
			
		||||
 | 
			
		||||
    onConnectClicked() {
 | 
			
		||||
        CoroutineV2.StartCoroutine(this.ConnectAsync());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *ConnectAsync() {
 | 
			
		||||
        if (!NetManager.HasInit) {
 | 
			
		||||
            let conn = new NetConnector("192.168.7.165", 9005);
 | 
			
		||||
            conn.OnDataReceived.AddCallback(this.OnNetDataReceived, this);
 | 
			
		||||
            conn.OnDisconnected.AddCallback(this.OnNetDisconnected, this);
 | 
			
		||||
            conn.OnLoadUIMask.AddCallback(this.OnLoadUIMask, this);
 | 
			
		||||
 | 
			
		||||
            NetManager.Initialize(conn);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        cc.log("連線中...");
 | 
			
		||||
        yield NetManager.ConnectAsync(); // 同個connector要再次連線, 可以不用叫CasinoNetManager.Initialize(), 但要先叫CasinoNetManager.Disconnect()
 | 
			
		||||
        cc.log(`連線狀態: ${NetManager.IsConnected}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onDisconnectClicked() {
 | 
			
		||||
        cc.log("中斷連線中...");
 | 
			
		||||
        NetManager.Disconnect(); // 中斷連線
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onSendMessageClicked1() {
 | 
			
		||||
        cc.log("發送訊息(不使用協程)");
 | 
			
		||||
        let req = new Slot1_SpinRequestExample(401);
 | 
			
		||||
        req.Send();
 | 
			
		||||
        // CasinoNetManager.Send(req);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onSendMessageClicked2() {
 | 
			
		||||
        CoroutineV2.StartCoroutine(this.SendAsync());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *SendAsync() {
 | 
			
		||||
        cc.log("發送訊息中(使用協程)...");
 | 
			
		||||
        let req = new Slot1_SpinRequestExample(399);
 | 
			
		||||
        yield req.SendAsync();
 | 
			
		||||
        // yield CasinoNetManager.SendAsync(req);
 | 
			
		||||
 | 
			
		||||
        let resp = req.Result;
 | 
			
		||||
        cc.log(`發送協程完畢, Server回應: ${resp.Method}(${JSON.stringify(resp.Data)}), 狀態: ${resp.Status}`);
 | 
			
		||||
        // cc.log(`使用介面資料: ${resp.Data.slot}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private OnNetDisconnected() {
 | 
			
		||||
        cc.log("[事件] 收到連線中斷事件");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private OnNetDataReceived(resp: INetResponse<any>) {
 | 
			
		||||
        cc.log(`[事件] 收到server呼叫: ${resp.Method}(${JSON.stringify(resp.Data)}), 狀態: ${resp.Status}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private OnLoadUIMask(value: boolean) {
 | 
			
		||||
        cc.log(`[事件] LoadUIMask: ${value}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "0cb7df7a-d0e7-4ce1-832e-4583cf3385e5",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,37 @@
 | 
			
		||||
import { NetRequest } from "../NetRequest";
 | 
			
		||||
 | 
			
		||||
// 送給server的結構
 | 
			
		||||
interface Request {
 | 
			
		||||
    pay: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// server回應的結構
 | 
			
		||||
interface Response {
 | 
			
		||||
    pay: [[number, number]];
 | 
			
		||||
    /**拉霸結果 */
 | 
			
		||||
    slot: number[];
 | 
			
		||||
    get: any[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// class Account_CreateRequest extends CasinoRequest<number, any> { // 也可以是基本類或any, 但不建議用any, 使用介面ts才會有提示
 | 
			
		||||
export class Slot1_SpinRequestExample extends NetRequest<Request, Response> {
 | 
			
		||||
    get Method(): string {
 | 
			
		||||
        return "slot1.spin";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // MethodBack預設回傳Method, 不一樣才需要覆寫
 | 
			
		||||
    // get MethodBack(): string {
 | 
			
		||||
    //     return "slot1.freespin";
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    constructor(totalBet: number) {
 | 
			
		||||
        super();
 | 
			
		||||
 | 
			
		||||
        // 原本的SingleValue拿掉, 統一使用Data來存送出結構
 | 
			
		||||
 | 
			
		||||
        // this.Data = 2;
 | 
			
		||||
        this.Data = {
 | 
			
		||||
            pay: totalBet,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "1af9e6af-3dc3-4d02-8b24-481adc07932a",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,4 @@
 | 
			
		||||
export default class NetConfig {
 | 
			
		||||
	/**是否顯示RPC接送JSON的LOG */
 | 
			
		||||
	public static ShowServerLog: boolean = true;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "c7f5f6a9-94fd-4f5f-9f0a-545cd14edca9",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										257
									
								
								assets/Script/Engine/CatanEngine/NetManagerV2/NetConnector.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										257
									
								
								assets/Script/Engine/CatanEngine/NetManagerV2/NetConnector.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,257 @@
 | 
			
		||||
import { BaseEnumerator } from "../CoroutineV2/Core/BaseEnumerator";
 | 
			
		||||
import { Action } from "../CSharp/System/Action";
 | 
			
		||||
import { Encoding } from "../CSharp/System/Text/Encoding";
 | 
			
		||||
import { INetRequest } from "./Core/INetRequest";
 | 
			
		||||
import { INetResponse } from "./Core/INetResponse";
 | 
			
		||||
import NetConfig from "./NetConfig";
 | 
			
		||||
 | 
			
		||||
export class NetConnector {
 | 
			
		||||
	readonly OnDataReceived: Action<INetResponse<any>> = new Action<INetResponse<any>>();
 | 
			
		||||
	readonly OnDisconnected: Action<void> = new Action<void>();
 | 
			
		||||
	readonly OnLoadUIMask: Action<boolean> = new Action<boolean>();
 | 
			
		||||
 | 
			
		||||
	get IsConnected() {
 | 
			
		||||
		return this._ws && this._ws.readyState === WebSocket.OPEN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private _host: string;
 | 
			
		||||
	private _ws: WebSocket;
 | 
			
		||||
	private _waitings: WsRequestEnumerator[] = [];
 | 
			
		||||
 | 
			
		||||
	constructor(host: string, port: number, ip: string) {
 | 
			
		||||
		let checkHttp: string = "";
 | 
			
		||||
		let index: number = host.indexOf("https://");
 | 
			
		||||
		if (index != -1) {
 | 
			
		||||
			checkHttp = "https";
 | 
			
		||||
			host = host.replace("https://", "");
 | 
			
		||||
		} else {
 | 
			
		||||
			checkHttp = window.location.href.substring(0, 5);
 | 
			
		||||
			host = host.replace("http://", "");
 | 
			
		||||
		}
 | 
			
		||||
		if (CC_DEBUG) {
 | 
			
		||||
			cc.log("[事件]checkHttp=", checkHttp, host, port);
 | 
			
		||||
		}
 | 
			
		||||
		if (checkHttp != "https") {
 | 
			
		||||
			this._host = `ws://${host}:${port}/?ip=${ip}`;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			this._host = `wss://${host}:${port}/?ip=${ip}`;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ConnectAsync() {
 | 
			
		||||
		if (this._ws) {
 | 
			
		||||
			throw new Error("請先執行CasinoNetManager.Disconnect()中斷連線");
 | 
			
		||||
		}
 | 
			
		||||
		if (cc.sys.isNative && cc.sys.os == cc.sys.OS_ANDROID && this._host.indexOf("wss") !== -1) {
 | 
			
		||||
			let cacert = cc.url.raw('resources/cacert.cer');
 | 
			
		||||
			if (cc.loader.md5Pipe) {
 | 
			
		||||
				cacert = cc.loader.md5Pipe.transformURL(cacert)
 | 
			
		||||
			}
 | 
			
		||||
			//@ts-ignore
 | 
			
		||||
			this._ws = new WebSocket(this._host, null, cacert)
 | 
			
		||||
		} else {
 | 
			
		||||
			//@ts-ignore
 | 
			
		||||
			this._ws = new WebSocket(this._host);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this._ws.binaryType = 'arraybuffer';
 | 
			
		||||
		this._ws.onopen = this.OnWebSocketOpen.bind(this);
 | 
			
		||||
		this._ws.onmessage = this.OnWebSocketMessage.bind(this);
 | 
			
		||||
		this._ws.onclose = this.OnWebSocketClose.bind(this);
 | 
			
		||||
 | 
			
		||||
		return new WsConnectEnumerator(this._ws);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Send(req: INetRequest<any, any>) {
 | 
			
		||||
		if (!this.IsConnected) return;
 | 
			
		||||
 | 
			
		||||
		let json = [req.Method];
 | 
			
		||||
		if (req.Data != null && req.Data != undefined && req.Data != NaN) {
 | 
			
		||||
			json[1] = req.Data;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (CC_DEBUG && NetConfig.ShowServerLog) {
 | 
			
		||||
			if (req.Data != null && req.Data != undefined && req.Data != NaN) {
 | 
			
		||||
				cc.log(`[RPC] 傳送server資料: ${req.Method}(${JSON.stringify(req.Data)})`);
 | 
			
		||||
			} else {
 | 
			
		||||
				cc.log(`[RPC] 傳送server資料: ${req.Method}()`);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		let str = JSON.stringify(json);
 | 
			
		||||
		if (str.length > 65535) {
 | 
			
		||||
			throw new Error('要傳的資料太大囉');
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		let strary = Encoding.UTF8.GetBytes(str);
 | 
			
		||||
		let buffer = new Uint8Array(4 + strary.byteLength);
 | 
			
		||||
		let u16ary = new Uint16Array(buffer.buffer, 0, 3);
 | 
			
		||||
		u16ary[0] = strary.byteLength;
 | 
			
		||||
		buffer[3] = 0x01;
 | 
			
		||||
		buffer.set(strary, 4);
 | 
			
		||||
 | 
			
		||||
		this._ws.send(buffer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	SendAsync(req: INetRequest<any, any>, mask: boolean) {
 | 
			
		||||
		let iterator = new WsRequestEnumerator(req);
 | 
			
		||||
		if (!this.IsConnected) {
 | 
			
		||||
			iterator.SetResponse(ErrorResponse);
 | 
			
		||||
		} else {
 | 
			
		||||
			this._waitings.push(iterator);
 | 
			
		||||
			if (mask) {
 | 
			
		||||
				this.OnLoadUIMask.DispatchCallback(true);
 | 
			
		||||
			}
 | 
			
		||||
			this.Send(req);
 | 
			
		||||
		}
 | 
			
		||||
		return iterator;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Disconnect() {
 | 
			
		||||
		this.WebSocketEnded();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private WebSocketEnded() {
 | 
			
		||||
		if (!this._ws) return;
 | 
			
		||||
 | 
			
		||||
		this._ws.close();
 | 
			
		||||
		this._ws.onopen = null;
 | 
			
		||||
		this._ws.onmessage = null;
 | 
			
		||||
		this._ws.onclose = () => { };
 | 
			
		||||
		this._ws = null;
 | 
			
		||||
 | 
			
		||||
		this.CleanWaitings();
 | 
			
		||||
		this.OnDisconnected.DispatchCallback();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private CleanWaitings() {
 | 
			
		||||
		for (let w of this._waitings) {
 | 
			
		||||
			w.SetResponse(ErrorResponse);
 | 
			
		||||
			this.OnLoadUIMask.DispatchCallback(false);
 | 
			
		||||
		}
 | 
			
		||||
		this._waitings.length = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private OnWebSocketOpen(e: Event) {
 | 
			
		||||
		if (CC_DEBUG) {
 | 
			
		||||
			cc.log(`[RPC] ${this._host} Connected.`);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private OnWebSocketMessage(e: MessageEvent) {
 | 
			
		||||
		if (e.data instanceof ArrayBuffer) {
 | 
			
		||||
			this.ParseRpcMessage(e.data);
 | 
			
		||||
		} else if (e.data instanceof Blob) {
 | 
			
		||||
			let reader = new FileReader();
 | 
			
		||||
			reader.onload = (e) => { this.ParseRpcMessage(<ArrayBuffer>reader.result); reader.onload = null; }
 | 
			
		||||
			reader.readAsArrayBuffer(e.data);
 | 
			
		||||
		} else {
 | 
			
		||||
			throw new Error(`未知的OnWebSocketMessage(e.data)類型: ${e.data}`);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private ParseRpcMessage(buffer: ArrayBuffer) {
 | 
			
		||||
		let startIndex = 0, byteLength = buffer.byteLength;
 | 
			
		||||
		while (startIndex + 4 < byteLength) {
 | 
			
		||||
			let strlen = new DataView(buffer, startIndex, 3).getUint16(0, true);
 | 
			
		||||
			let str = Encoding.UTF8.GetString(new Uint8Array(buffer, startIndex + 4, strlen));
 | 
			
		||||
			startIndex += strlen + 4;
 | 
			
		||||
 | 
			
		||||
			try {
 | 
			
		||||
				let json = JSON.parse(str);
 | 
			
		||||
				let method = <string>json[0];
 | 
			
		||||
				let status = <number>json[1][0];
 | 
			
		||||
				let data = json[1][1];
 | 
			
		||||
 | 
			
		||||
				let resp = <INetResponse<any>>{
 | 
			
		||||
					Method: method,
 | 
			
		||||
					Status: status,
 | 
			
		||||
					Data: data,
 | 
			
		||||
					IsValid: method && status === 0
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				if (CC_DEBUG && NetConfig.ShowServerLog) {
 | 
			
		||||
					if (data) {
 | 
			
		||||
						cc.log(`[RPC] 收到server呼叫:(${resp.Status}): ${resp.Method}(${JSON.stringify(resp.Data)})`);
 | 
			
		||||
					} else {
 | 
			
		||||
						cc.log(`[RPC] 收到server呼叫:(${resp.Status}): ${resp.Method}()`);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				let dispatch = true;
 | 
			
		||||
				for (let i = 0, len = this._waitings.length; i < len; i++) {
 | 
			
		||||
					let w = this._waitings[i];
 | 
			
		||||
					if (w.MethodBack === resp.Method) {
 | 
			
		||||
						dispatch = false;
 | 
			
		||||
						this._waitings.splice(i, 1);
 | 
			
		||||
						w.SetResponse(resp);
 | 
			
		||||
						this.OnLoadUIMask.DispatchCallback(false);
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (dispatch) {
 | 
			
		||||
					this.OnDataReceived.DispatchCallback(resp);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			catch
 | 
			
		||||
			{
 | 
			
		||||
				throw new Error(`[RPC] 無法解析Server回應: ${str}`);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private OnWebSocketClose(e: CloseEvent) {
 | 
			
		||||
		this.WebSocketEnded();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ErrorResponse: INetResponse<any> = {
 | 
			
		||||
	Status: -1,
 | 
			
		||||
	Method: "",
 | 
			
		||||
	Data: {},
 | 
			
		||||
	IsValid: false,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class WsConnectEnumerator extends BaseEnumerator {
 | 
			
		||||
	private _ws: WebSocket;
 | 
			
		||||
 | 
			
		||||
	constructor(ws: WebSocket) {
 | 
			
		||||
		super();
 | 
			
		||||
		this._ws = ws;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	next(value?: any): IteratorResult<any> {
 | 
			
		||||
		return {
 | 
			
		||||
			done: this._ws.readyState === WebSocket.OPEN || this._ws.readyState === WebSocket.CLOSED,
 | 
			
		||||
			value: undefined
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class WsRequestEnumerator extends BaseEnumerator {
 | 
			
		||||
	readonly MethodBack: string;
 | 
			
		||||
 | 
			
		||||
	private _req: INetRequest<any, any>;
 | 
			
		||||
	private _done: boolean = false;
 | 
			
		||||
 | 
			
		||||
	constructor(req: INetRequest<any, any>) {
 | 
			
		||||
		super();
 | 
			
		||||
 | 
			
		||||
		this._req = req;
 | 
			
		||||
		this.MethodBack = req.MethodBack;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	SetResponse(resp: INetResponse<any>) {
 | 
			
		||||
		this._req.Result = resp;
 | 
			
		||||
		this._done = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	next(value?: any): IteratorResult<any> {
 | 
			
		||||
		return {
 | 
			
		||||
			done: this._done,
 | 
			
		||||
			value: undefined
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "221e1688-cc40-450d-9248-464978540a85",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								assets/Script/Engine/CatanEngine/NetManagerV2/NetManager.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								assets/Script/Engine/CatanEngine/NetManagerV2/NetManager.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
import { INetRequest } from "./Core/INetRequest";
 | 
			
		||||
import { NetConnector } from "./NetConnector";
 | 
			
		||||
 | 
			
		||||
export class NetManager {
 | 
			
		||||
    static get IsConnected() { return this._connector && this._connector.IsConnected; }
 | 
			
		||||
    static get HasInit() { return this._connector != null; }
 | 
			
		||||
 | 
			
		||||
    private static _connector: NetConnector;
 | 
			
		||||
 | 
			
		||||
    static Initialize(connector: NetConnector) {
 | 
			
		||||
        this._connector = connector;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static ConnectAsync() {
 | 
			
		||||
        this.CheckConnector();
 | 
			
		||||
        return this._connector.ConnectAsync();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 斷線
 | 
			
		||||
     */
 | 
			
		||||
    static Disconnect() {
 | 
			
		||||
        this.CheckConnector();
 | 
			
		||||
        this._connector.Disconnect();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 傳送資料給Server, 不等待回應
 | 
			
		||||
     * @param req
 | 
			
		||||
     */
 | 
			
		||||
    static Send(req: INetRequest<any, any>) {
 | 
			
		||||
        this.CheckConnector();
 | 
			
		||||
        this._connector.Send(req);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 傳送資料給Server, 並等待回應
 | 
			
		||||
     * @param req
 | 
			
		||||
     */
 | 
			
		||||
    static SendAsync(req: INetRequest<any, any>,mask:boolean) {
 | 
			
		||||
        this.CheckConnector();
 | 
			
		||||
        return this._connector.SendAsync(req,mask);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static CheckConnector()
 | 
			
		||||
    {
 | 
			
		||||
        if (!this._connector) throw new Error("請先呼叫CasinoNetManager.Initialize()初始化connector");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "7c3e375d-3672-42e7-8a45-dd5ecf9d5fe8",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								assets/Script/Engine/CatanEngine/NetManagerV2/NetRequest.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								assets/Script/Engine/CatanEngine/NetManagerV2/NetRequest.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
import { INetRequest } from "./Core/INetRequest";
 | 
			
		||||
import { NetManager } from "./NetManager";
 | 
			
		||||
 | 
			
		||||
export abstract class NetRequest<TResquest, TResponse> implements INetRequest<TResquest, TResponse> {
 | 
			
		||||
    abstract get Method(): string;
 | 
			
		||||
 | 
			
		||||
    get MethodBack(): string {
 | 
			
		||||
        return this.Method;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Data: TResquest;
 | 
			
		||||
    Result: import("./Core/INetResponse").INetResponse<TResponse>;
 | 
			
		||||
 | 
			
		||||
    SendAsync(mask: boolean = false): Iterator<any> {
 | 
			
		||||
        return NetManager.SendAsync(this, mask);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Send() {
 | 
			
		||||
        NetManager.Send(this);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "36534597-4273-48e8-bbeb-8dde4857d26f",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										81
									
								
								assets/Script/Engine/CatanEngine/NoSleep.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								assets/Script/Engine/CatanEngine/NoSleep.ts
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										9
									
								
								assets/Script/Engine/CatanEngine/NoSleep.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								assets/Script/Engine/CatanEngine/NoSleep.ts.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "90f2152c-2c37-4c7c-b3a3-04c8aee53c34",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								assets/Script/Engine/CatanEngine/TableV3.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								assets/Script/Engine/CatanEngine/TableV3.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.1.2",
 | 
			
		||||
  "uuid": "8e05805d-5ab8-4526-8463-f4c837e23534",
 | 
			
		||||
  "isBundle": false,
 | 
			
		||||
  "bundleName": "",
 | 
			
		||||
  "priority": 1,
 | 
			
		||||
  "compressionType": {},
 | 
			
		||||
  "optimizeHotUpdate": {},
 | 
			
		||||
  "inlineSpriteFrames": {},
 | 
			
		||||
  "isRemoteBundle": {},
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								assets/Script/Engine/CatanEngine/TableV3/Core.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								assets/Script/Engine/CatanEngine/TableV3/Core.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.1.2",
 | 
			
		||||
  "uuid": "3d4ae989-9f9b-429a-a331-191a8cd8193d",
 | 
			
		||||
  "isBundle": false,
 | 
			
		||||
  "bundleName": "",
 | 
			
		||||
  "priority": 1,
 | 
			
		||||
  "compressionType": {},
 | 
			
		||||
  "optimizeHotUpdate": {},
 | 
			
		||||
  "inlineSpriteFrames": {},
 | 
			
		||||
  "isRemoteBundle": {},
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,4 @@
 | 
			
		||||
export interface ITableJson {
 | 
			
		||||
    cols: string[],
 | 
			
		||||
    rows: any[],
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "c5f8c44b-0b24-4f57-b229-4c3ad9301236",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								assets/Script/Engine/CatanEngine/TableV3/Core/ITableRow.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								assets/Script/Engine/CatanEngine/TableV3/Core/ITableRow.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
export interface ITableRow {
 | 
			
		||||
    Id: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 表沒有欄位
 | 
			
		||||
 */
 | 
			
		||||
export class WithoutRow implements ITableRow {
 | 
			
		||||
    Id: number;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "104d86f0-0cb9-4cd1-a305-44ea90ee3d7f",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								assets/Script/Engine/CatanEngine/TableV3/Core/TableBase.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								assets/Script/Engine/CatanEngine/TableV3/Core/TableBase.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
import { ITableRow } from "./ITableRow";
 | 
			
		||||
 | 
			
		||||
export abstract class TableBase<TRow extends ITableRow> extends Array<TRow> {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        super();
 | 
			
		||||
        Object.setPrototypeOf(this, new.target.prototype);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**欄位數量 */
 | 
			
		||||
    public get Count(): number { return this.length; }
 | 
			
		||||
    /**取得全部鍵值 */
 | 
			
		||||
    public get Keys(): string[] { return Object.keys(this); }
 | 
			
		||||
    /**取得全部欄位值 */
 | 
			
		||||
    public get Rows(): Array<TRow> { return Object["values"](this); }
 | 
			
		||||
    // public get Rows(): Array<TRow> { return this; }
 | 
			
		||||
    
 | 
			
		||||
    /**是否包含該Id值的欄位 */
 | 
			
		||||
    public ContainsRow(id: number): boolean {
 | 
			
		||||
        return id in this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "e4f18713-244f-4375-b77a-c26bf197cd3f",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								assets/Script/Engine/CatanEngine/TableV3/Examples.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								assets/Script/Engine/CatanEngine/TableV3/Examples.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.1.2",
 | 
			
		||||
  "uuid": "4a176b88-26e0-42ae-8acc-42ab2e942ace",
 | 
			
		||||
  "isBundle": false,
 | 
			
		||||
  "bundleName": "",
 | 
			
		||||
  "priority": 1,
 | 
			
		||||
  "compressionType": {},
 | 
			
		||||
  "optimizeHotUpdate": {},
 | 
			
		||||
  "inlineSpriteFrames": {},
 | 
			
		||||
  "isRemoteBundle": {},
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
import { TableManager } from "../TableManager";
 | 
			
		||||
import { StringExampleTableRow, StringTableExample } from "./Tables/StringTableExample";
 | 
			
		||||
 | 
			
		||||
const { ccclass } = cc._decorator;
 | 
			
		||||
 | 
			
		||||
@ccclass
 | 
			
		||||
export default class CSSettingsV3Example {
 | 
			
		||||
 | 
			
		||||
	private static _stringExample: StringTableExample;
 | 
			
		||||
	/** 共用_字串表#string.xlsx */
 | 
			
		||||
	public static get StringExample(): StringTableExample { return this._stringExample = this._stringExample || TableManager.InitTable("#string", StringTableExample, StringExampleTableRow); }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "04f57003-d6a1-4fee-adf8-69994db08f05",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,82 @@
 | 
			
		||||
import CSSettingsV3Example from "./CSSettingsV3Example";
 | 
			
		||||
import { StringExampleTable } from "./Tables/StringTableExample";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const { ccclass, property } = cc._decorator;
 | 
			
		||||
 | 
			
		||||
@ccclass
 | 
			
		||||
export default class TableUseExample extends cc.Component {
 | 
			
		||||
 | 
			
		||||
    start() {
 | 
			
		||||
 | 
			
		||||
        //#region StringExample表
 | 
			
		||||
        cc.log("----------------#stringExample");
 | 
			
		||||
        cc.log(CSSettingsV3Example.StringExample instanceof StringExampleTable); // true
 | 
			
		||||
        cc.log(Array.isArray(CSSettingsV3Example.StringExample)); // true, 所以Array相關的方法都可以拿來操作
 | 
			
		||||
 | 
			
		||||
        cc.log(CSSettingsV3Example.StringExample.length);
 | 
			
		||||
        cc.log(CSSettingsV3Example.StringExample.Count); // 跟length一樣
 | 
			
		||||
 | 
			
		||||
        cc.log(CSSettingsV3Example.StringExample.ContainsRow(11)); // 是否包含id=11的Row
 | 
			
		||||
        cc.log(11 in CSSettingsV3Example.StringExample); // 同上
 | 
			
		||||
 | 
			
		||||
        cc.log(CSSettingsV3Example.StringExample[1].MsgZnCh);
 | 
			
		||||
        cc.log(CSSettingsV3Example.StringExample[1]["MsgZnCh"]); // 同上
 | 
			
		||||
        cc.log(CSSettingsV3Example["StringExample"][1]["MsgZnCh"]); // 同上
 | 
			
		||||
 | 
			
		||||
        cc.log("----------------");
 | 
			
		||||
        for (let row of CSSettingsV3Example.StringExample) {
 | 
			
		||||
            if (row) { // 如果Row沒有連號, 那有可能取到undefined值, 要先判斷, 不想判斷就用 CSSettings.StringExample.Rows
 | 
			
		||||
                cc.log(row.Id, row.MsgZnCh);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        cc.log("----------------");
 | 
			
		||||
        for (let id of CSSettingsV3Example.StringExample.Keys) {
 | 
			
		||||
            cc.log(id); // 只會列出有值的id, undefined會跳過
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        cc.log("----------------");
 | 
			
		||||
        for (let row of CSSettingsV3Example.StringExample.Rows) {
 | 
			
		||||
            cc.log(row.Id, row.MsgZnCh); // 只會列出有值的Row, undefined會跳過
 | 
			
		||||
        }
 | 
			
		||||
        //#endregion
 | 
			
		||||
 | 
			
		||||
        //#region StringExample表 #StringFilter表
 | 
			
		||||
        cc.log("----------------#stringExample#string_filter");
 | 
			
		||||
        //cc.log(CSSettings.StringExample.StringFilter instanceof StringFilterTable); // true
 | 
			
		||||
        cc.log(Array.isArray(CSSettingsV3Example.StringExample.StringFilter)); // true, 所以Array相關的方法都可以拿來操作
 | 
			
		||||
 | 
			
		||||
        cc.log(CSSettingsV3Example.StringExample.StringFilter.length);
 | 
			
		||||
        cc.log(CSSettingsV3Example.StringExample.StringFilter.Count); // 跟length一樣
 | 
			
		||||
 | 
			
		||||
        cc.log(CSSettingsV3Example.StringExample.StringFilter.ContainsRow(11)); // 是否包含id=11的Row
 | 
			
		||||
        cc.log(11 in CSSettingsV3Example.StringExample.StringFilter); // 同上
 | 
			
		||||
 | 
			
		||||
        cc.log(CSSettingsV3Example.StringExample.StringFilter[1].FilterWord);
 | 
			
		||||
        cc.log(CSSettingsV3Example.StringExample.StringFilter[1]["FilterWord"]); // 同上
 | 
			
		||||
        cc.log(CSSettingsV3Example["StringExample"]["StringFilter"][1]["FilterWord"]); // 同上
 | 
			
		||||
 | 
			
		||||
        cc.log("----------------");
 | 
			
		||||
        for (let row of CSSettingsV3Example.StringExample.StringFilter) {
 | 
			
		||||
            if (row) { // 如果Row沒有連號, 那有可能取到undefined值, 要先判斷, 不想判斷就用 CSSettings.StringExample.StringFilter.Rows
 | 
			
		||||
                cc.log(row.Id, row.FilterWord);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        cc.log("----------------");
 | 
			
		||||
        for (let id of CSSettingsV3Example.StringExample.StringFilter.Keys) {
 | 
			
		||||
            cc.log(id); // 只會列出有值的id, undefined會跳過
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        cc.log("----------------");
 | 
			
		||||
        for (let row of CSSettingsV3Example.StringExample.StringFilter.Rows) {
 | 
			
		||||
            cc.log(row.Id, row.FilterWord); // 只會列出有值的Row, undefined會跳過
 | 
			
		||||
        }
 | 
			
		||||
        //#endregion
 | 
			
		||||
 | 
			
		||||
        cc.log("----------------");
 | 
			
		||||
        //CSSettingsV3.ResetTables(); // 重置表
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "27d36ad6-da65-4673-abdb-4635a1a3d3a8",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.1.2",
 | 
			
		||||
  "uuid": "e65b6243-578c-4cea-ac46-1dfd4d455017",
 | 
			
		||||
  "isBundle": false,
 | 
			
		||||
  "bundleName": "",
 | 
			
		||||
  "priority": 1,
 | 
			
		||||
  "compressionType": {},
 | 
			
		||||
  "optimizeHotUpdate": {},
 | 
			
		||||
  "inlineSpriteFrames": {},
 | 
			
		||||
  "isRemoteBundle": {},
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,45 @@
 | 
			
		||||
import { ITableRow } from "../../Core/ITableRow";
 | 
			
		||||
import { TableBase } from "../../Core/TableBase";
 | 
			
		||||
import { TableManager } from "../../TableManager";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 共用_字串表#string.xlsx
 | 
			
		||||
 * ##程式碼由工具產生, 在此做的修改都將被覆蓋##
 | 
			
		||||
 */
 | 
			
		||||
export class StringTableExample extends TableBase<StringExampleTableRow> {
 | 
			
		||||
	private _stringFilter: StringFilterTable;
 | 
			
		||||
	/**  共用_字串表#string.xlsx > #string_filter */
 | 
			
		||||
	public get StringFilter(): StringFilterTable { return this._stringFilter = this._stringFilter || TableManager.InitTable("#string#string_filter", StringFilterTable, StringFilterTableRow); }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * #string
 | 
			
		||||
 */
 | 
			
		||||
export class StringExampleTable extends TableBase<StringExampleTableRow> {}
 | 
			
		||||
 | 
			
		||||
export class StringExampleTableRow implements ITableRow {
 | 
			
		||||
	/** 編號 */
 | 
			
		||||
	Id: number;
 | 
			
		||||
	/** 英文訊息 */
 | 
			
		||||
	MsgEn: string;
 | 
			
		||||
	/** 繁體中文訊息 */
 | 
			
		||||
	MsgZnTw: string;
 | 
			
		||||
	/** 簡體中文讯息 */
 | 
			
		||||
	MsgZnCh: string;
 | 
			
		||||
	/** 越南文讯息 */
 | 
			
		||||
	MsgVi: string;
 | 
			
		||||
	/** 泰文讯息 */
 | 
			
		||||
	MsgTh: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * #string_filter
 | 
			
		||||
 */
 | 
			
		||||
export class StringFilterTable extends TableBase<StringFilterTableRow> {}
 | 
			
		||||
 | 
			
		||||
export class StringFilterTableRow implements ITableRow {
 | 
			
		||||
	/** 編號 */
 | 
			
		||||
	Id: number;
 | 
			
		||||
	/** 過濾字串 */
 | 
			
		||||
	FilterWord: string;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "c4bea919-96cd-40ee-a5f7-d9327414b1b2",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								assets/Script/Engine/CatanEngine/TableV3/TableManager.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								assets/Script/Engine/CatanEngine/TableV3/TableManager.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
import { ITableJson } from "./Core/ITableJson";
 | 
			
		||||
import { ITableRow } from "./Core/ITableRow";
 | 
			
		||||
 | 
			
		||||
export class TableManager {
 | 
			
		||||
    private static _tableJsons: { [key: string]: ITableJson } = {};
 | 
			
		||||
 | 
			
		||||
    public static AddJsonAssets(jsonAssets: cc.JsonAsset[]) {
 | 
			
		||||
        if (!jsonAssets) return;
 | 
			
		||||
        let newAssets: cc.JsonAsset[] = jsonAssets.concat();
 | 
			
		||||
        for (let jsonAsset of newAssets) {
 | 
			
		||||
            this.AddJsonAsset(jsonAsset);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static AddJsonAsset(jsonAsset: cc.JsonAsset) {
 | 
			
		||||
        if (!jsonAsset) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        for (let tableName in jsonAsset.json) {
 | 
			
		||||
            console.log(`TableV3 [${tableName}] json loaded`);
 | 
			
		||||
            this._tableJsons[tableName] = jsonAsset.json[tableName];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static GetTable(name: string): ITableJson {
 | 
			
		||||
        return this._tableJsons[name];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static InitTable<T extends Array<ITableRow>>(name: string, tableType: { new(): T }, rowType: { new(): ITableRow }): T {
 | 
			
		||||
        let json = this._tableJsons[name];
 | 
			
		||||
        if (!json) {
 | 
			
		||||
            throw new Error(`TableV3 [${name}] 尚未載入json檔`);
 | 
			
		||||
        }
 | 
			
		||||
        let table = new tableType();
 | 
			
		||||
        let cols = json.cols;
 | 
			
		||||
        let colLength = cols.length;
 | 
			
		||||
        let rows = json.rows;
 | 
			
		||||
        for (let r of rows) {
 | 
			
		||||
            let trow = new rowType();
 | 
			
		||||
            for (let i = 0; i < colLength; i++) {
 | 
			
		||||
                trow[cols[i]] = r[i];
 | 
			
		||||
            }
 | 
			
		||||
            table[trow.Id] = trow;
 | 
			
		||||
        }
 | 
			
		||||
        //cc.log(`TableV3 [${name}] init done`);
 | 
			
		||||
        return table;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "1.0.8",
 | 
			
		||||
  "uuid": "f3bcfb76-6225-4757-a039-9018806ef54e",
 | 
			
		||||
  "isPlugin": false,
 | 
			
		||||
  "loadPluginInWeb": true,
 | 
			
		||||
  "loadPluginInNative": true,
 | 
			
		||||
  "loadPluginInEditor": false,
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										0
									
								
								assets/Script/Engine/CatanEngine/公司自架接功能.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								assets/Script/Engine/CatanEngine/公司自架接功能.txt
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										5
									
								
								assets/Script/Engine/CatanEngine/公司自架接功能.txt.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								assets/Script/Engine/CatanEngine/公司自架接功能.txt.meta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
  "ver": "2.0.0",
 | 
			
		||||
  "uuid": "6ab253ff-8c5d-419f-9f8b-5cf0ef661a28",
 | 
			
		||||
  "subMetas": {}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user