#async example not working for me

12 messages · Page 1 of 1 (latest)

undone valve
#

Code:

use std::{clone, future};

use bevy::{
    ecs::system::CommandQueue,
    prelude::*,
    tasks::{prelude::*, Task},
};
use futures_lite::{future::block_on, FutureExt};

pub struct ViewWorldPlugin;

impl Plugin for ViewWorldPlugin {
    fn build(&self, app: &mut App) {
        app.add_state::<LoadingState>()
            .add_systems(Startup, spawn_tasks)
            .add_systems(Update, handle_tasks)
            .add_systems(OnExit(LoadingState::Loading), draw_map);
    }
}

#[derive(States, Debug, Hash, PartialEq, Eq, Clone, Default)]
pub enum LoadingState {
    #[default]
    Loading,
    Loaded,
}

#[derive(Resource, Debug)]
pub struct Map {
    tiles: Vec<Tile>,
}

#[derive(Debug)]
pub struct Tile {
    x: i32,
    y: i32,
    z: i32,
}
#[derive(Component)]
pub struct WorldGen(Task<String>);

fn spawn_tasks(mut commands: Commands) {
    let thread_pool = AsyncComputeTaskPool::get();

    let entity = commands.spawn_empty().id();

    let task = thread_pool.spawn(async move {
        let response = reqwest::get("https://localhost:8000/get_world")
            .await
            .unwrap()
            .text()
            .await
            .unwrap();
        response
    });

    // Spawn new entity and add our new task as a component
    commands.entity(entity).insert(WorldGen(task));
}

fn handle_tasks(mut commands: Commands, mut transform_tasks: Query<&mut WorldGen>) {
    for mut task in &mut transform_tasks {
        if let Some(mut commands_queue) = block_on(future::poll_fn(&mut task.0)) {
  println!(commands_queue);
        }
    }
}

fn draw_map(mut commands: Commands, world: Res<Map>) {
    print!("world: {:?}", world)
}

Error:

expected a `FnMut(&mut Context<'_>)` closure, found `Task<std::string::String>`
the trait `for<'a, 'b> FnMut<(&'a mut Context<'b>,)>` is not implemented for `Task<std::string::String>`
required for `&mut Task<std::string::String>` to implement `for<'a, 'b> FnOnce<(&'a mut Context<'b>,)>`
required for `std::future::PollFn<&mut Task<std::string::String>>` to implement `Future`rustcClick for full compiler diagnostic
view_world_plugin.rs(63, 43): required by a bound introduced by this call
future.rs(56, 33): required by a bound in `futures_lite::future::block_on`
carmine pilot
#

what version of bevy and rust and futures_lite?

undone valve
#

12.1
Rust fully updated
Futureslite I tried at latest and also 1.3 which was what the example used I believe

#

I tried many different ways to do this.

carmine pilot
undone valve
#
use bevy::{
    prelude::*,
    tasks::{block_on, prelude::*, Task},
};
use serde::{Deserialize, Serialize};


#[derive(Component)]
pub struct WorldGen(Task<String>);

fn handle_tasks(
    mut commands: Commands,
    mut transform_tasks: Query<&mut WorldGen>,
    mut map: ResMut<Map>,
    asset_server: Res<AssetServer>,
) {
    for mut task in &mut transform_tasks {
        if let Some(body) = block_on(futures_lite::future::poll_once(&mut task.0)) {
            let tiles = serde_json::from_str::<Vec<Tile>>(&body).unwrap();
            for tile in tiles.iter() {
                let t = tile.clone();
                let size = 16f32;
                let x: f32 =
                    size * (f32::sqrt(3.0) * t.q as f32 + f32::sqrt(3.0) / 2.0 * t.r as f32);
                let y: f32 = size * (3.0 / 2.0 * t.r as f32);

                commands.spawn((
                    t,
                    SpriteBundle {
                        transform: Transform::from_xyz(x, y, 0.),
                        texture: asset_server.load("tile.png").into(),
                        sprite: Sprite {
                            custom_size: Some(Vec2::new(size * 2., f32::sqrt(3.) * size)),
                            ..Default::default()
                        },
                        ..Default::default()
                    },
                ));
            }
            map.tiles = tiles;
        }
    }
}

fn spawn_tasks(mut commands: Commands) {
    commands.spawn(Camera2dBundle::default());
    let thread_pool = AsyncComputeTaskPool::get();

    let entity = commands.spawn_empty().id();

    let task = thread_pool.spawn(async move {
        let body: String = reqwest::blocking::get("http://localhost:8000/get_world")
            .unwrap()
            .text()
            .unwrap();
        body
    });
    commands.entity(entity).insert(WorldGen(task));
}

fn draw_map(mut commands: Commands, world: Res<Map>) {
    print!("world: {:?}", world.tiles.len())
}
#

I've tried a lot of variations keep getting the same error

#
[package]
name = "TwilightSurvivalClient"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bevy = { version = "0.12.1", features = ["async-io"] }
futures-lite = "1.13.0"
rand = "0.8.5"
reqwest = { version = "0.11.23", features = ["blocking"] }
tokio = { version = "1.35.1", features = ["full", "rt-multi-thread"] }
serde = { version = "1.0.130", features = ["derive"] }
serde_json = "1.0.111"
#

Only way I could get it to work was using reqwest::blocking::get('url');

#
mod view_world_plugin;

use bevy::prelude::*;
use view_world_plugin::ViewWorldPlugin;

 fn main() {
    App::new()
        .add_plugins((DefaultPlugins, ViewWorldPlugin))
        .run();
}

main file if Im missing a plugin or something?

#

Mac M1

undone valve
#

It was because I'm stupid and didnt init_resource Map