gpt4 book ai didi

Rust:保持相同帧速率的宏不起作用

转载 作者:行者123 更新时间:2023-12-03 11:41:42 25 4
gpt4 key购买 nike

为了保持一定的帧率,我一直在使用 std::thread::sleep()等到足够的时间过去。计算它的 sleep 时间会使代码有点困惑,所以我尝试为它制作一个宏。现在就是这样,但它不起作用:

macro_rules! fps30 {
($($body: expr;);*) => {
let time = std::time::Instant::now()

$($body)*

let time_elapsed = time.elapsed().as_micros();
if FRAME_TIME_30FPS_IN_MICROS > time_elapsed {
let time_to_sleep = FRAME_TIME_30FPS_IN_MICROS - time_elapsed;
std::thread::sleep(std::time::Duration::from_micros(time_to_sleep as u64));
}

};
}
我想像这样使用它:
loop {
fps30!{
// do everything I want to do in the loop
}
}
当我不将它实现为宏时(通过直接将代码粘贴到循环中),它可以工作,并且每秒保持 29 帧(我猜不是 30 帧,因为 sleep 计算的开销很小)。它在编译期间给出的错误状态: no rules expected the token 'p' , 其中 p是我在宏中使用的对象/结构实例。
有什么建议么?

最佳答案

问题在于 ; 的处理。在:

$($($body: expr;);*)
当您想接受 ;分隔的表达式列表,你应该写 $($($body: expr;)*)$($($body: expr);*) .前者表示 ; 的列表- 终止的表达式,而后者是 ; 的列表- 分隔的表达式。
差异是微妙但重要的。如果同时添加两者,则需要编写两个 ;;分隔每个表达式。
如果您接受 ; 的列表会更好终止表达式,所以这样做:
$($($body: expr;)*)
然后你在宏的主体中有几个错误,也与 ; 相关。 .您缺少 ;扩容前 $body :
let time = std::time::Instant::now();
你错过了 ;$body 的扩展中本身,因为 ;不属于捕获的 expr :
$($body;)*
通过这些更改,它可以工作,除非您尝试:
fps30!{
if a {
}
if a {
}
}
因为没有 ;if 之后表达!!!您可以尝试切换到:
$($($body: expr);*)
但它也不起作用,现在因为没有 ;表情之间!
您可以接受单个 $body: block但随后您将需要再写几篇 {} .不理想...
如果您真的想接受任何类型的代码块,我建议您接受 token 树列表 ( tt)。并且在扩展它们时,将它们包含在 {} 中,以防它不以 ; 结尾.
macro_rules! fps30 {
($($body: tt)*) => {
let time = std::time::Instant::now();
{ $($body)* }
let time_elapsed = time.elapsed().as_micros();
//...
};
}
现在您的宏将接受任何类型的语法,并将在宏内部无声地扩展它。
您甚至可以添加 $body 的可能性具有类型和值,并使 fps30评估为该值`:
let res = { $($body)* };
//...
res
作为一个额外的好处,如果你写了一个语法错误,它会在编译代码时失败,而不是在扩展宏时,这更容易调试。

关于Rust:保持相同帧速率的宏不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63443149/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com