lua: make hook processing more flexible

This can now opt to not continue a hook after the hook callback returns.
This makes it easier for scripts, and may make it unnecessary to run
reentrant event loops etc. for scripts that want to wait before
continuing while still running the event loop.
This commit is contained in:
wm4 2020-08-05 22:58:19 +02:00
parent 13d354e46d
commit d0ab562b1f
2 changed files with 41 additions and 4 deletions

View File

@ -889,8 +889,22 @@ guarantee a stable interface.
their result (normally, the Lua scripting interface is asynchronous from their result (normally, the Lua scripting interface is asynchronous from
the point of view of the player core). ``priority`` is an arbitrary integer the point of view of the player core). ``priority`` is an arbitrary integer
that allows ordering among hooks of the same kind. Using the value 50 is that allows ordering among hooks of the same kind. Using the value 50 is
recommended as neutral default value. ``fn`` is the function that will be recommended as neutral default value.
called during execution of the hook.
``fn(hook)`` is the function that will be called during execution of the
hook. The parameter passed to it (``hook``) is a Lua object that can control
further aspects about the currently invoked hook. It provides the following
methods:
``defer()``
Returning from the hook function should not automatically continue
the hook. Instead, the API user wants to call ``hook:cont()`` on its
own at a later point in time (before or after the function has
returned).
``cont()``
Continue the hook. Doesn't need to be called unless ``defer()`` was
called.
See `Hooks`_ for currently existing hooks and what they do - only the hook See `Hooks`_ for currently existing hooks and what they do - only the hook
list is interesting; handling hook execution is done by the Lua script list is interesting; handling hook execution is done by the Lua script

View File

@ -547,12 +547,35 @@ end
local hook_table = {} local hook_table = {}
local hook_mt = {}
hook_mt.__index = hook_mt
function hook_mt.cont(t)
if t._id == nil then
mp.msg.error("hook already continued")
else
mp.raw_hook_continue(t._id)
t._id = nil
end
end
function hook_mt.defer(t)
t._defer = true
end
mp.register_event("hook", function(ev) mp.register_event("hook", function(ev)
local fn = hook_table[tonumber(ev.id)] local fn = hook_table[tonumber(ev.id)]
local hookobj = {
_id = ev.hook_id,
_defer = false,
}
setmetatable(hookobj, hook_mt)
if fn then if fn then
fn() fn(hookobj)
end
if (not hookobj._defer) and hookobj._id ~= nil then
hookobj:cont()
end end
mp.raw_hook_continue(ev.hook_id)
end) end)
function mp.add_hook(name, pri, cb) function mp.add_hook(name, pri, cb)