This PR gives users greater flexibility with Excalibur Coroutines!
* Optionally ask coroutines not to start immediately
```typescript
ex.coroutine(function* () { .. }, { autostart: false });
```
* New `CoroutineInstance` is returned that is also awaitable
```typescript
export interface CoroutineOptions {
timing?: ScheduledCallbackTiming;
autostart?: boolean;
}
export interface CoroutineInstance extends PromiseLike<void> {
isRunning(): boolean;
isComplete(): boolean;
done: Promise<void>;
generator: Generator<CoroutineInstance | number | Promise<any> | undefined, void, number>;
start: () => CoroutineInstance;
cancel: () => void;
then: Thenable;
[Symbol.iterator]: () => Generator<CoroutineInstance | number | Promise<any> | undefined, void, number>;
}
```
```typescript
const co = ex.coroutine(function* () {
yield 100;
});
await co; // wait for coroutine to finish
```
* `start()`/`cancel()`coroutines
```typescript
const co = ex.coroutine(function* () {
yield 100;
});
co.start();
co.cancel();
await co;
```
* nested coroutines! (Nested coroutines do not start running, they are run with their parent)
```typescript
const result = ex.coroutine(function* () {
yield 100;
yield* ex.coroutine(function* () {
const elapsed = yield 99;
});
yield 100;
});
```