/**
* Interface added to `LfoCore to implement source
*
* Source have some responsability on graph as they mostly control its whole
* lifecycle. They must implement the start and stop method in order to
* make sure the graph is initialized and set `started` to true.
* A source should never accept and propagate incomming frames until `started`
* is set to `true`.
*
* @name SourceMixin
* @memberof module:core
* @mixin
*
* @example
* class MySource extends SourceMixin(BaseLfo) {}
*/
const SourceMixin = (superclass) => class extends superclass {
constructor(...args) {
super(...args);
this.initialized = false;
this.initPromise = null;
this.started = false;
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
}
/**
* Initialize the graph by calling `initModule`. When the returned `Promise`
* fulfills, the graph can be considered as initialized and `start` can be
* called safely. If `start` is called whithout explicit `init`, `init` is
* made internally, actual start of the graph is then not garanteed to be
* synchronous.
*
* @memberof module:core.SourceMixin
* @instance
* @name init
*
* @return Promise
*
* @example
* // safe initialization and start
* source.init().then(() => source.start())
* // safe initialization and start
* source.start();
*/
init() {
this.initPromise = this.initModule().then(() => {
this.initStream(); // this is synchronous
this.initialized = true;
return Promise.resolve(true);
});
return this.initPromise;
}
/**
* Interface method to implement that starts the graph.
*
* The method main purpose is to make sure take verify initialization step and
* set `started` to `true` when done.
* Should behave synchronously when called inside `init().then()` and async
* if called without init step.
*
* @memberof module:core.SourceMixin
* @instance
* @name start
*
* @example
* // basic `start` implementation
* start() {
* if (this.initialized === false) {
* if (this.initPromise === null) // init has not yet been called
* this.initPromise = this.init();
*
* this.initPromise.then(this.start);
* return;
* }
*
* this.started = true;
* }
*/
start() {}
/**
* Interface method to implement that stops the graph.
*
* @memberof module:core.SourceMixin
* @instance
* @name stop
*
* @example
* // basic `stop` implementation
* stop() {
* this.started = false;
* }
*/
stop() {}
/**
* The implementation should never allow incomming frames
* if `this.started` is not `true`.
*
* @memberof module:core.SourceMixin
* @instance
* @name processFrame
*
* @param {Object} frame
*
* @example
* // basic `processFrame` implementation
* processFrame(frame) {
* if (this.started === true) {
* this.prepareFrame();
* this.processFunction(frame);
* this.propagateFrame();
* }
* }
*/
processFrame(frame) {}
}
export default SourceMixin;