mirror of
https://github.com/mpv-player/mpv
synced 2025-02-26 18:32:08 +00: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
|
||||
``fn(name, mp.get_property_string(name))``.
|
||||
|
||||
Sporadic property change events are possible. This means the change function
|
||||
``fn`` can be called even if the property doesn't actually change. Likewise,
|
||||
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
|
||||
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.)
|
||||
|
||||
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)``
|
||||
Undo ``mp.observe_property(..., fn)``. This removes all property handlers
|
||||
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
|
||||
* 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
|
||||
* field for the received MPV_EVENT_PROPERTY_CHANGE
|
||||
* 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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
ctx->properties_updating--;
|
||||
prop->updating = false;
|
||||
prop->changed = true;
|
||||
prop->value_valid = req.status >= 0;
|
||||
if (prop->value_valid) {
|
||||
m_option_free(type, &prop->value);
|
||||
memcpy(&prop->value, &val, type->type->size);
|
||||
bool new_value_valid = req.status >= 0;
|
||||
if (prop->value_valid != new_value_valid) {
|
||||
prop->changed = true;
|
||||
} else if (prop->value_valid && new_value_valid) {
|
||||
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)
|
||||
talloc_steal(ctx->cur_event, prop);
|
||||
wakeup_client(ctx);
|
||||
|
Loading…
Reference in New Issue
Block a user