edbus: Add invalidate to EDBus_Property

Patch by: José Roberto de Souza  <zehortigoza@profusion.mobi>



SVN revision: 79036
This commit is contained in:
José Roberto de Souza 2012-11-09 18:35:20 +00:00 committed by Lucas De Marchi
parent ffc6f5cf9f
commit 5169b73515
5 changed files with 115 additions and 35 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -136,11 +136,17 @@ _introspect_append_method(Eina_Strbuf *buf, const EDBus_Method *method)
eina_strbuf_append(buf, "</method>");
}
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, "</interface>");
@ -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);
}

View File

@ -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);
/**
* @}
*/