forked from enlightenment/efl
edbus: Add invalidate to EDBus_Property
Patch by: José Roberto de Souza <zehortigoza@profusion.mobi> SVN revision: 79036
This commit is contained in:
parent
ffc6f5cf9f
commit
5169b73515
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue