Skip to content

Commit 4b086c3

Browse files
committed
Add connect_stream! macro
1 parent 875a35b commit 4b086c3

1 file changed

Lines changed: 36 additions & 27 deletions

File tree

relm-state/src/macros.rs

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,6 @@
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.\nThis can be caused by calling a gtk+ function that is connected to send a message \
29-
to the same widget.\nInspect the stack trace to determine which call it is.\nThen 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-
\nSee 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]
5845
macro_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

Comments
 (0)