gtk-rs / glib

DEPRECATED, use https://github.com/gtk-rs/gtk-rs-core repository instead!
http://gtk-rs.org/
MIT License
93 stars 62 forks source link

Custom Glib signals in user-defined structs #265

Closed meadofpoetry closed 5 years ago

meadofpoetry commented 6 years ago

Is there any way I could implement mainloop-aware signal for my struct? In glibmm there is sigc which is pretty awesome since it allows to define statically typed signals. In python bindings I could set "gsignals" property. How could I define signals in rust bindings?

sdroege commented 6 years ago

You mean defining your own signals for your own types? That's currently not possible with safe code, but work is being done here to allow creating new subclasses of GObject and other types: https://github.com/federicomenaquintero/gnome-class

You can do it with (quite a lot) unsafe code though, see here for some overview: https://coaxion.net/blog/2017/09/exporting-a-gobject-c-api-from-rust-code-and-using-it-from-c-python-javascript-and-others/

meadofpoetry commented 6 years ago

@sdroege Thanks for reply. Yeah, I think I can replace signals in my app by plain callbacks for now, though it would be useful to be able to define signals for the sake of writing libraries.

sdroege commented 6 years ago

If your code is only supposed to be used from other Rust code, it would probably make more sense to implement a Rust-based signals/slots system instead of going via GObject. Going via GObject only really makes sense if you want to interoperate with C code, or any other language via automatic bindings created from the GObject introspection data.

meadofpoetry commented 6 years ago

@sdroege sure, I'll better stick to reactive programming in this case. Thanks.

sdroege commented 6 years ago

For UI programming that's definitely nicer, but it's a different approach. A generic signals/slots system for Rust would be useful to have nonetheless.

meadofpoetry commented 6 years ago

@sdroege do you know any decent signal/slot or reactive stream/event library which does not rely on it's own event loop (i.e. works fine with Glib's mainloop).

sdroege commented 6 years ago

Note that signals in GObject have nothing to do with the mainloop. They're just glorified function calls in the end, and you get your callbacks called from the very same thread as where the signal was emitted. Which in the case of GTK happens to be the main thread (that runs the mainloop), but that's just coincidence.

You could take a look at relm for a GTK based reactive UI library: https://github.com/antoyo/relm

meadofpoetry commented 6 years ago

I'm not interested in Gtk actually, writing a gstreamer app. Just used to reactive programming since it has lots of benefits (composable signals and streams, many composition primitives out of the box, safety). It seems I have to just implement signals/slots by myself.

sdroege commented 6 years ago

Ah, I thought you were looking for something GTK related. For GStreamer, it depends on what kind of "events" you want to work with. There's a tokio based gst::Bus adapter, which allows you to handle bus messages as a tokio Stream. https://sdroege.github.io/rustdoc/gstreamer/gstreamer/struct.BusStream.html

sdroege commented 6 years ago

Also, in the case of GStreamer there is nothing that requires a GLib mainloop or any mainloop at all. The Bus can only be integrated into the GLib mainloop (or tokio's reactor or anything else really) for receiving the messages from there.

And all the signals on objects are emitted from arbitrary threads, not any kind of main thread.

meadofpoetry commented 6 years ago

I'll investigate it. Actually I have no problems with gobject/gstreamer signals and messages, I've just looked for a way to implement an event mechanism for my own data structures that will naturally fit in the whole glib/gstreamer framework concept. In c++ it was convenient to use sigc for both gobject signals and my own classes.

The Bus can only be integrated into the GLib mainloop (or tokio's reactor or anything else really) for receiving the messages from there.

Yeah, thanks for the explanation, I've always thought that mainloop is needed for gobject signals and all messaging stuff (e.g. passing buffers and events between elements).

sdroege commented 5 years ago

Nothing to be done here. Signals can be implemented in new GObject subclasses now.