#async #async-await #ndless #integration #key #timer #ti-nspire

nightly ndless-async

Ndless 对 TI-Nspire 的异步/await 的特定集成

3 个版本

0.1.2 2020 年 5 月 17 日
0.1.1 2020 年 5 月 13 日
0.1.0 2020 年 5 月 13 日

#1901异步

每月 22 次下载

MIT/Apache

520KB
9K SLoC

ndless-async

Crates.io Docs.rs

Ndless 对 TI-Nspire 的异步/await 的特定集成

此包提供了一个执行器、反应器和实用工具,以便在 TI Nspire 的定时器和按键中使用 Rust 的 async 功能。请注意,通常 async 函数用于 I/O。然而,据我所知,TI-Nspire 的操作系统没有任何形式的异步 I/O 支持。然而,这仍然提供了同时做很多事情的有用工具,比如带有超时的等待按键。

您首先需要使用 AsyncListenersAsyncListeners::default() 创建一个实例。这允许您从 Nspire 的定时器接收事件。从那里,您可以将其传递到 task::block_on,以及您选择的 Future

有用的资源

查看 Rust Async 书籍。这里有一些关于异步编程的有用说明。尽管它主要是为与完整的操作系统一起使用而编写的,但除了第 1.4、6.3、8 和 10 章外,所有内容都适用。

futures_util 有许多有用的实用函数。通过在您的 Cargo.toml 中添加以下内容将它们添加到您的项目中

futures-util = { version = "0.3.5", default-features = false, features = ["alloc", "async-await-macro"] }

您可能会发现其 FuturesUnordered 对安排多个任务有所帮助。虽然像 joinfirst 这样的宏可能会有所帮助,但它们的效率和灵活性不如它。

joinselecttry_join 以及特质 FutureExtStreamExt 都从它重新导出,所以如果您只需要这些,您不需要直接依赖它。

示例

use futures_util::future;
use ndless_async::task::{block_on, AsyncListeners};
use ndless_async::{first, StreamExt};
use ndless_async::keypad::KeypadListener;
use ndless::input::Key;

fn main() {
    let listeners = AsyncListeners::new();
    let keypad = KeypadListener::new(&listeners.timer());
    block_on(&listeners, async {
        let _ = listeners.timer().timeout_ms(5000, do_stuff(&keypad)).await;
        listeners.timer().sleep_ms(2000).await;
        first!(do_other_stuff(&listeners), wait_for_esc(&keypad));
    });
}

async fn wait_for_esc(keypad: &KeypadListener<'_>) {
    keypad
        .stream()
        .filter(|key| future::ready(key.key == Key::Esc))
        .next()
        .await;
}

async fn do_other_stuff(listeners: &AsyncListeners) {
    loop {
        listeners.timer().sleep_ms(1000).await;
        println!("1s!");
    }
}

async fn do_stuff(listeners: &KeypadListener<'_>) {
    use ndless_async::keypad::KeyState::*;
    let mut keypad = listeners.stream();
    while let Some(event) = keypad.next().await {
        println!(
            "Key {:?} was {}",
            event.key,
            if event.state == Released {
                "released"
            } else {
                "pressed"
            }
        );
        print!("Keys currently pressed: ");
        listeners
            .list_keys()
            .iter()
            .for_each(|key| print!("{:?} ", key));
        println!();
        if event.key == Key::Esc { break; }
    }
}

除了这个包之外,还要查看 ndless

依赖项

~3MB
~68K SLoC