Skip to content

Commit

Permalink
fix: [#1864] [#1865] Timer.start() must be called + rename Timer.unpa…
Browse files Browse the repository at this point in the history
…use() -> Timer.resume()
  • Loading branch information
eonarheim committed Jun 27, 2021
1 parent 3ec9698 commit 6df7ed1
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 77 deletions.
22 changes: 11 additions & 11 deletions src/engine/Scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -494,18 +494,17 @@ export class Scene extends Class implements CanInitialize, CanActivate, CanDeact
this.actors.push(entity);
}
// TODO remove after collision ecs
entity.children.forEach(c => this.add(c));
entity.children.forEach((c) => this.add(c));
entity.childrenAdded$.register({
notify: (e => {
notify: (e) => {
this.add(e);
})
}
});
entity.childrenRemoved$.register({
notify: (e => {
notify: (e) => {
this.remove(e);
})
}
});

}
return;
}
Expand Down Expand Up @@ -577,7 +576,7 @@ export class Scene extends Class implements CanInitialize, CanActivate, CanDeact
* @todo Should this be `ScreenElement` only?
* @deprecated Use [[Scene.add]]
*/
@obsolete({message: 'Will be removed in excalibur v0.26.0', alternateMethod: 'Use Scene.add'})
@obsolete({ message: 'Will be removed in excalibur v0.26.0', alternateMethod: 'Use Scene.add' })
public addScreenElement(actor: Actor) {
this.add(actor);
}
Expand All @@ -586,7 +585,7 @@ export class Scene extends Class implements CanInitialize, CanActivate, CanDeact
* Removes an actor as a piece of UI
* @deprecated Use [[Scene.remove]]
*/
@obsolete({message: 'Will be removed in excalibur v0.26.0', alternateMethod: 'Use Scene.remove'})
@obsolete({ message: 'Will be removed in excalibur v0.26.0', alternateMethod: 'Use Scene.remove' })
public removeScreenElement(actor: Actor) {
this.remove(actor);
}
Expand All @@ -595,7 +594,7 @@ export class Scene extends Class implements CanInitialize, CanActivate, CanDeact
* Adds a [[TileMap]] to the scene, once this is done the TileMap will be drawn and updated.
* @deprecated Use [[Scene.add]]
*/
@obsolete({message: 'Will be removed in excalibur v0.26.0', alternateMethod: 'Use Scene.add'})
@obsolete({ message: 'Will be removed in excalibur v0.26.0', alternateMethod: 'Use Scene.add' })
public addTileMap(tileMap: TileMap) {
this.tileMaps.push(tileMap);
this.world.add(tileMap);
Expand All @@ -605,7 +604,7 @@ export class Scene extends Class implements CanInitialize, CanActivate, CanDeact
* Removes a [[TileMap]] from the scene, it will no longer be drawn or updated.
* @deprecated Use [[Scene.remove]]
*/
@obsolete({message: 'Will be removed in excalibur v0.26.0', alternateMethod: 'Use Scene.remove'})
@obsolete({ message: 'Will be removed in excalibur v0.26.0', alternateMethod: 'Use Scene.remove' })
public removeTileMap(tileMap: TileMap) {
const index = this.tileMaps.indexOf(tileMap);
if (index > -1) {
Expand Down Expand Up @@ -668,7 +667,8 @@ export class Scene extends Class implements CanInitialize, CanActivate, CanDeact
for (const actor of this.actors) {
engine.stats.currFrame.actors.alive++;
for (const child of actor.children) {
if (ActorUtils.isScreenElement(child as Actor)) { // TODO not true
if (ActorUtils.isScreenElement(child as Actor)) {
// TODO not true
engine.stats.currFrame.actors.ui++;
} else {
engine.stats.currFrame.actors.alive++;
Expand Down
108 changes: 93 additions & 15 deletions src/engine/Timer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Scene } from './Scene';
import { obsolete } from './Util/Decorators';
import { Logger } from './Util/Log';

export interface TimerOptions {
repeats?: boolean;
Expand All @@ -12,17 +14,26 @@ export interface TimerOptions {
* after a certain interval, optionally repeating.
*/
export class Timer {
public static id: number = 0;
private _logger = Logger.getInstance();
private static _MAX_ID: number = 0;
public id: number = 0;
public interval: number = 10;
public repeats: boolean = false;
public maxNumberOfRepeats: number = -1;

private _elapsedTime: number = 0;
private _totalTimeAlive: number = 0;
private _paused: boolean = false;

private _running = false;

private _numberOfTicks: number = 0;
private _callbacks: Array<() => void>;
public complete: boolean = false;

public interval: number = 10;
public repeats: boolean = false;
public maxNumberOfRepeats: number = -1;

private _complete = false;
public get complete() {
return this._complete;
}
public scene: Scene = null;

/**
Expand All @@ -48,7 +59,7 @@ export class Timer {
}
}

this.id = Timer.id++;
this.id = Timer._MAX_ID++;
this.interval = interval || this.interval;
this.repeats = repeats || this.repeats;

Expand Down Expand Up @@ -81,12 +92,14 @@ export class Timer {
* @param delta Number of elapsed milliseconds since the last update.
*/
public update(delta: number) {
if (!this._paused) {
if (this._running) {
this._totalTimeAlive += delta;
this._elapsedTime += delta;

if (this.maxNumberOfRepeats > -1 && this._numberOfTicks >= this.maxNumberOfRepeats) {
this.complete = true;
this._complete = true;
this._running = false;
this._elapsedTime = 0;
}

if (!this.complete && this._elapsedTime >= this.interval) {
Expand All @@ -98,14 +111,18 @@ export class Timer {
if (this.repeats) {
this._elapsedTime = 0;
} else {
this.complete = true;
this._complete = true;
this._running = false;
this._elapsedTime = 0;
}
}
}
}

/**
* Resets the timer so that it can be reused, and optionally reconfigure the timers interval.
*
* Warning** you may need to call `timer.start()` again if the timer had completed
* @param newInterval If specified, sets a new non-negative interval in milliseconds to refire the callback
* @param newNumberOfRepeats If specified, sets a new non-negative upper limit to the number of time this timer executes
*/
Expand All @@ -121,7 +138,7 @@ export class Timer {
}
}

this.complete = false;
this._complete = false;
this._elapsedTime = 0;
this._numberOfTicks = 0;
}
Expand All @@ -135,23 +152,84 @@ export class Timer {
}

/**
* Pauses the timer so that no more time will be incremented towards the next call
* @returns milliseconds until the next action callback, if complete will return 0
*/
public get timeToNextAction() {
if (this.complete) {
return 0;
}
return this.interval - this._elapsedTime;
}

/**
* @returns milliseconds elapsed toward the next action
*/
public get timeElapsedTowardNextAction() {
return this._elapsedTime;
}

public get isRunning() {
return this._running;
}

/**
* Pauses the timer, time will no longer increment towards the next call
*/
public pause() {
this._paused = true;
public pause(): Timer {
this._running = false;
return this;
}

/**
* Unpauses the timer. Time will now increment towards the next call
* @deprecated Will be removed in v0.26.0
*/
@obsolete({ message: 'Will be removed in v0.26.0', alternateMethod: 'Use Timer.resume()' })
public unpause() {
this._paused = false;
this._running = true;
}

/**
* Resumes the timer, time will now increment towards the next call.
*/
public resume(): Timer {
this._running = true;
return this;
}

/**
* Starts the timer, if the timer was complete it will restart the timer and reset the elapsed time counter
*/
public start(): Timer {
if (!this.scene) {
this._logger.warn('Cannot start a timer not part of a scene, timer wont start until added');
}

this._running = true;
if (this.complete) {
this._complete = false;
this._elapsedTime = 0;
this._numberOfTicks = 0;
}

return this;
}

/**
* Stops the timer and resets the elapsed time counter towards the next action invocation
*/
public stop(): Timer {
this._running = false;
this._elapsedTime = 0;
this._numberOfTicks = 0;
return this;
}

/**
* Cancels the timer, preventing any further executions.
*/
public cancel() {
this.pause();
if (this.scene) {
this.scene.cancelTimer(this);
}
Expand Down
28 changes: 14 additions & 14 deletions src/spec/CollisionSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ describe('A Collision', () => {

it('should recognize when actor bodies are touching', () => {
let touching = false;
actor1.on('postupdate', function() {
actor1.on('postupdate', function () {
if (actor1.body.collider.touching(actor2.body.collider)) {
touching = true;
}
Expand All @@ -209,17 +209,17 @@ describe('A Collision', () => {
engine.add(passiveBlock);

const collisionHandler = (ev: ex.PreCollisionEvent) => {
engine.add(
new ex.Timer({
interval: 30,
fcn: () => {
expect(activeBlock.vel.x).toBeGreaterThan(0);
expect(passiveBlock.vel.x).toBeLessThan(0);
done();
},
repeats: false
})
);
const timer = new ex.Timer({
interval: 30,
fcn: () => {
expect(activeBlock.vel.x).toBeGreaterThan(0);
expect(passiveBlock.vel.x).toBeLessThan(0);
done();
},
repeats: false
});
timer.start();
engine.add(timer);
};

activeBlock.once('precollision', collisionHandler);
Expand Down Expand Up @@ -337,7 +337,7 @@ describe('A Collision', () => {
passiveBlock.vel = ex.vec(-100, activeBlock.vel.y);
engine.add(passiveBlock);

const collisionEnd = function() {
const collisionEnd = function () {
expect(this).toBe(activeBlock);
done();
};
Expand All @@ -362,7 +362,7 @@ describe('A Collision', () => {
passiveBlock.vel = ex.vec(-100, activeBlock.vel.y);
engine.add(passiveBlock);

const collisionEnd = function() {
const collisionEnd = function () {
expect(this).toBe(activeBlock);
done();
};
Expand Down
3 changes: 3 additions & 0 deletions src/spec/SceneSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ describe('A scene', () => {
});

scene.add(timer);
timer.start();
scene.update(engine, 11);
scene.draw(engine.ctx, 11);

Expand Down Expand Up @@ -479,6 +480,7 @@ describe('A scene', () => {
});

scene.add(timer);
timer.start();
scene.update(engine, 11);
scene.draw(engine.ctx, 11);

Expand Down Expand Up @@ -537,6 +539,7 @@ describe('A scene', () => {
});

scene.add(timer);
timer.start();
scene.update(engine, 11);
scene.draw(engine.ctx, 11);

Expand Down
Loading

0 comments on commit 6df7ed1

Please sign in to comment.