2 个版本
使用旧的 Rust 2015
0.1.1 | 2016 年 3 月 13 日 |
---|---|
0.1.0 | 2016 年 3 月 13 日 |
2272 在 Rust 模式
20KB
312 行 行
当前问题
考虑一个事件循环,定义如下
let (tx, rx) = channel();
thread::spawn(move || {
for event in rx {
match event {
UIEvent::KeyboardEvent(ev) => { ... },
UIEvent::MouseEvent(ev) => { ... },
...
}
}
});
现在,想象一个可以监听键盘事件的系统库,具有以下签名
impl ThirdPartyLibrary {
fn register_watch(&self, on_event: Sender<PrimitiveKeyboardEvent>) -> ...;
}
我们如何与这个库交互?嗯,使用 Sender
,唯一的办法是启动另一个线程,如下所示
let (tx2, rx2) = channel();
let tx = tx.clone(); // That's the tx for my event loop, see above.
thread::spawn(move || {
for ev in rx {
match tx.send(UIEvent::KeyboardEvent(ev) {
Ok(_) => {},
Err(_) => return, // Cleanup if nobody is listening anymore.
}
}
});
third_party_library.register_watch(tx2);
如果我们可以编写以下内容并使其在没有启动线程的情况下工作,那不是更好且更节省资源吗?
third_party_library.register_watch(tx.map(|ev| UIEvent::KeyboardEvent(ev)));
现在,让我们假设情况稍微复杂一些,并且我们的系统需要处理多个键盘。现在,我们需要给每个键盘分配一个唯一的键。
使用 Sender
,唯一的解决方案是为每个键盘启动 一个线程,即
let key = ...;
let (tx3, rx3) = channel();
let tx = tx.clone(); // That's the tx for my event loop, see above.
thread::spawn(move || {
for ev in rx {
match tx.send(UIEvent::KeyboardEvent(key, ev) {
Ok(_) => {},
Err(_) => return, // Cleanup if nobody is listening anymore.
}
}
});
third_party_library.register_watch(tx3);
如果我们可以编写以下内容并使其在没有启动线程的情况下工作,那不是更好且更节省资源吗?
let key = ...;
third_party_library.register_watch(tx.map(move |ev| UIEvent::KeyboardEvent(key, ev)));
这个软件包旨在实现更优雅且更节省资源的策略。