diff options
author | wm4 <wm4@nowhere> | 2018-03-23 16:24:49 +0100 |
---|---|---|
committer | Kevin Mitchell <kevmitch@gmail.com> | 2018-03-26 23:02:23 -0700 |
commit | f60826c3a14ba3b49077f17e5364b7347f9b468a (patch) | |
tree | 285f39963a9f978939743b12527539e1ec8a3f54 /libmpv | |
parent | 6d7cfdfae582353e1f10797bb2c587e6ada0aed7 (diff) | |
download | mpv-f60826c3a14ba3b49077f17e5364b7347f9b468a.tar.bz2 mpv-f60826c3a14ba3b49077f17e5364b7347f9b468a.tar.xz |
client API: add a first class hook API, and deprecate old API
As it turns out, there are multiple libmpv users who saw a need to
use the hook API. The API is kind of shitty and was never meant to be
actually public (it was mostly a hack for the ytdl script).
Introduce a proper API and deprecate the old one. The old one will
probably continue to work for a few releases, but will be removed
eventually.
There are some slight changes to the old API, but if a user followed
the manual properly, it won't break.
Mostly untested. Appears to work with ytdl_hook.
Diffstat (limited to 'libmpv')
-rw-r--r-- | libmpv/client.h | 79 | ||||
-rw-r--r-- | libmpv/mpv.def | 2 |
2 files changed, 80 insertions, 1 deletions
diff --git a/libmpv/client.h b/libmpv/client.h index cd646eb218..77c149e405 100644 --- a/libmpv/client.h +++ b/libmpv/client.h @@ -1133,6 +1133,9 @@ int mpv_get_property_async(mpv_handle *ctx, uint64_t reply_userdata, * property yourself. Try to avoid endless feedback loops, which could happen * if you react to the change notifications triggered by your own change. * + * Only the mpv_handle on which this was called will receive the property + * change events, or can unobserve them. + * * @param reply_userdata This will be used for the mpv_event.reply_userdata * field for the received MPV_EVENT_PROPERTY_CHANGE * events. (Also see section about asynchronous calls, @@ -1350,7 +1353,14 @@ typedef enum mpv_event_id { * Event delivery will continue normally once this event was returned * (this forces the client to empty the queue completely). */ - MPV_EVENT_QUEUE_OVERFLOW = 24 + MPV_EVENT_QUEUE_OVERFLOW = 24, + /** + * Triggered if a hook handler was registered with mpv_hook_add(), and the + * hook is invoked. If you receive this, you must handle it, and continue + * the hook with mpv_hook_continue(). + * See also mpv_event and mpv_event_hook. + */ + MPV_EVENT_HOOK = 25, // Internal note: adjust INTERNAL_EVENT_BASE when adding new events. } mpv_event_id; @@ -1514,6 +1524,17 @@ typedef struct mpv_event_client_message { const char **args; } mpv_event_client_message; +typedef struct mpv_event_hook { + /** + * The hook name as passed to mpv_hook_add(). + */ + const char *name; + /** + * Internal ID that must be passed to mpv_hook_continue(). + */ + uint64_t id; +} mpv_event_hook; + typedef struct mpv_event { /** * One of mpv_event. Keep in mind that later ABI compatible releases might @@ -1682,6 +1703,62 @@ void mpv_set_wakeup_callback(mpv_handle *ctx, void (*cb)(void *d), void *d); */ void mpv_wait_async_requests(mpv_handle *ctx); +/** + * A hook is like a synchronous event that blocks the player. You register + * a hook handler with this function. You will get an event, which you need + * to handle, and once things are ready, you can let the player continue with + * mpv_hook_continue(). + * + * Currently, hooks can't be removed explicitly. But they will be implicitly + * removed if the mpv_handle it was registered with is destroyed. This also + * continues the hook if it was being handled by the destroyed mpv_handle (but + * this should be avoided, as it might mess up order of hook execution). + * + * Hook handlers are ordered globally by priority and order of registration. + * Handlers for the same hook with same priority are invoked in order of + * registration (the handler registered first is run first). Handlers with + * lower priority are run first (which seems backward). + * + * See the "Hooks" section in the manpage to see which hooks are currently + * defined. + * + * Some hooks might be reentrant (so you get multiple MPV_EVENT_HOOK for the + * same hook). If this can happen for a specific hook type, it will be + * explicitly documented in the manpage. + * + * Only the mpv_handle on which this was called will receive the hook events, + * or can "continue" them. + * + * @param reply_userdata This will be used for the mpv_event.reply_userdata + * field for the received MPV_EVENT_HOOK events. + * If you have no use for this, pass 0. + * @param name The hook name. This should be one of the documented names. But + * if the name is unknown, the hook event will simply be never + * raised. + * @param priority See remarks above. Use 0 as a neutral default. + * @return error code (usually fails only on OOM) + */ +int mpv_hook_add(mpv_handle *ctx, uint64_t reply_userdata, + const char *name, int priority); + +/** + * Respond to a MPV_EVENT_HOOK event. You must call this after you have handled + * the event. There is no way to "cancel" or "stop" the hook. + * + * Calling this will will typically unblock the player for whatever the hook + * is responsible for (e.g. for the "on_load" hook it lets it continue + * playback). + * + * It is explicitly undefined behavior to call this more than once for each + * MPV_EVENT_HOOK, to pass an incorrect ID, or to call this on a mpv_handle + * different from the one that registered the handler and received the event. + * + * @param id This must be the value of the mpv_event_hook.id field for the + * corresponding MPV_EVENT_HOOK. + * @return error code + */ +int mpv_hook_continue(mpv_handle *ctx, uint64_t id); + #if MPV_ENABLE_DEPRECATED /** diff --git a/libmpv/mpv.def b/libmpv/mpv.def index ccd98422a7..1d828f4b2b 100644 --- a/libmpv/mpv.def +++ b/libmpv/mpv.def @@ -21,6 +21,8 @@ mpv_get_property_string mpv_get_sub_api mpv_get_time_us mpv_get_wakeup_pipe +mpv_hook_add +mpv_hook_continue mpv_initialize mpv_load_config_file mpv_observe_property |