summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-12-18 08:58:49 +0100
committerwm4 <wm4@nowhere>2019-12-18 08:58:49 +0100
commit7e4819e705d2f046de06fcff53ce151d835bbdad (patch)
treec775dc2f1517c05bfa2931c10ca8999b5cd7e63a
parent6ab013cbdd9d627f7cdd5eb1eca8df0da112b929 (diff)
downloadmpv-7e4819e705d2f046de06fcff53ce151d835bbdad.tar.bz2
mpv-7e4819e705d2f046de06fcff53ce151d835bbdad.tar.xz
command, lua: add a way to share data between scripts
Very primitive and dumb, but fulfils its purpose for the next commits. I chose this specific implementation because it has the lowest footprint in command.c, without resorting to crazy hacks such as sending messages between scripts (which would be hard to coordinate especially on startup).
-rw-r--r--DOCS/man/input.rst22
-rw-r--r--player/command.c31
-rw-r--r--player/lua/defaults.lua24
3 files changed, 77 insertions, 0 deletions
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index 0f6ec9430e..94e1f2fd27 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -2533,6 +2533,28 @@ Property list
``current-ao``
Current audio output driver (name as used with ``--ao``).
+``shared-script-properties`` (RW)
+ This is a key/value map of arbitrary strings shared between scripts for
+ general use. The player itself does not use any data in it (although some
+ builtin scripts may). The property is not preserved across player restarts.
+
+ This is very primitive, inefficient, and annoying to use. It's a makeshift
+ solution which could go away any time (for example, when a better solution
+ becomes available). This is also why this property has an annoying name. You
+ should avoid using it, unless you absolutely have to.
+
+ Lua scripting has helpers starting with ``utils.shared_script_property_``.
+ They are undocumented because you should not use this property. If you still
+ think you must, you should use the helpers instead of the property directly.
+
+ You are supposed to use the ``change-list`` command to modify the contents.
+ Reading, modifying, and writing the property manually could data loss if two
+ scripts update different keys at the same time due to lack of
+ synchronization. The Lua helpers take care of this.
+
+ (There is no way to ensure synchronization if two scripts try to update the
+ same key at the same time.)
+
``working-directory``
Return the working directory of the mpv process. Can be useful for JSON IPC
users, because the command line player usually works with relative paths.
diff --git a/player/command.c b/player/command.c
index 8576e36da7..32e4e3dfea 100644
--- a/player/command.c
+++ b/player/command.c
@@ -102,6 +102,12 @@ struct command_ctx {
struct ao_hotplug *hotplug;
struct mp_cmd_ctx *cache_dump_cmd; // in progress cache dumping
+
+ char **script_props;
+};
+
+static const struct m_option script_props_type = {
+ .type = &m_option_type_keyvalue_list
};
struct overlay {
@@ -3217,6 +3223,27 @@ static int mp_property_bindings(void *ctx, struct m_property *prop,
return M_PROPERTY_NOT_IMPLEMENTED;
}
+
+static int mp_property_script_props(void *ctx, struct m_property *prop,
+ int action, void *arg)
+{
+ MPContext *mpctx = ctx;
+ struct command_ctx *cmd = mpctx->command_ctx;
+ switch (action) {
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)arg = script_props_type;
+ return M_PROPERTY_OK;
+ case M_PROPERTY_GET:
+ m_option_copy(&script_props_type, arg, &cmd->script_props);
+ return M_PROPERTY_OK;
+ case M_PROPERTY_SET:
+ m_option_copy(&script_props_type, &cmd->script_props, arg);
+ mp_notify_property(mpctx, prop->name);
+ return M_PROPERTY_OK;
+ }
+ return M_PROPERTY_NOT_IMPLEMENTED;
+}
+
// Redirect a property name to another
#define M_PROPERTY_ALIAS(name, real_property) \
{(name), mp_property_alias, .priv = (real_property)}
@@ -3391,6 +3418,8 @@ static const struct m_property mp_properties_base[] = {
{"command-list", mp_property_commands},
{"input-bindings", mp_property_bindings},
+ {"shared-script-properties", mp_property_script_props},
+
M_PROPERTY_ALIAS("video", "vid"),
M_PROPERTY_ALIAS("audio", "aid"),
M_PROPERTY_ALIAS("sub", "sid"),
@@ -5856,6 +5885,8 @@ void command_uninit(struct MPContext *mpctx)
overlay_uninit(mpctx);
ao_hotplug_destroy(ctx->hotplug);
+ m_option_free(&script_props_type, &ctx->script_props);
+
talloc_free(mpctx->command_ctx);
mpctx->command_ctx = NULL;
}
diff --git a/player/lua/defaults.lua b/player/lua/defaults.lua
index f2983e8dc3..29e513f4ea 100644
--- a/player/lua/defaults.lua
+++ b/player/lua/defaults.lua
@@ -676,4 +676,28 @@ function mp_utils.subprocess_detached(t)
mp.commandv("run", unpack(t.args))
end
+function mp_utils.shared_script_property_set(name, value)
+ if value ~= nil then
+ -- no such thing as change-list with mpv_node, so build a string value
+ mp.commandv("change-list", "shared-script-properties", "append",
+ name .. "=" .. value)
+ else
+ mp.commandv("change-list", "shared-script-properties", "remove", name)
+ end
+end
+
+function mp_utils.shared_script_property_get(name)
+ local map = mp.get_property_native("shared-script-properties")
+ return map and map[name]
+end
+
+-- cb(name, value) on change and on init
+function mp_utils.shared_script_property_observe(name, cb)
+ -- it's _very_ wasteful to observe the mpv core "super" property for every
+ -- shared sub-property, but then again you shouldn't use this
+ mp.observe_property("shared-script-properties", "native", function(_, val)
+ cb(name, val and val[name])
+ end)
+end
+
return {}