summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorAvi Halachmi (:avih) <avihpit@yahoo.com>2017-12-22 13:50:38 +0200
committerKevin Mitchell <kevmitch@gmail.com>2018-04-07 16:02:19 -0700
commit9a47023c444df488ff51c8f86fbd1b1b93e99a9b (patch)
tree1ec4e64361565deb06836f4c76cd72ccc214aa71 /player
parentb04f0cad43eb627fb4e970367062329e3331d9fe (diff)
downloadmpv-9a47023c444df488ff51c8f86fbd1b1b93e99a9b.tar.bz2
mpv-9a47023c444df488ff51c8f86fbd1b1b93e99a9b.tar.xz
js: implement mp.register_idle
Due to earlier misinterpretation of the Lua docs as if mp.register_idle registers a one-shot callback, the JS docs suggested to use setTimeout. But the behavior and Lua docs are such that it's a repeating callback which fires just before the script thread goes to sleep. Implement it for JS too.
Diffstat (limited to 'player')
-rw-r--r--player/javascript/defaults.js39
1 files changed, 37 insertions, 2 deletions
diff --git a/player/javascript/defaults.js b/player/javascript/defaults.js
index c5c1f35161..281008fd07 100644
--- a/player/javascript/defaults.js
+++ b/player/javascript/defaults.js
@@ -17,7 +17,7 @@ function new_cache() {
}
/**********************************************************************
- * event handlers, property observers, client messages, hooks
+ * event handlers, property observers, idle, client messages, hooks
*********************************************************************/
var ehandlers = new_cache() // items of event-name: array of {maybe cb: fn}
@@ -54,6 +54,31 @@ function dispatch_event(e) {
}
}
+// ----- idle observers -----
+var iobservers = [], // array of callbacks
+ ideleted = false;
+
+mp.register_idle = function(fn) {
+ iobservers.push(fn);
+}
+
+mp.unregister_idle = function(fn) {
+ iobservers.forEach(function(f, i) {
+ if (f == fn)
+ delete iobservers[i]; // -> same length but [more] sparse
+ });
+ ideleted = true;
+}
+
+function notify_idle_observers() {
+ // forEach and filter skip deleted items and newly added items
+ iobservers.forEach(function(f) { f() });
+ if (ideleted) {
+ iobservers = iobservers.filter(function() { return true });
+ ideleted = false;
+ }
+}
+
// ----- property observers -----
var next_oid = 1,
observers = new_cache(); // items of id: fn
@@ -254,6 +279,10 @@ function peek_wait(arr) {
return arr.length ? Math.max(0, arr[arr.length - 1].when - now()) : -1;
}
+function peek_timers_wait() {
+ return peek_wait(timers); // must not be called while in process_timers
+}
+
// Callback all due non-canceled timers which were inserted before calling us.
// Returns wait in ms till the next timer (possibly 0), or -1 if nothing pends.
function process_timers() {
@@ -481,6 +510,8 @@ mp.get_time = function() { return mp.get_time_ms() / 1000 };
mp.utils.getcwd = function() { return mp.get_property("working-directory") };
mp.dispatch_event = dispatch_event;
mp.process_timers = process_timers;
+mp.notify_idle_observers = notify_idle_observers;
+mp.peek_timers_wait = peek_timers_wait;
mp.get_opt = function(key, def) {
var v = mp.get_property_native("options/script-opts")[key];
@@ -533,13 +564,17 @@ mp.register_script_message("key-binding", dispatch_key_binding);
g.mp_event_loop = function mp_event_loop() {
var wait = 0; // seconds
- do { // distapch events as long as they arrive, then do the timers
+ do { // distapch events as long as they arrive, then do the timers/idle
var e = mp.wait_event(wait);
if (e.event != "none") {
dispatch_event(e);
wait = 0; // poll the next one
} else {
wait = process_timers() / 1000;
+ if (wait != 0) {
+ notify_idle_observers(); // can add timers -> recalculate wait
+ wait = peek_timers_wait() / 1000;
+ }
}
} while (mp.keep_running);
};