Rust时雄select宏条件睡眠分支

gmxoilav  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(104)

我有一个异步选择宏循环,用于处理我正在编写的CLI游戏中的用户输入和事件间隔。我希望能够有条件地设置一个睡眠倒计时内以及。我试着声明一个Option<Sleep>,它的值在循环的每次迭代中都被设置,检查是否满足条件。

async fn run(game: &mut Game) {
    let mut reader = EventStream::new();

    draw().unwrap();

    let mut render_interval = interval(Duration::from_nanos(1_000_000_000 / TARGET_FRAME_RATE));
    let mut drop_interval = interval(Duration::from_millis(1_000 / game.level as u64));

    let mut lock_delay: Option<Sleep>;

    loop {

        lock_delay = if game.locking { Some(sleep(Duration::from_millis(500))) } else { None }; // check if  condition has been met yet

        select! {
            maybe_event = reader.next().fuse() => {
                match maybe_event {
                    Some(Ok(event)) => {
                        if let Event::Key(key) = event {
                            match key.code {
                                KeyCode::Char('w') | KeyCode::Char('W') | KeyCode::Up => {
                                    game.rotate(RotationDirection::Clockwise)
                                },
                                KeyCode::Char('a') | KeyCode::Char('A') | KeyCode::Left => {
                                    game.shift(ShiftDirection::Left)
                                },
                                KeyCode::Char('s') | KeyCode::Char('S') | KeyCode::Down => {
                                    game.soft_drop()
                                },
                                KeyCode::Char('d') | KeyCode::Char('D') | KeyCode::Right => {
                                    game.shift(ShiftDirection::Right)
                                },
                                KeyCode::Char(' ') => {
                                    game.hard_drop()
                                },
                                KeyCode::Char('z') | KeyCode::Char('Z') => {
                                    game.rotate(RotationDirection::CounterClockwise)
                                },
                                KeyCode::Char('c') | KeyCode::Char('C') => {
                                    game.hold()
                                },
                                KeyCode::Char('q') | KeyCode::Char('Q') | KeyCode::Esc => {
                                    break
                                },
                                _ => (),
                            }
                        }
                    },
                    Some(Err(error)) => panic!("{}", error),
                    None => (),
                }
            },
            _ = drop_interval.tick() => {
                game.shift(ShiftDirection::Down)
            },
            _ = lock_delay => {
                debug_println!("PLACING");
                game.place();
            },
            _ = render_interval.tick() => {
                render(game).unwrap()
            },
        };
    }
}

字符串
这当然不起作用,因为lock_interval不是Future类型,不能用作select中的分支。

`Option<Sleep>` is not a future
the trait `futures::Future` is not implemented for `Option<Sleep>`
Option<Sleep> must be a future or must implement `IntoFuture` to be awaitedrustcClick for full compiler diagnostic


我已经尝试了很多其他方法,例如当条件返回false时使用Duration::from_secs(u64::MAX)而不是None,避免了对Option的需要,但它似乎不起作用。
我也试着引用了一个老的reddit帖子的一些建议:https://www.reddit.com/r/learnrust/comments/zh4deb/tokioselect_on_an_option_using_if/,但没有成功。
简而言之,我需要一些方法,我可以有条件地设置一个选择宏内的睡眠倒计时。
任何帮助或想法都将非常感谢,我有有限的异步编程经验,我相信有一个完全不同的方法来解决这个问题。

1tuwyuhd

1tuwyuhd1#

您可以创建一个异步块,而不是创建一个Option

let lock_delay = async {
    if game.locking {
        sleep(Duration::from_millis(500)).await;
    } else {
        futures::future::pending().await;
    }
};

字符串

相关问题