1919 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2020 */
2121
22- #[ macro_export]
23- #[ doc( hidden) ]
24- macro_rules! check_recursion {
25- ( $widget: ident) => {
26- if $widget. try_borrow_mut( ) . is_err( ) {
27- panic!( "An event to the same widget was emitted in the update() method, which would cause an infinite \
28- recursion.\n This can be caused by calling a gtk+ function that is connected to send a message \
29- to the same widget.\n Inspect the stack trace to determine which call it is.\n Then you can either \
30- refactor your code to avoid a cyclic event dependency or block events from being emitted by doing \
31- the following:\n {\n let _lock = self.model.relm.stream().lock();\n // Your panicking call.\n }\
32- \n See this example: \
33- https://github.com/antoyo/relm/blob/feature/futures-glib/examples/checkboxes.rs#L88\
34- This issue can also happen when emitting a signal to the same widget, in which case you need to\
35- refactor your code to avoid this cyclic event dependency.") ;
36- }
37- } ;
38- }
39-
4022/// Connect events to sending a message.
4123///
4224/// Rule #1:
@@ -50,21 +32,20 @@ macro_rules! check_recursion {
5032/// Option<MSG> can be None if no message needs to be emitted.
5133///
5234/// Rule #3:
53- /// Send `$msg` when the GTK+ `$event` is emitted on `$widget`.
35+ /// Send `$msg` with a Resolver and block the callback into it resolves to a value.
36+ /// This is useful in case you need an access to the model to decide whether you want to inhibit
37+ /// the event or not.
5438///
5539/// Rule #4:
40+ /// Send `$msg` when the GTK+ `$event` is emitted on `$widget`.
41+ ///
42+ /// Rule #5:
5643/// Send `$msg` to `$widget` when the `$message` is received on `$stream`.
5744#[ macro_export]
5845macro_rules! connect {
5946 // Connect to a GTK+ widget event, sending a message to another widget.
6047 ( $widget: expr, $event: ident( $( $args: pat) ,* ) , $other_component: expr, $msg: expr) => {
61- let stream = $other_component. stream( ) . clone( ) ;
62- $widget. $event( move |$( $args) ,* | {
63- let msg: Option <_> = $crate:: IntoOption :: into_option( $msg) ;
64- if let Some ( msg) = msg {
65- stream. emit( msg) ;
66- }
67- } ) ;
48+ connect_stream!( $widget, $event( $( $args) ,* ) , $other_component. stream( ) , $msg) ;
6849 } ;
6950
7051 // Connect to a GTK+ widget event.
@@ -114,7 +95,35 @@ macro_rules! connect {
11495 // Connect to a message reception.
11596 // TODO: create another macro rule accepting multiple patterns.
11697 ( $src_component: ident @ $message: pat, $dst_component: expr, $msg: expr) => {
117- let stream = $dst_component. stream( ) . clone( ) ;
98+ connect_stream!( $src_component@$message, $dst_component. stream( ) , $msg) ;
99+ } ;
100+ }
101+
102+ /// Connect events to sending a message.
103+ /// Similar to `connect!` but wants a stream instead of a component.
104+ ///
105+ /// Rule #1:
106+ /// Send `$msg` to `$other_stream` when the GTK+ `$event` is emitted on `$widget`.
107+ ///
108+ /// Rule #2:
109+ /// Send `$msg` to `$widget` when the `$message` is received on `$stream`.
110+ #[ macro_export]
111+ macro_rules! connect_stream {
112+ // Connect to a GTK+ widget event, sending a message to another widget.
113+ ( $widget: expr, $event: ident( $( $args: pat) ,* ) , $other_stream: expr, $msg: expr) => {
114+ let stream = $other_stream. clone( ) ;
115+ $widget. $event( move |$( $args) ,* | {
116+ let msg: Option <_> = $crate:: IntoOption :: into_option( $msg) ;
117+ if let Some ( msg) = msg {
118+ stream. emit( msg) ;
119+ }
120+ } ) ;
121+ } ;
122+
123+ // Connect to a message reception.
124+ // TODO: create another macro rule accepting multiple patterns.
125+ ( $src_component: ident @ $message: pat, $dst_stream: expr, $msg: expr) => {
126+ let stream = $dst_stream. clone( ) ;
118127 $src_component. stream( ) . observe( move |msg| {
119128 #[ allow( unreachable_patterns) ]
120129 match msg {
0 commit comments