DEVELOPMENT ENVIRONMENT

~liljamo/deck-builder

f562571c0c947f21efdfad86f2ef39c3b569346d — Jonni Liljamo 1 year, 5 months ago 1809259
feat(client): parsing event
M client/src/plugins/async_tasks/mod.rs => client/src/plugins/async_tasks/mod.rs +12 -1
@@ 29,6 29,9 @@ pub use req_game_mygames::GameMyGamesCallEvent;
mod req_game_details;
pub use req_game_details::GameDetailsCallEvent;

mod parse_game_status;
pub use parse_game_status::ParseGameStatusEvent;

pub struct AsyncTasksPlugin;

impl Plugin for AsyncTasksPlugin {


@@ 41,6 44,7 @@ impl Plugin for AsyncTasksPlugin {
            .add_event::<GameFormingCallEvent>()
            .add_event::<GameMyGamesCallEvent>()
            .add_event::<GameDetailsCallEvent>()
            .add_event::<ParseGameStatusEvent>()
            .add_systems(
            (
                req_login::start_call,


@@ 57,7 61,14 @@ impl Plugin for AsyncTasksPlugin {
                req_game_mygames::handle_call,
                req_game_details::start_call,
                req_game_details::handle_call,
            )
            .chain()
            )
            .add_systems(
            (
                parse_game_status::start_call,
                parse_game_status::handle_call,
            ).chain()
        );
            );
    }
}

A client/src/plugins/async_tasks/parse_game_status.rs => client/src/plugins/async_tasks/parse_game_status.rs +59 -0
@@ 0,0 1,59 @@
/*
 * This file is part of laurelin_client
 * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
 *
 * Licensed under GPL-3.0-only.
 * See LICENSE for licensing information.
 */

use crate::{
    plugins::game::GameData, game_status::GameStatus, api::game::Game,
};

use bevy::{prelude::*, tasks::{Task, AsyncComputeTaskPool}};
use futures_lite::future;

#[derive(Component)]
pub struct ParseGameStatus(Task<GameStatus>);

#[derive(Clone)]
pub struct ParseGameStatusEvent {
    pub game: Game,
}

pub fn start_call(
    mut commands: Commands,
    mut start_ev_r: EventReader<ParseGameStatusEvent>,
    ) {
    for ev in start_ev_r.iter() {
        let thread_pool = AsyncComputeTaskPool::get();
        let ev = ev.clone();
        let task = thread_pool.spawn(async move {
            let res = GameStatus::new(&ev.game.actions.unwrap());

            res
        });
        commands.spawn(ParseGameStatus(task));
    }
}

pub fn handle_call(
    mut commands: Commands,
    mut tasks: Query<(Entity, &mut ParseGameStatus)>,
    mut game_data: ResMut<GameData>,
   ) {
    match tasks.get_single_mut() {
        Ok((entity, mut task)) => {
            if let Some(response) = future::block_on(future::poll_once(&mut task.0)) {
                game_data.game_status = Some(response);
                game_data.parsing_data = false;

                // remove the task
                commands.entity(entity).remove::<ParseGameStatus>();
                commands.entity(entity).despawn_recursive();
            }
        }
        // NOTE: don't do anything if the wanted thingy doesn't exist
        _ => {}
    }
}

M client/src/plugins/game/mod.rs => client/src/plugins/game/mod.rs +4 -0
@@ 28,6 28,8 @@ impl Plugin for GamePlugin {
pub struct GameData {
    pub game: Option<Game>,
    pub game_status: Option<GameStatus>,

    pub parsing_data: bool,
}

impl Default for GameData {


@@ 35,6 37,8 @@ impl Default for GameData {
        Self {
            game: None,
            game_status: None,

            parsing_data: false,
        }
    }
}

M client/src/plugins/game/ui/mod.rs => client/src/plugins/game/ui/mod.rs +12 -2
@@ 9,7 9,7 @@
use bevy::prelude::*;
use bevy_egui::{egui, EguiContexts};

use crate::{plugins::GameDetailsCallEvent, Global};
use crate::{plugins::{GameDetailsCallEvent, ParseGameStatusEvent}, Global};

use super::GameData;



@@ 19,6 19,7 @@ pub fn ui(
    global: Res<Global>,
    mut game_data: ResMut<GameData>,
    mut details_ev_w: EventWriter<GameDetailsCallEvent>,
    mut parse_ev_w: EventWriter<ParseGameStatusEvent>,
) {
    egui::Window::new("Game Details")
        .show(contexts.ctx_mut(), |ui| {


@@ 27,7 28,16 @@ pub fn ui(
                return;
            };
            let Some(status) = &game_data.game_status else {
                // early return if game_status is None
                if game_data.parsing_data {
                    // early return if game_status is None, and we're parsing it
                    return;
                }

                // since we're not already parsing the data, we start it
                game_data.parsing_data = true;
                parse_ev_w.send(ParseGameStatusEvent {
                    game: game_data.game.as_ref().unwrap().clone(),
                });
                return;
            };