diff options
author | Avi Halachmi (:avih) <avihpit@yahoo.com> | 2017-12-22 13:50:38 +0200 |
---|---|---|
committer | Kevin Mitchell <kevmitch@gmail.com> | 2018-04-07 16:02:19 -0700 |
commit | 9a47023c444df488ff51c8f86fbd1b1b93e99a9b (patch) | |
tree | 1ec4e64361565deb06836f4c76cd72ccc214aa71 /player/javascript/defaults.js | |
parent | b04f0cad43eb627fb4e970367062329e3331d9fe (diff) | |
download | mpv-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/javascript/defaults.js')
-rw-r--r-- | player/javascript/defaults.js | 39 |
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); }; |