Skip to content

Commit

Permalink
feat(animation): RenderLoop
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Strauß committed Jan 30, 2018
1 parent 8b82ffd commit b26a769
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 0 deletions.
98 changes: 98 additions & 0 deletions src/animation/rendering.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
goog.module('clulib.animation.rendering');

const EventTarget = goog.require('goog.events.EventTarget');
const Event = goog.require('goog.events.Event');

/**
* A render loop which runs on requestAnimationFrame.
*
* Dispatches RenderLoopEvents
*/
class RenderLoop extends EventTarget {
constructor () {
super();

/**
* @type {boolean}
* @private
*/
this.isRunning_ = false;

/**
* @type {?number}
* @private
*/
this.id_ = null;
}

/**
* @returns {boolean}
*/
get isRunning () {
return this.isRunning_;
}

start () {
if (this.isRunning_)
return;
this.id_ = window.requestAnimationFrame(this.tick_.bind(this));
this.isRunning_ = true;
this.dispatchEvent(new RenderLoopEvent(RenderLoopEventType.START, this));
}

/**
* @param {number} highResolutionTimestamp
* @private
*/
tick_ (highResolutionTimestamp) {
this.dispatchEvent(new RenderLoopEvent(RenderLoopEventType.TICK, this, highResolutionTimestamp));
}

stop () {
if (!this.isRunning_)
return;
window.cancelAnimationFrame(/** @type {number} */ (this.id_));
this.isRunning_ = false;
this.dispatchEvent(new RenderLoopEvent(RenderLoopEventType.END, this));
}
}

/**
* The event for RenderLoop. Holds the elapsed time.
*/
class RenderLoopEvent extends Event {
/**
* @param {RenderLoopEventType} type
* @param {RenderLoop} target
* @param {number=} elapsedTime
*/
constructor (type, target, elapsedTime) {
super(type, target);

/**
* @type {?number}
* @private
*/
this.elapsedTime_ = /** @type {?number} */ (elapsedTime);
}

/**
* The elapsed time since the last tick in milliseconds.
*
* @returns {?number}
*/
get elapsedTime () {
return this.elapsedTime_;
}
}

/**
* @enum {string}
*/
const RenderLoopEventType = {
START: 'start',
TICK: 'tick',
END: 'end'
};

exports = {RenderLoop, RenderLoopEvent, RenderLoopEventType};
52 changes: 52 additions & 0 deletions test/animation/rendering.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
goog.module('test.clulib.animation.rendering');

const {RenderLoop, RenderLoopEventType} = goog.require('clulib.animation.rendering');

/**
* @param {number} ms
* @returns {Promise<void>}
*/
const waitFor = function (ms) {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, ms);
});
};

exports = function () {
describe('clulib.animation.rendering', () => {
describe('RenderLoop', () => {
it('should dispatch tick events', async () => {
const loop = new RenderLoop();
let started = false;
let ticked = false;
let ended = false;
let elapsedTime = 0;

loop.addEventListener(RenderLoopEventType.START, () => {
started = true;
});

loop.addEventListener(RenderLoopEventType.TICK, event => {
ticked = true;
elapsedTime = event.elapsedTime;
loop.stop();
});

loop.addEventListener(RenderLoopEventType.END, () => {
ended = true;
});

loop.start();

await waitFor(1000);

expect(started).toBe(true);
expect(ticked).toBe(true);
expect(ended).toBe(true);
expect(elapsedTime > 0).toBe(true);
});
});
});
};
2 changes: 2 additions & 0 deletions test/test_main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
goog.module('test.main');

const renderingMain = goog.require('test.clulib.animation.rendering');
const arrayMain = goog.require('test.clulib.array');
const asyncCompleterMain = goog.require('test.clulib.async.Completer');
const cmMain = goog.require('test.clulib.cm');
Expand All @@ -11,6 +12,7 @@ const resourceManagerMain = goog.require('test.clulib.l10n.ResourceManager');
const httpRequestMain = goog.require('test.clulib.net.http_request');
const mathMain = goog.require('test.clulib.math');

renderingMain();
arrayMain();
asyncCompleterMain();
cmMain();
Expand Down

0 comments on commit b26a769

Please sign in to comment.