Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions res/controllers/common-controller-scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,77 @@ var colorCodeToObject = function(colorCode) {
var script = function() {
};

/**
* Wraps the engine timer API in JS promises
*
* Use `new TimerPromise()` to call `engine.beginTimer`, use {@link TimerPromise#cancel} to call `engine.stopTimer()`.
* The Promise resolves the first time the timer completes and rejects when canceled.
*/
class TimerPromise extends Promise {
Comment on lines +143 to +149
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain a little more on why you think the promise model is suited well for timers here? From what I can tell, they would only work for one-shot timers. I know engine.beginTimer is clunky to use, but so is its direct foundation (window.setTimeout/window.setInterval) and I don't think JS overs anything better. Do you have a better idea of what constitutes a good timer API? I'm also not sure, but wasn't there a previous discussion on this already?

Copy link
Copy Markdown
Contributor Author

@christophehenry christophehenry Jul 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not aware of a previous discussion on this matter.

So the idea here is to offer a more modern and ES6+ way of using timers. Promises a particularly suited for this kind of task.

Of course, since Promises only resolve once, it makes more sense for one-shot timers. But the cancel() method I added also handle the case where the timer was already cancelled which has the advantage of avoiding the warning when trying to engine.stopTimer() a one-shot that was already executed. This warning message really bothers me.

Of course, if this is too controversial, I'll remove this. But I still think it's a nice addition.

/**
* @param {number} interval Time in milliseconds until the function is executed. Intervals below 20ms are ignored
* @param {boolean} oneShot If true the function is only once, if false the function is executed repeatedly and the
* promise resolves the first time the timer completes. [default = false]
*/
constructor(interval, oneShot = false) {
let resolve = undefined;
let reject = undefined;
super((res, rej) => {
resolve = res;
reject = rej;
});

this._resolve = resolve;
this._reject = reject;

this.__timer = 0;
if (Number.isInteger(interval) && interval >= 20) {
this.__timer = engine.beginTimer(interval, () => {
this.__done = true;
this.__canceled = false;
this._resolve();
}, oneShot);
}

}

get settled() {
return this.__done || this.__canceled;
}

get done() {
return this.__done;
}

get canceled() {
return this.__canceled;
}

cancel() {
if (this.__done || this.__canceled) { return; }
this.__done = false;
this.__canceled = true;
if (this.__timer !== 0) {
engine.stopTimer(this.__timer);
}
this._reject();
}
}

TimerPromise.resolve = function resolve(value) {
const promise = new TimerPromise(0);
promise._resolve(value);
return promise;
};

TimerPromise.cancelled = function cancelled() {
const promise = new TimerPromise(0);
promise.cancel();
return promise;
};

script.TimerPromise = TimerPromise;

/**
* Discriminates whether an object was created using the `{}` synthax.
*
Expand Down
2 changes: 0 additions & 2 deletions res/controllers/engine-api.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@

/** ScriptConnectionJSProxy */

declare interface ScriptConnection {
/**
* Disconnect the script connection,
Expand Down
8 changes: 1 addition & 7 deletions res/controllers/midi-components-0.0.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Components JS library for Mixxx
* Documentation is on the Mixxx wiki at
* http://mixxx.org/wiki/doku.php/components_js
* https://github.com/mixxxdj/mixxx/wiki/Components-JS
*
* Copyright (C) 2017 Be <be.0@gmx.com>
*
Expand All @@ -18,12 +18,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*
* This library depends on Lodash, which is copyright JS Foundation
* and other contributors and licensed under the MIT license. Refer to
* the lodash.mixxx.js file in this directory for details.
*/

(function(global) {
Expand Down
Loading