From 309ae76e0b159d4000e24f04aabef8e29f41e86a Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 15 Feb 2014 16:41:48 +0100 Subject: m_property: add a sub-property mechanism This adds a mechanism for easier export of sub-properties. The following commits will make use of it to export fine grained information about certain things. The sub-property mechanism reduces the amount of code needed to export a data value to 1 line. --- options/m_property.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ options/m_property.h | 28 +++++++++++++++++++++++- 2 files changed, 88 insertions(+), 1 deletion(-) (limited to 'options') diff --git a/options/m_property.c b/options/m_property.c index 9c8649c5ab..d863a06ab3 100644 --- a/options/m_property.c +++ b/options/m_property.c @@ -386,3 +386,64 @@ int m_property_strdup_ro(const struct m_option* prop, int action, void* arg, } return M_PROPERTY_NOT_IMPLEMENTED; } + +// This allows you to make a list of values (like from a struct) available +// as a number of sub-properties. The property list is set up with the current +// property values on the stack before calling this function. +// This does not support write access. +int m_property_read_sub(const struct m_sub_property *props, int action, void *arg) +{ + switch (action) { + case M_PROPERTY_GET_TYPE: + *(struct m_option *)arg = (struct m_option){ + .name = "", + .type = CONF_TYPE_STRING, + }; + return M_PROPERTY_OK; + case M_PROPERTY_GET: + case M_PROPERTY_PRINT: { + // Output "something" - what it really should return is not yet decided. + // It should probably be something that is easy to consume by slave + // mode clients. (M_PROPERTY_PRINT on the other hand can return this + // as human readable version just fine). + char *res = NULL; + for (int n = 0; props && props[n].name; n++) { + const struct m_sub_property *prop = &props[n]; + if (prop->unavailable) + continue; + struct m_option type = { .name = "", .type = prop->type, }; + char *s = m_option_print(&type, &prop->value); + ta_xasprintf_append(&res, "%s=%s\n", prop->name, s); + talloc_free(s); + } + *(char **)arg = res; + return M_PROPERTY_OK; + } + case M_PROPERTY_KEY_ACTION: { + struct m_property_action_arg *ka = arg; + const struct m_sub_property *prop = NULL; + for (int n = 0; props && props[n].name; n++) { + if (strcmp(props[n].name, ka->key) == 0) { + prop = &props[n]; + break; + } + } + if (!prop) + return M_PROPERTY_UNKNOWN; + if (prop->unavailable) + return M_PROPERTY_UNAVAILABLE; + struct m_option type = { .name = "", .type = prop->type, }; + switch (ka->action) { + case M_PROPERTY_GET: { + memset(ka->arg, 0, type.type->size); + m_option_copy(&type, ka->arg, &prop->value); + return M_PROPERTY_OK; + } + case M_PROPERTY_GET_TYPE: + *(struct m_option *)ka->arg = type; + return M_PROPERTY_OK; + } + } + } + return M_PROPERTY_NOT_IMPLEMENTED; +} diff --git a/options/m_property.h b/options/m_property.h index ae4b7716b6..cb9f8b5a25 100644 --- a/options/m_property.h +++ b/options/m_property.h @@ -22,7 +22,8 @@ #include #include -struct m_option; +#include "m_option.h" + struct mp_log; extern const struct m_option_type m_option_type_dummy; @@ -141,4 +142,29 @@ int m_property_double_ro(const struct m_option* prop, int action, void* arg, int m_property_strdup_ro(const struct m_option* prop, int action, void* arg, const char *var); +struct m_sub_property { + // Name of the sub-property - this will be prefixed with the parent + // property's name. + const char *name; + // Type of the data stored in the value member. See m_option. + const struct m_option_type *type; + // Data returned by the sub-property. m_property_read_sub() will make a + // copy of this if needed. It will never write or free the data. + union m_option_value value; + // This can be set to true if the property should be hidden. + bool unavailable; +}; + +// Convenience macros which can be used as part of a sub_property entry. +#define SUB_PROP_INT(i) \ + .type = CONF_TYPE_INT, .value = {.int_ = (i)} +#define SUB_PROP_STR(s) \ + .type = CONF_TYPE_STRING, .value = {.string = (char *)(s)} +#define SUB_PROP_FLOAT(f) \ + .type = CONF_TYPE_FLOAT, .value = {.float_ = (f)} +#define SUB_PROP_FLAG(f) \ + .type = CONF_TYPE_FLAG, .value = {.flag = (f)} + +int m_property_read_sub(const struct m_sub_property *props, int action, void *arg); + #endif /* MPLAYER_M_PROPERTY_H */ -- cgit v1.2.3