diff options
author | Yorhel <git@yorhel.nl> | 2013-04-13 17:53:52 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2013-04-13 17:53:52 +0200 |
commit | e4fcaf1b48a7c9a1d74a95ffc09a723af63856ef (patch) | |
tree | a1aad9782909c9cfa9df89ab98cd84bb152664dd | |
parent | 19bd62ebe6fbbe4f21cf6ad943d1d4ca654d0086 (diff) |
dbo+itfgen: Allow for grouping multiple PropertiesChanged signals
-rw-r--r-- | src/dbo.c | 40 | ||||
-rw-r--r-- | src/dbo.h | 18 | ||||
-rwxr-xr-x | src/itfgen.pl | 20 |
3 files changed, 47 insertions, 31 deletions
@@ -408,35 +408,31 @@ void dbo_register(dbo_t *o, const char *path, const dbo_reg_t *regs, int numregs } -void dbo_prop_invalidate(const char *path, const dbo_interface_t *itf, int idx) { - DBusMessageIter iter, sub; - DBusMessage *msg = dbus_message_new_signal(path, DBUS_INTERFACE_PROPERTIES, "PropertiesChanged"); - dbus_message_iter_init_append(msg, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &itf->name); - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub); - dbus_message_iter_close_container(&iter, &sub); - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub); - dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &(itf->properties[idx].name)); - dbus_message_iter_close_container(&iter, &sub); - dbo_sendfree(msg); -} - +void dbo_prop_changed(dbo_prop_changed_t props, void *obj, const dbo_interface_t *itf, void *table) { + int i; + if(!props.n) + return; -/* Update a property */ -void dbo_prop_changed(const char *path, const dbo_interface_t *itf, int idx, void *table) { DBusMessageIter iter, sub, sub2, sub3; - DBusMessage *msg = dbus_message_new_signal(path, DBUS_INTERFACE_PROPERTIES, "PropertiesChanged"); + DBusMessage *msg = dbus_message_new_signal(((dbo_t*)obj)->path, DBUS_INTERFACE_PROPERTIES, "PropertiesChanged"); dbus_message_iter_init_append(msg, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &itf->name); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub); - dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, NULL, &sub2); - dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &(itf->properties[idx].name)); - dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, itf->properties[idx].type, &sub3); - itf->properties[idx].getter(table, &sub3); - dbus_message_iter_close_container(&sub2, &sub3); - dbus_message_iter_close_container(&sub, &sub2); + if(table) { + for(i=0; i<props.n; i++) { + dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, NULL, &sub2); + dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &(itf->properties[props.l[i]].name)); + dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, itf->properties[props.l[i]].type, &sub3); + itf->properties[props.l[i]].getter(table, &sub3); + dbus_message_iter_close_container(&sub2, &sub3); + dbus_message_iter_close_container(&sub, &sub2); + } + } dbus_message_iter_close_container(&iter, &sub); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub); + if(!table) + for(i=0; i<props.n; i++) + dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &(itf->properties[props.l[i]].name)); dbus_message_iter_close_container(&iter, &sub); dbo_sendfree(msg); } @@ -125,10 +125,20 @@ static inline void dbo_prop_reply(DBusMessage *msg) { } -/* Update a property. Called from the dbo_*_set() wrappers generated by - * itfgen.pl */ -void dbo_prop_invalidate(const char *path, const dbo_interface_t *itf, int idx); -void dbo_prop_changed(const char *path, const dbo_interface_t *itf, int idx, void *table); +/* API for sending out the PropertiesChanged signal */ + +typedef struct { + unsigned char n; + /* Property indices to notify. This struct definition imposes a limit of 7 + * properties per batch notification, and requires that an interface has no + * more than 256 properties. The upside is that the struct can easily be + * stack-allocated. (In fact, this struct is as small as a int64_t) */ + unsigned char l[7]; +} dbo_prop_changed_t; + +/* If table == NULL, the properties will only be invalidated. Otherwise, their + * values will be sent with the signal. */ +void dbo_prop_changed(dbo_prop_changed_t props, void *obj, const dbo_interface_t *itf, void *table); #endif diff --git a/src/itfgen.pl b/src/itfgen.pl index 681d35b..21b2153 100755 --- a/src/itfgen.pl +++ b/src/itfgen.pl @@ -283,7 +283,7 @@ sub prop_getter { } -# The _set_noemit(), _set(), _setreply() and DBO_*_SETTER() functions/macros. +# The _set_noemit(), _set(), _add_batch(), _set_batch(), _setreply() and DBO_*_SETTER() functions/macros. sub prop_setter { my($itf, $i) = @_; local $_ = $itf{$itf}{properties}[$i]; @@ -302,14 +302,24 @@ sub prop_setter { $r .= "\treturn dbo_${itf}_$_->{name}_set_noemit(p, val);\n"; } else { $r .= "\tbool changed = dbo_${itf}_$_->{name}_set_noemit(p, val);\n"; - $r .= "\tif(changed)\n"; - $r .= $_->{flags} =~ /emitchange/ - ? "\t\tdbo_prop_invalidate(((dbo_t *)obj)->path, &dbo_${itf}_interface, $i);\n" - : "\t\tdbo_prop_changed(((dbo_t *)obj)->path, &dbo_${itf}_interface, $i, p);\n"; + $r .= "\tdbo_prop_changed((dbo_prop_changed_t){changed,{$i}}, obj, &dbo_${itf}_interface, ". + ($_->{flags} =~ /emitchange/ ? 'NULL' : 'p').");\n"; $r .= "\treturn changed;\n"; } $r .= "}\n"; + $r .= "static inline void dbo_${itf}_$_->{name}_add_batch(dbo_prop_changed_t *props) {\n"; + $r .= "\tprops->l[props->n++] = $i;\n"; + $r .= "}\n"; + + $r .= "static inline bool dbo_${itf}_$_->{name}_set_batch(". + "dbo_prop_changed_t *props, dbo_${itf}_properties_t *p, ".sig_ctypec($_->{type})." val) {\n"; + $r .= "\tbool changed = dbo_${itf}_$_->{name}_set_noemit(p, val);\n"; + $r .= "\tif(changed)\n"; + $r .= "\t\tdbo_${itf}_$_->{name}_add_batch(props);\n"; + $r .= "\treturn changed;\n"; + $r .= "}\n"; + if($_->{access} =~ /w/) { $r .= "static inline bool dbo_${itf}_$_->{name}_setreply(void *obj, dbo_${itf}_properties_t *p, DBusMessage *msg, ".sig_ctypec($_->{type})." val) {\n"; $r .= "\tdbo_prop_reply(msg);\n"; |