summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2013-04-13 17:53:52 +0200
committerYorhel <git@yorhel.nl>2013-04-13 17:53:52 +0200
commite4fcaf1b48a7c9a1d74a95ffc09a723af63856ef (patch)
treea1aad9782909c9cfa9df89ab98cd84bb152664dd
parent19bd62ebe6fbbe4f21cf6ad943d1d4ca654d0086 (diff)
dbo+itfgen: Allow for grouping multiple PropertiesChanged signals
-rw-r--r--src/dbo.c40
-rw-r--r--src/dbo.h18
-rwxr-xr-xsrc/itfgen.pl20
3 files changed, 47 insertions, 31 deletions
diff --git a/src/dbo.c b/src/dbo.c
index 7ba3d73..c385877 100644
--- a/src/dbo.c
+++ b/src/dbo.c
@@ -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);
}
diff --git a/src/dbo.h b/src/dbo.h
index 9c487e8..ba92688 100644
--- a/src/dbo.h
+++ b/src/dbo.h
@@ -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";