diff --git a/legacy/edbus/src/examples/complex_types_client_eina_value.c b/legacy/edbus/src/examples/complex_types_client_eina_value.c index 2e9455f4ef..10e8f72663 100644 --- a/legacy/edbus/src/examples/complex_types_client_eina_value.c +++ b/legacy/edbus/src/examples/complex_types_client_eina_value.c @@ -147,6 +147,14 @@ on_plus_one(void *data, const EDBus_Message *msg, EDBus_Pending *pending) eina_value_free(v); } +static void +_property_removed(void *data, EDBus_Proxy *proxy, void *event_info) +{ + EDBus_Proxy_Event_Property_Removed *event = event_info; + + printf("\nproperty removed: %s", event->name); +} + static void _property_changed(void *data, EDBus_Proxy *proxy, void *event_info) { @@ -266,6 +274,8 @@ main(void) edbus_proxy_event_callback_add(proxy, EDBUS_PROXY_EVENT_PROPERTY_CHANGED, _property_changed, NULL); + edbus_proxy_event_callback_add(proxy, EDBUS_PROXY_EVENT_PROPERTY_REMOVED, + _property_removed, NULL); edbus_proxy_properties_monitor(proxy, EINA_TRUE); ecore_timer_add(10, _read_cache, proxy); diff --git a/legacy/edbus/src/examples/complex_types_server.c b/legacy/edbus/src/examples/complex_types_server.c index 05443a848e..cce42c8804 100644 --- a/legacy/edbus/src/examples/complex_types_server.c +++ b/legacy/edbus/src/examples/complex_types_server.c @@ -306,6 +306,7 @@ static Eina_Bool _emit_changed(void *data) { EDBus_Service_Interface *iface = data; edbus_service_property_changed(iface, "int32"); + edbus_service_property_invalidate_set(iface, "Resp2", EINA_TRUE); return EINA_TRUE; } diff --git a/legacy/edbus/src/lib/edbus_private_types.h b/legacy/edbus/src/lib/edbus_private_types.h index 3e47f64f47..b1a116aea1 100644 --- a/legacy/edbus/src/lib/edbus_private_types.h +++ b/legacy/edbus/src/lib/edbus_private_types.h @@ -155,6 +155,7 @@ struct _EDBus_Service_Interface EDBus_Property_Get_Cb get_func; Ecore_Idler *idler_propschanged; Eina_Array *props_changed; + Eina_Array *prop_invalidated; }; typedef struct _Signal_Argument diff --git a/legacy/edbus/src/lib/edbus_service.c b/legacy/edbus/src/lib/edbus_service.c index ea41f8c493..4aaf7e9a15 100644 --- a/legacy/edbus/src/lib/edbus_service.c +++ b/legacy/edbus/src/lib/edbus_service.c @@ -136,11 +136,17 @@ _introspect_append_method(Eina_Strbuf *buf, const EDBus_Method *method) eina_strbuf_append(buf, ""); } +typedef struct _Property +{ + EDBus_Property *property; + Eina_Bool is_invalidate:1; +} Property; + static void _introspect_append_interface(Eina_Strbuf *buf, EDBus_Service_Interface *iface) { EDBus_Method *method; - EDBus_Property *prop; + Property *prop; Eina_Iterator *iterator; unsigned short i; unsigned int size; @@ -157,7 +163,7 @@ _introspect_append_interface(Eina_Strbuf *buf, EDBus_Service_Interface *iface) iterator = eina_hash_iterator_data_new(iface->properties); EINA_ITERATOR_FOREACH(iterator, prop) - _instrospect_append_property(buf, prop, iface); + _instrospect_append_property(buf, prop->property, iface); eina_iterator_free(iterator); eina_strbuf_append(buf, ""); @@ -169,7 +175,7 @@ _cb_property_get(const EDBus_Service_Interface *piface, const EDBus_Message *msg const char *propname, *iface_name; EDBus_Service_Object *obj = piface->obj; EDBus_Service_Interface *iface; - EDBus_Property *prop; + Property *prop; EDBus_Message *reply, *error_reply = NULL; EDBus_Message_Iter *main_iter, *variant; Eina_Bool ret; @@ -184,10 +190,10 @@ _cb_property_get(const EDBus_Service_Interface *piface, const EDBus_Message *msg "Interface not found."); prop = eina_hash_find(iface->properties, propname); - if (!prop) goto not_found; + if (!prop || prop->is_invalidate) goto not_found; - if (prop->get_func) - getter = prop->get_func; + if (prop->property->get_func) + getter = prop->property->get_func; else if (iface->get_func) getter = iface->get_func; @@ -197,7 +203,8 @@ _cb_property_get(const EDBus_Service_Interface *piface, const EDBus_Message *msg EINA_SAFETY_ON_NULL_RETURN_VAL(reply, NULL); main_iter = edbus_message_iter_get(reply); - variant = edbus_message_iter_container_new(main_iter, 'v', prop->type); + variant = edbus_message_iter_container_new(main_iter, 'v', + prop->property->type); ret = getter(iface, propname, variant, &error_reply); @@ -222,7 +229,7 @@ _cb_property_getall(const EDBus_Service_Interface *piface, const EDBus_Message * EDBus_Service_Object *obj = piface->obj; EDBus_Service_Interface *iface; Eina_Iterator *iterator; - EDBus_Property *prop; + Property *prop; EDBus_Message *reply, *error_reply; EDBus_Message_Iter *main_iter, *dict; @@ -250,21 +257,22 @@ _cb_property_getall(const EDBus_Service_Interface *piface, const EDBus_Message * Eina_Bool ret; EDBus_Property_Get_Cb getter = NULL; - if (prop->get_func) - getter = prop->get_func; + if (prop->property->get_func) + getter = prop->property->get_func; else if (iface->get_func) getter = iface->get_func; - if (!getter) + if (!getter || prop->is_invalidate) continue; if (!edbus_message_iter_arguments_set(dict, "{sv}", &entry)) continue; - edbus_message_iter_basic_append(entry, 's', prop->name); - var = edbus_message_iter_container_new(entry, 'v', prop->type); + edbus_message_iter_basic_append(entry, 's', prop->property->name); + var = edbus_message_iter_container_new(entry, 'v', + prop->property->type); - ret = getter(iface, prop->name, var, &error_reply); + ret = getter(iface, prop->property->name, var, &error_reply); if (!ret) { @@ -289,7 +297,7 @@ _cb_property_set(const EDBus_Service_Interface *piface, const EDBus_Message *msg const char *propname, *iface_name; EDBus_Service_Object *obj = piface->obj; EDBus_Service_Interface *iface; - EDBus_Property *prop; + Property *prop; EDBus_Message *reply; EDBus_Message_Iter *main_iter; EDBus_Property_Set_Cb setter = NULL; @@ -308,18 +316,19 @@ _cb_property_set(const EDBus_Service_Interface *piface, const EDBus_Message *msg "Interface not found."); prop = eina_hash_find(iface->properties, propname); - if (!prop) + if (!prop || prop->is_invalidate) return edbus_message_error_new(msg, DBUS_ERROR_UNKNOWN_PROPERTY, "Property not found."); - if (prop->set_func) - setter = prop->set_func; + if (prop->property->set_func) + setter = prop->property->set_func; else if (iface->set_func) setter = iface->set_func; if (!setter) return edbus_message_error_new(msg, DBUS_ERROR_PROPERTY_READ_ONLY, "This property is read only"); + reply = setter(iface, propname, msg); return reply; } @@ -479,6 +488,13 @@ _edbus_service_object_add(EDBus_Connection *conn, const char *path) return obj; } +static void +_props_free(void *data) +{ + Property *p = data; + free(p); +} + static EDBus_Service_Interface * _edbus_service_interface_add(EDBus_Service_Object *obj, const char *interface) { @@ -493,7 +509,7 @@ _edbus_service_interface_add(EDBus_Service_Object *obj, const char *interface) EINA_MAGIC_SET(iface, EDBUS_SERVICE_INTERFACE_MAGIC); iface->name = eina_stringshare_add(interface); iface->methods = eina_hash_string_superfast_new(NULL); - iface->properties = eina_hash_string_superfast_new(NULL); + iface->properties = eina_hash_string_superfast_new(_props_free); iface->obj = obj; eina_hash_add(obj->interfaces, iface->name, iface); return iface; @@ -536,13 +552,18 @@ _edbus_service_method_add(EDBus_Service_Interface *interface, EDBus_Method *meth static Eina_Bool _edbus_service_property_add(EDBus_Service_Interface *interface, EDBus_Property *property) { + Property *p; EINA_SAFETY_ON_TRUE_RETURN_VAL(!!eina_hash_find(interface->properties, property->name), EINA_FALSE); EINA_SAFETY_ON_NULL_RETURN_VAL(property->type, EINA_FALSE); EINA_SAFETY_ON_FALSE_RETURN_VAL( dbus_signature_validate_single(property->type, NULL), EINA_FALSE); - return eina_hash_add(interface->properties, property->name, property); + p = calloc(1, sizeof(Property)); + EINA_SAFETY_ON_NULL_RETURN_VAL(p, EINA_FALSE); + p->property = property; + + return eina_hash_add(interface->properties, property->name, p); } EAPI EDBus_Service_Interface * @@ -633,6 +654,8 @@ _interface_free(EDBus_Service_Interface *interface) eina_array_free(interface->props_changed); if (interface->idler_propschanged) ecore_idler_del(interface->idler_propschanged); + if (interface->prop_invalidated) + eina_array_free(interface->prop_invalidated); free(interface); } @@ -859,7 +882,7 @@ _idler_propschanged(void *data) EDBus_Message *msg; EDBus_Message_Iter *main_iter, *dict, *array_invalidate; Eina_Hash *added = NULL; - EDBus_Property *prop; + Property *prop; iface->idler_propschanged = NULL; @@ -884,25 +907,26 @@ _idler_propschanged(void *data) Eina_Bool ret; EDBus_Property_Get_Cb getter = NULL; - if (eina_hash_find(added, prop->name)) + if (eina_hash_find(added, prop->property->name)) continue; - eina_hash_add(added, prop->name, prop); + eina_hash_add(added, prop->property->name, prop); - if (prop->get_func) - getter = prop->get_func; + if (prop->property->get_func) + getter = prop->property->get_func; else if (iface->get_func) getter = iface->get_func; - if (!getter) + if (!getter || prop->is_invalidate) continue; EINA_SAFETY_ON_FALSE_GOTO( edbus_message_iter_arguments_set(dict, "{sv}", &entry), error); - edbus_message_iter_basic_append(entry, 's', prop->name); - var = edbus_message_iter_container_new(entry, 'v', prop->type); + edbus_message_iter_basic_append(entry, 's', prop->property->name); + var = edbus_message_iter_container_new(entry, 'v', + prop->property->type); - ret = getter(iface, prop->name, var, &error_reply); + ret = getter(iface, prop->property->name, var, &error_reply); if (!ret) { @@ -923,6 +947,17 @@ invalidate: edbus_message_iter_container_close(main_iter, dict); edbus_message_iter_arguments_set(main_iter, "as", &array_invalidate); + + if (!iface->prop_invalidated) + goto end; + while ((prop = eina_array_pop(iface->prop_invalidated))) + { + if (!prop->is_invalidate) + continue; + edbus_message_iter_basic_append(array_invalidate, 's', + prop->property->name); + } +end: edbus_message_iter_container_close(main_iter, array_invalidate); edbus_service_signal_send(iface, msg); @@ -932,13 +967,15 @@ error: eina_hash_free(added); if (iface->props_changed) eina_array_flush(iface->props_changed); + if (iface->prop_invalidated) + eina_array_flush(iface->prop_invalidated); return ECORE_CALLBACK_CANCEL; } EAPI Eina_Bool edbus_service_property_changed(EDBus_Service_Interface *iface, const char *name) { - EDBus_Property *prop; + Property *prop; EDBUS_SERVICE_INTERFACE_CHECK_RETVAL(iface, EINA_FALSE); EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); @@ -946,11 +983,40 @@ edbus_service_property_changed(EDBus_Service_Interface *iface, const char *name) EINA_SAFETY_ON_NULL_RETURN_VAL(prop, EINA_FALSE); if (!iface->idler_propschanged) - { - iface->idler_propschanged = ecore_idler_add(_idler_propschanged, iface); - if (!iface->props_changed) - iface->props_changed = eina_array_new(1); - } + iface->idler_propschanged = ecore_idler_add(_idler_propschanged, iface); + if (!iface->props_changed) + iface->props_changed = eina_array_new(1); return eina_array_push(iface->props_changed, prop); } + +EAPI Eina_Bool +edbus_service_property_invalidate_set(EDBus_Service_Interface *iface, const char *name, Eina_Bool is_invalidate) +{ + Property *prop; + + EDBUS_SERVICE_INTERFACE_CHECK_RETVAL(iface, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); + + prop = eina_hash_find(iface->properties, name); + EINA_SAFETY_ON_NULL_RETURN_VAL(prop, EINA_FALSE); + + if (prop->is_invalidate == is_invalidate) + return EINA_TRUE; + + prop->is_invalidate = is_invalidate; + + if (!iface->idler_propschanged) + iface->idler_propschanged = ecore_idler_add(_idler_propschanged, iface); + + if (is_invalidate) + { + if (!iface->props_changed) + iface->props_changed = eina_array_new(1); + return eina_array_push(iface->props_changed, prop); + } + + if (!iface->prop_invalidated) + iface->prop_invalidated = eina_array_new(1); + return eina_array_push(iface->prop_invalidated, prop); +} diff --git a/legacy/edbus/src/lib/edbus_service.h b/legacy/edbus/src/lib/edbus_service.h index 761797cede..d20700316f 100644 --- a/legacy/edbus/src/lib/edbus_service.h +++ b/legacy/edbus/src/lib/edbus_service.h @@ -153,6 +153,8 @@ EAPI void *edbus_service_object_data_del(EDBus_Service_Interface *iface, const c * properties in changed list. */ EAPI Eina_Bool edbus_service_property_changed(EDBus_Service_Interface *iface, const char *name); + +EAPI Eina_Bool edbus_service_property_invalidate_set(EDBus_Service_Interface *iface, const char *name, Eina_Bool is_invalidate); /** * @} */