Have a look at this code:
use std::future::Future;
use std::pin::Pin;
use macroquad::prelude::*;
use crate::ball::Ball;
use crate::physics::Experiment;
use crate::vector_2d::Vector2D;
#[macroquad::main("BasicShapes")]
async fn main() {
let mut experiment = Experiment::new();
experiment.balls.push(Ball::new(Vector2D { x: 500.0, y: 200.0 }, 10.0));
loop {
clear_background(BLACK);
experiment.balls.iter().for_each(|ball| {
draw_circle(ball.verlet_object.position_current.x, ball.verlet_object.position_current.y, ball.radius, BLUE);
});
next_frame().await
}
}
It compiles and executes just fine. I wanted to add a mechanism that will limit the FPS.
Here’s my take on it:
use std::future::Future;
use std::pin::Pin;
use macroquad::prelude::*;
use crate::ball::Ball;
use crate::physics::Experiment;
use crate::vector_2d::Vector2D;
#[macroquad::main("BasicShapes")]
async fn main() {
let frames_controller = FramesController::new(60);
let mut experiment = Experiment::new();
experiment.balls.push(Ball::new(Vector2D { x: 500.0, y: 200.0 }, 10.0));
loop {
frames_controller.control_frame(async || {
clear_background(BLACK);
experiment.balls.iter().for_each(|ball| {
draw_circle(ball.verlet_object.position_current.x, ball.verlet_object.position_current.y, ball.radius, BLUE);
});
next_frame().await
}).await;
}
}
pub struct FramesController {
pub max_frames_per_second: u32
}
impl FramesController {
pub fn new(max_frames_per_second: u32) -> Self {
Self { max_frames_per_second }
}
pub async fn control_frame<F>(&self, func: F) where
F: Fn() -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> {
func().await;
}
}
Regarding the F: Fn() -> Pin<Box<dyn Future<Output = ()> + Send + 'static>>
thing – I have no idea what I’m doing here, it’s something that ChatGPT spit out.
The code does not compile, I get errors:
>: cargo run
Compiling twod-sim v0.1.0 (/home/mnj/code/private/twod-sim)
error[E0658]: async closures are unstable
--> src/main.rs:19:41
|
19 | frames_controller.control_frame(async || {
| ^^^^^
|
= note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
= help: to use an async block, remove the `||`: `async {`
error[E0271]: expected `{async [email protected]:19:41}` to be a closure that returns `Pin<Box<dyn Future<Output = ()> + Send>>`, but it returns `{async closure body@src/main.rs:19:50:
--> src/main.rs:19:41
|
19 | frames_controller.control_frame(async || {
| ___________________________-------------_^
| | |
| | required by a bound introduced by this call
20 | | clear_background(BLACK);
21 | |
22 | | experiment.balls.iter().for_each(|ball| {
... |
27 | |
28 | | }).await;
| |_________^ expected `Pin<Box<dyn Future<Output = ()> + Send>>`, found `async` closure body
|
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + Send + 'static)>>`
found `async` closure body `{async closure body@src/main.rs:19:50: 28:10}`
note: required by a bound in `FramesController::control_frame`
--> src/main.rs:42:20
|
41 | pub async fn control_frame<F>(&self, func: F) where
| ------------- required by a bound in this associated function
42 | F: Fn() -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `FramesController::control_frame`
error[E0271]: expected `{async [email protected]:19:41}` to be a closure that returns `Pin<Box<dyn Future<Output = ()> + Send>>`, but it returns `{async closure body@src/main.rs:19:50:
--> src/main.rs:19:9
|
19 | / frames_controller.control_frame(async || {
20 | | clear_background(BLACK);
21 | |
22 | | experiment.balls.iter().for_each(|ball| {
... |
27 | |
28 | | }).await;
| |__________^ expected `Pin<Box<dyn Future<Output = ()> + Send>>`, found `async` closure body
|
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + Send + 'static)>>`
found `async` closure body `{async closure body@src/main.rs:19:50: 28:10}`
note: required by a bound in `FramesController::control_frame`
--> src/main.rs:42:20
|
41 | pub async fn control_frame<F>(&self, func: F) where
| ------------- required by a bound in this associated function
42 | F: Fn() -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `FramesController::control_frame`
error[E0271]: expected `{async [email protected]:19:41}` to be a closure that returns `Pin<Box<dyn Future<Output = ()> + Send>>`, but it returns `{async closure body@src/main.rs:19:50: 28:10}`
--> src/main.rs:28:12
|
19 | frames_controller.control_frame(async || {
| __________________________________________________-
20 | | clear_background(BLACK);
21 | |
22 | | experiment.balls.iter().for_each(|ball| {
... |
27 | |
28 | | }).await;
| | - ^^^^^ expected `Pin<Box<dyn Future<Output = ()> + Send>>`, found `async` closure body
| |_________|
| the found `async` closure body
|
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + Send + 'static)>>`
found `async` closure body `{async closure body@src/main.rs:19:50: 28:10}`
note: required by a bound in `FramesController::control_frame`
--> src/main.rs:42:20
|
41 | pub async fn control_frame<F>(&self, func: F) where
| ------------- required by a bound in this associated function
42 | F: Fn() -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `FramesController::control_frame`
Some errors have detailed explanations: E0271, E0658.
For more information about an error, try `rustc --explain E0271`.
I have no idea how to make it work. I didn’t even get to implementing the actual FPS limiting logic, at the moment I’d just want to run the code as I have it, through FramesController
.