mirror of
https://github.com/mpv-player/mpv.git
synced 2024-09-20 12:02:23 +02:00
client API: avoid redundant property change events if possible
This is done simply by comparing the previous and current values. Do this only if the requested format is not MPV_FORMAT_NONE.
This commit is contained in:
parent
d6022f33d6
commit
89d400dc21
@ -250,13 +250,17 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
|||||||
example ``string``, ``fn`` is roughly called as in
|
example ``string``, ``fn`` is roughly called as in
|
||||||
``fn(name, mp.get_property_string(name))``.
|
``fn(name, mp.get_property_string(name))``.
|
||||||
|
|
||||||
Sporadic property change events are possible. This means the change function
|
If possible, change events are coalesced. If a property is changed a bunch
|
||||||
``fn`` can be called even if the property doesn't actually change. Likewise,
|
of times in a row, only the last change triggers the change function. (The
|
||||||
in some cases the function is not called even if the property changes. If
|
|
||||||
possible, change events are coalesced. If a property is changed a bunch of
|
|
||||||
times in a row, only the last change triggers the change function. (The
|
|
||||||
exact behavior depends on timing and other things.)
|
exact behavior depends on timing and other things.)
|
||||||
|
|
||||||
|
In some cases the function is not called even if the property changes.
|
||||||
|
Whether this can happen depends on the property.
|
||||||
|
|
||||||
|
If the ``type`` is ``none`` or ``nil``, sporadic property change events are
|
||||||
|
possible. This means the change function ``fn`` can be called even if the
|
||||||
|
property doesn't actually change.
|
||||||
|
|
||||||
``mp.unobserve_property(fn)``
|
``mp.unobserve_property(fn)``
|
||||||
Undo ``mp.observe_property(..., fn)``. This removes all property handlers
|
Undo ``mp.observe_property(..., fn)``. This removes all property handlers
|
||||||
that are equal to the ``fn`` parameter. This uses normal Lua ``==``
|
that are equal to the ``fn`` parameter. This uses normal Lua ``==``
|
||||||
|
@ -752,6 +752,10 @@ int mpv_get_property_async(mpv_handle *ctx, uint64_t reply_userdata,
|
|||||||
* Observing a property that doesn't exist is allowed, although it may still
|
* Observing a property that doesn't exist is allowed, although it may still
|
||||||
* cause some sporadic change events.
|
* cause some sporadic change events.
|
||||||
*
|
*
|
||||||
|
* If you set the format parameter to a value other than MPV_FORMAT_NONE, the
|
||||||
|
* API will suppress redundant change events by comparing the raw value against
|
||||||
|
* the previous value.
|
||||||
|
*
|
||||||
* @param reply_userdata This will be used for the mpv_event.reply_userdata
|
* @param reply_userdata This will be used for the mpv_event.reply_userdata
|
||||||
* field for the received MPV_EVENT_PROPERTY_CHANGE
|
* field for the received MPV_EVENT_PROPERTY_CHANGE
|
||||||
* events. (Also see section about asynchronous calls,
|
* events. (Also see section about asynchronous calls,
|
||||||
|
@ -562,6 +562,46 @@ static bool conv_node_to_format(void *dst, mpv_format dst_fmt, mpv_node *src)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool compare_value(void *a, void *b, mpv_format format)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
case MPV_FORMAT_NONE:
|
||||||
|
return false;
|
||||||
|
case MPV_FORMAT_STRING:
|
||||||
|
case MPV_FORMAT_OSD_STRING:
|
||||||
|
return strcmp(*(char **)a, *(char **)b) == 0;
|
||||||
|
case MPV_FORMAT_FLAG:
|
||||||
|
return *(int *)a == *(int *)b;
|
||||||
|
case MPV_FORMAT_INT64:
|
||||||
|
return *(int64_t *)a == *(int64_t *)b;
|
||||||
|
case MPV_FORMAT_DOUBLE:
|
||||||
|
return *(double *)a == *(double *)b;
|
||||||
|
case MPV_FORMAT_NODE: {
|
||||||
|
struct mpv_node *a_n = a, *b_n = b;
|
||||||
|
if (a_n->format != b_n->format)
|
||||||
|
return false;
|
||||||
|
return compare_value(&a_n->u, &b_n->u, a_n->format);
|
||||||
|
}
|
||||||
|
case MPV_FORMAT_NODE_ARRAY:
|
||||||
|
case MPV_FORMAT_NODE_MAP:
|
||||||
|
{
|
||||||
|
mpv_node_list *l_a = *(mpv_node_list **)a, *l_b = *(mpv_node_list **)b;
|
||||||
|
if (l_a->num != l_b->num)
|
||||||
|
return false;
|
||||||
|
for (int n = 0; n < l_a->num; n++) {
|
||||||
|
if (!compare_value(&l_a->values[n], &l_b->values[n], MPV_FORMAT_NODE))
|
||||||
|
return false;
|
||||||
|
if (format == MPV_FORMAT_NODE_MAP) {
|
||||||
|
if (strcmp(l_a->keys[n], l_b->keys[n]) != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
void mpv_free_node_contents(mpv_node *node)
|
void mpv_free_node_contents(mpv_node *node)
|
||||||
{
|
{
|
||||||
static const struct m_option type = { .type = CONF_TYPE_NODE };
|
static const struct m_option type = { .type = CONF_TYPE_NODE };
|
||||||
@ -1104,12 +1144,17 @@ static void update_prop(void *p)
|
|||||||
pthread_mutex_lock(&ctx->lock);
|
pthread_mutex_lock(&ctx->lock);
|
||||||
ctx->properties_updating--;
|
ctx->properties_updating--;
|
||||||
prop->updating = false;
|
prop->updating = false;
|
||||||
prop->changed = true;
|
bool new_value_valid = req.status >= 0;
|
||||||
prop->value_valid = req.status >= 0;
|
if (prop->value_valid != new_value_valid) {
|
||||||
if (prop->value_valid) {
|
prop->changed = true;
|
||||||
m_option_free(type, &prop->value);
|
} else if (prop->value_valid && new_value_valid) {
|
||||||
memcpy(&prop->value, &val, type->type->size);
|
if (!compare_value(&prop->value, &val, prop->format))
|
||||||
|
prop->changed = true;
|
||||||
}
|
}
|
||||||
|
m_option_free(type, &prop->value);
|
||||||
|
if (new_value_valid)
|
||||||
|
memcpy(&prop->value, &val, type->type->size);
|
||||||
|
prop->value_valid = new_value_valid;
|
||||||
if (prop->dead)
|
if (prop->dead)
|
||||||
talloc_steal(ctx->cur_event, prop);
|
talloc_steal(ctx->cur_event, prop);
|
||||||
wakeup_client(ctx);
|
wakeup_client(ctx);
|
||||||
|
Loading…
Reference in New Issue
Block a user