[add] Engine
This commit is contained in:
@@ -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,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "9a414131-91a8-4d02-9921-9d1ee01764c3",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
13
assets/Script/Engine/CatanEngine/CoroutineV2/Core.meta
Normal file
13
assets/Script/Engine/CatanEngine/CoroutineV2/Core.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "1.1.3",
|
||||
"uuid": "fbfe97a8-24ca-4f67-b049-323652c7194b",
|
||||
"importer": "folder",
|
||||
"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,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "3cf9e5c3-520f-48a9-8821-9be76d519765",
|
||||
"importer": "typescript",
|
||||
"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,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "4084537c-c7e8-4d47-b283-39be77ef9685",
|
||||
"importer": "typescript",
|
||||
"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,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "f25b1e42-90d8-4fc0-9925-6e7e92296d57",
|
||||
"importer": "typescript",
|
||||
"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,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "91cb70ed-e6f9-4ce0-b7c5-1720087b3bd7",
|
||||
"importer": "typescript",
|
||||
"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,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "017ebc9a-5152-4f94-bbaf-e3b914e87b41",
|
||||
"importer": "typescript",
|
||||
"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,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "c439d019-2da8-48b8-a65b-bff928d0fda8",
|
||||
"importer": "typescript",
|
||||
"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,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "a3038e6f-1bb4-4aff-a686-b69209df3592",
|
||||
"importer": "typescript",
|
||||
"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,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "dfd32c11-76f6-4e38-9272-1d7966d1ef3c",
|
||||
"importer": "typescript",
|
||||
"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,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "fc38e505-bd37-44c3-9e0a-fd463bb88c51",
|
||||
"importer": "typescript",
|
||||
"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,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "df3ab07d-3d2b-4552-b454-29b95223ea85",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
Reference in New Issue
Block a user