After writing an interface, I wanted some helpers for the "usual case" of fields in the struct directly matching properties, and that turned in to this idea:
struct Foo {
bar : i32,
baz : HashMap<String, Vec<String>>,
baz2 : HashMap<String, Vec<String>>,
bell : Arc<Bell>,
id: u64,
hair: u64,
}
struct Bell {
ding : Mutex<i32>,
dong : Mutex<i32>,
}
#[dbus_interface(name = "org.example.Foo")]
impl Foo {
fn split_hair(&mut self) {
self.hair = self.hair * 2 - 1;
}
fn add_baz(&mut self, k : String, v : String, #[zbus(signal_context)] ctx) {
self.baz.entry(k).or_default().push(v);
Foo::emit_baz_changed(&ctx, &self.baz);
}
dbus_property!(bar: i32, readwrite);
dbus_property!(baz: HashMap<String, Vec<String>>, readonly, emits_changed);
// org.freedesktop.DBus.Property.EmitsChangedSignal for bar and baz are set to true
fn add_baz2(&mut self, k : String, v : String, #[zbus(signal_context)] ctx) {
self.baz2.entry(k).or_default().push(v);
Foo::emit_baz2_changed(&ctx);
}
dbus_property!(baz2: HashMap<String, Vec<String>>, readonly, invalidates);
// org.freedesktop.DBus.Property.EmitsChangedSignal for baz2 is set to invalidates
dbus_property!(id: u64, readonly, const);
// org.freedesktop.DBus.Property.EmitsChangedSignal for id is set to const
dbus_property!(hair: u64, readonly, uncached);
// org.freedesktop.DBus.Property.EmitsChangedSignal for hair is set to false
// Long version 1, same as today
#[dbus_interface(property)]
fn dong(&self) -> i32 {
*self.bell.dong.lock()
}
fn set_dong(&self, value: i32) {
*self.bell.dong.lock() = value;
}
// Long version 2, value get
dbus_property!(ding: i32, readwrite, access = fn(&self) {
self.bell.ding.lock()
});
// "access" is expanded to a function or closure whose return type is
// "-> impl Deref<Target=i32>" (-> &mut i32 for the simple case).
// For readonly properties, "-> impl Deref" and "-> &T" would also be allowed;
// the normal interface already handles "-> T"
}
The Bell struct is an example of a good way to have an interface whose data is available outside the ObjectServer. I think it would be useful to make this pattern (or one with Arc<Mutex<Bell>>) simpler to use; I'll make another issue for that to avoid tangling the conversation too much.
In GitLab by @danieldg on Sep 11, 2021, 22:18
After writing an interface, I wanted some helpers for the "usual case" of fields in the struct directly matching properties, and that turned in to this idea:
The
Bell
struct is an example of a good way to have an interface whose data is available outside theObjectServer
. I think it would be useful to make this pattern (or one withArc<Mutex<Bell>>
) simpler to use; I'll make another issue for that to avoid tangling the conversation too much.