mirror of
https://github.com/mpv-player/mpv
synced 2024-12-23 15:22:09 +00:00
lua: add a timer API
This commit is contained in:
parent
206616b697
commit
92a004bf87
@ -63,6 +63,69 @@ local function script_dispatch(event)
|
||||
end
|
||||
end
|
||||
|
||||
local timers = {}
|
||||
|
||||
-- Install a one-shot timer. Once the given amount of seconds has passed from
|
||||
-- now, the callback will be called as cb(), and the timer is removed.
|
||||
function mp.add_timeout(seconds, cb)
|
||||
local t = mp.add_periodic_timer(seconds, cb)
|
||||
t.oneshot = true
|
||||
return t
|
||||
end
|
||||
|
||||
-- Install a periodic timer. It works like add_timeout(), but after cb() is
|
||||
-- called, the timer is re-added.
|
||||
function mp.add_periodic_timer(seconds, cb)
|
||||
local t = {
|
||||
timeout = seconds,
|
||||
cb = cb,
|
||||
oneshot = false,
|
||||
next_deadline = mp.get_timer() + seconds,
|
||||
}
|
||||
timers[t] = t
|
||||
return t
|
||||
end
|
||||
|
||||
function mp.cancel_timer(t)
|
||||
if t then
|
||||
timers[t] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Return the timer that expires next.
|
||||
local function get_next_timer()
|
||||
local best = nil
|
||||
for t, _ in pairs(timers) do
|
||||
if (best == nil) or (t.next_deadline < best.next_deadline) then
|
||||
best = t
|
||||
end
|
||||
end
|
||||
return best
|
||||
end
|
||||
|
||||
-- Run timers that have met their deadline.
|
||||
-- Return: next absolute time a timer expires as number, or nil if no timers
|
||||
local function process_timers()
|
||||
while true do
|
||||
local timer = get_next_timer()
|
||||
if not timer then
|
||||
return
|
||||
end
|
||||
local wait = timer.next_deadline - mp.get_timer()
|
||||
if wait > 0 then
|
||||
return wait
|
||||
else
|
||||
if timer.oneshot then
|
||||
timers[timer] = nil
|
||||
end
|
||||
timer.cb()
|
||||
if not timer.oneshot then
|
||||
timer.next_deadline = mp.get_timer() + timer.timeout
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- used by default event loop (mp_event_loop()) to decide when to quit
|
||||
mp.keep_running = true
|
||||
|
||||
@ -93,21 +156,27 @@ package.loaded["mp"] = mp
|
||||
package.loaded["mp.msg"] = mp.msg
|
||||
|
||||
_G.mp_event_loop = function()
|
||||
wait = 0
|
||||
local more_events = true
|
||||
mp.suspend()
|
||||
while mp.keep_running do
|
||||
-- Drop all locks - important especially if an error happened while
|
||||
-- locked, and the error was handled, but the lock not dropped.
|
||||
local wait = process_timers()
|
||||
if wait == nil then
|
||||
wait = 1e20 -- infinity for all practical purposes
|
||||
end
|
||||
if more_events then
|
||||
wait = 0
|
||||
end
|
||||
-- Resume playloop - important especially if an error happened while
|
||||
-- suspended, and the error was handled, but no resume was done.
|
||||
if wait > 0 then
|
||||
mp.resume("all")
|
||||
end
|
||||
local e = mp.wait_event(wait)
|
||||
if e.event == "none" then
|
||||
wait = 1e20
|
||||
else
|
||||
-- Empty the event queue while suspended; otherwise, each
|
||||
-- event will keep us waiting until the core suspends again.
|
||||
mp.suspend()
|
||||
wait = 0
|
||||
-- Empty the event queue while suspended; otherwise, each
|
||||
-- event will keep us waiting until the core suspends again.
|
||||
mp.suspend()
|
||||
more_events = (e.event ~= "none")
|
||||
if more_events then
|
||||
local handler = event_handlers[e.event]
|
||||
if handler then
|
||||
handler(e)
|
||||
|
Loading…
Reference in New Issue
Block a user