From 98dad6afa316b9a44ff76b305520339ddc44c789 Mon Sep 17 00:00:00 2001 From: "1992414357@qq.com" <1992414357@qq.com> Date: Fri, 13 Jun 2025 16:25:22 +0800 Subject: . --- client/src/bevy_plugins/mod.rs | 1 + client/src/bevy_plugins/plugin_client_app.rs | 80 ++++++++++++++++++++ client/src/bin/pad.rs | 23 ++++++ client/src/data/layout_data.rs | 106 +++++++++++++++++++++++++++ client/src/data/mod.rs | 1 + client/src/lib.rs | 2 + client/src/main.rs | 23 ------ client/src/plugin_client.rs | 69 ----------------- 8 files changed, 213 insertions(+), 92 deletions(-) create mode 100644 client/src/bevy_plugins/mod.rs create mode 100644 client/src/bevy_plugins/plugin_client_app.rs create mode 100644 client/src/bin/pad.rs create mode 100644 client/src/data/layout_data.rs create mode 100644 client/src/data/mod.rs create mode 100644 client/src/lib.rs delete mode 100644 client/src/main.rs delete mode 100644 client/src/plugin_client.rs (limited to 'client/src') diff --git a/client/src/bevy_plugins/mod.rs b/client/src/bevy_plugins/mod.rs new file mode 100644 index 0000000..0f0aa3e --- /dev/null +++ b/client/src/bevy_plugins/mod.rs @@ -0,0 +1 @@ +pub mod plugin_client_app; \ No newline at end of file diff --git a/client/src/bevy_plugins/plugin_client_app.rs b/client/src/bevy_plugins/plugin_client_app.rs new file mode 100644 index 0000000..e7d60d2 --- /dev/null +++ b/client/src/bevy_plugins/plugin_client_app.rs @@ -0,0 +1,80 @@ +use std::sync::{Arc, Mutex}; +use bevy::app::FixedLast; +use bevy::input::common_conditions::input_just_pressed; +use bevy::log::info; +use bevy::log::tracing::Instrument; +use bevy::prelude::{App, AppExit, Commands, Component, EventReader, IntoScheduleConfigs, KeyCode, NextState, OnEnter, OnExit, Plugin, PreStartup, Query, ResMut, Startup, State, States, Update}; +use bevy_tokio_tasks::TokioTasksRuntime; +use nogamepads::entry_mutex; +use nogamepads_core::data::controller::controller_data::ControllerData; +use nogamepads_core::data::controller::controller_runtime::ControllerRuntime; +use nogamepads_core::data::player::player_data::Player; +use nogamepads_core::service::tcp_network::pad_client::pad_client_service::PadClientNetwork; +use crate::bevy_plugins::plugin_client_app::GameState::Exiting; + +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States)] +enum GameState { + #[default] + Waiting, + Playing, + Exiting +} + +#[derive(Component)] +struct ClientComponent { + pad_client: Arc>, +} + +pub struct ClientAppPlugins; +impl Plugin for ClientAppPlugins { + fn build(&self, app: &mut App) { + app.add_systems(PreStartup, client_init); + app.add_systems(Startup, client_start); + app.add_systems(OnEnter(Exiting), client_exit); + } +} + +fn client_init( + mut commands: Commands +) { + let mut controller_data = ControllerData::default(); + controller_data.bind_player( + Player::register( + env!("TEST_PLAYER_ACCOUNT").to_string(), + env!("TEST_PLAYER_PASSWORD").to_string()) + ); + + let runtime = controller_data.runtime(); + + commands.spawn( + ClientComponent { + pad_client: Arc::clone(&runtime), + } + ); +} + +fn client_start( + client_components: Query<&mut ClientComponent>, + runtime: ResMut +) { + for client_component in client_components.iter() { + let client_runtime = Arc::clone(&client_component.pad_client); + let network = PadClientNetwork::build(client_runtime); + let entry = network.build_entry(); + + runtime.spawn_background_task(|_ctx| async move { + entry.await; + info!("Client finished.") + }); + } +} + +fn client_exit( + client_components: Query<&mut ClientComponent> +) { + for client_component in client_components.iter() { + entry_mutex!(client_component.pad_client, |guard| { + guard.close(); + }) + }; +} diff --git a/client/src/bin/pad.rs b/client/src/bin/pad.rs new file mode 100644 index 0000000..796dea3 --- /dev/null +++ b/client/src/bin/pad.rs @@ -0,0 +1,23 @@ +use bevy::prelude::{App}; +use bevy::DefaultPlugins; +use bevy_tokio_tasks::TokioTasksPlugin; +use tokio::runtime::Builder; +use nogamepads_client::bevy_plugins::plugin_client_app::ClientAppPlugins; + +fn main() { + let mut app = App::new(); + + // Default + app.add_plugins(DefaultPlugins); + + // Bevy Tokio Tasks + app.add_plugins(TokioTasksPlugin { + make_runtime: Box::new(|| Builder::new_multi_thread().enable_all().build().unwrap()), + ..TokioTasksPlugin::default() + }); + + // Client App Plugins + app.add_plugins(ClientAppPlugins); + + app.run(); +} diff --git a/client/src/data/layout_data.rs b/client/src/data/layout_data.rs new file mode 100644 index 0000000..f960b41 --- /dev/null +++ b/client/src/data/layout_data.rs @@ -0,0 +1,106 @@ +use quick_xml::de::from_str; +use serde::Deserialize; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct LayoutXml { + + pub preload: Preload, + + pub events: Events, + + pub layout: Layout, +} + +#[derive(Debug, Deserialize)] +struct Preload { + + #[serde(rename = "sound", default)] + pub sounds: Vec, + + #[serde(rename = "image", default)] + pub images: Vec, + + #[serde(rename = "text", default)] + pub texts: Vec, +} + +#[derive(Debug, Deserialize)] +pub struct Asset { + + #[serde(rename = "@src")] + pub src: String, + + #[serde(rename = "$text")] + pub name: String, +} + +#[derive(Debug, Deserialize)] +pub struct Events { + + #[serde(rename = "lua_setup", default)] + pub lua_setup: Option, + + #[serde(rename = "lua_exit", default)] + pub lua_exit: Option, + + #[serde(rename = "lua", default)] + pub lua_scripts: Vec, +} + +#[derive(Debug, Deserialize)] +pub struct Lua { + + #[serde(rename = "@id")] + pub id: String, + + #[serde(rename = "@src", default)] + pub src: Option, + + #[serde(rename = "$text", default)] + pub content: Option, +} + +#[derive(Debug, Deserialize)] +pub struct Layout { + + #[serde(rename = "box_layout")] + pub boxes: Vec, +} + +#[derive(Debug, Deserialize)] +pub struct BoxLayout { + + pub button_bind: ButtonBind, + + pub position: String, + + pub pivot: String, + + pub size: String, + + pub name: String, +} + +#[derive(Debug, Deserialize)] +pub struct ButtonBind { + + #[serde(rename = "on_click")] + pub on_click: OnClick, +} + +#[derive(Debug, Deserialize)] +pub struct OnClick { + + #[serde(rename = "@event")] + pub event: String, +} + +impl LayoutXml { + pub fn parse_xml(xml: String) -> Result { + let wrapped = format!("{}", xml); + + let layout_xml: LayoutXml = from_str(&wrapped)?; + Ok(layout_xml) + } +} \ No newline at end of file diff --git a/client/src/data/mod.rs b/client/src/data/mod.rs new file mode 100644 index 0000000..0e0a42e --- /dev/null +++ b/client/src/data/mod.rs @@ -0,0 +1 @@ +pub mod layout_data; \ No newline at end of file diff --git a/client/src/lib.rs b/client/src/lib.rs new file mode 100644 index 0000000..bcfa9d8 --- /dev/null +++ b/client/src/lib.rs @@ -0,0 +1,2 @@ +pub mod bevy_plugins; +pub mod data; \ No newline at end of file diff --git a/client/src/main.rs b/client/src/main.rs deleted file mode 100644 index 31fb406..0000000 --- a/client/src/main.rs +++ /dev/null @@ -1,23 +0,0 @@ -mod plugin_client; - -use crate::plugin_client::PadClientPlugin; -use bevy::prelude::{App}; -use bevy::DefaultPlugins; -use bevy_tokio_tasks::TokioTasksPlugin; -use tokio::runtime::Builder; - -fn main() { - let mut app = App::new(); - - app.add_plugins(DefaultPlugins); - app.add_plugins(TokioTasksPlugin { - make_runtime: Box::new(|| { - Builder::new_multi_thread().enable_all().build().unwrap() - }), - ..TokioTasksPlugin::default() - }); - - app.add_plugins(PadClientPlugin); - - app.run(); -} diff --git a/client/src/plugin_client.rs b/client/src/plugin_client.rs deleted file mode 100644 index d998f75..0000000 --- a/client/src/plugin_client.rs +++ /dev/null @@ -1,69 +0,0 @@ -use std::sync::{Arc, Mutex}; -use bevy::input::common_conditions::input_just_pressed; -use bevy::log::info; -use bevy::prelude::{App, Commands, Component, IntoScheduleConfigs, KeyCode, Plugin, PreStartup, Query, ResMut, Startup, Update}; -use bevy_tokio_tasks::TokioTasksRuntime; -use nogamepads::entry_mutex; -use nogamepads_core::data::controller::controller_data::ControllerData; -use nogamepads_core::data::controller::controller_runtime::ControllerRuntime; -use nogamepads_core::data::player::player_data::Player; -use nogamepads_core::service::tcp_network::pad_client::pad_client_service::PadClientNetwork; - -#[derive(Component)] -struct ClientComponent { - pad_client: Arc>, -} - -pub struct PadClientPlugin; -impl Plugin for PadClientPlugin { - fn build(&self, app: &mut App) { - app.add_systems(PreStartup, client_init); - app.add_systems(Startup, client_start); - app.add_systems(Update, client_exit.run_if(input_just_pressed(KeyCode::Escape))); - } -} - -fn client_init( - mut commands: Commands -) { - let mut controller_data = ControllerData::default(); - controller_data.bind_player( - Player::register( - env!("TEST_PLAYER_ACCOUNT").to_string(), - env!("TEST_PLAYER_PASSWORD").to_string()) - ); - - let runtime = controller_data.runtime(); - - commands.spawn( - ClientComponent { - pad_client: Arc::clone(&runtime), - } - ); -} - -fn client_start( - client_components: Query<&mut ClientComponent>, - runtime: ResMut -) { - for client_component in client_components.iter() { - let client_runtime = Arc::clone(&client_component.pad_client); - let network = PadClientNetwork::build(client_runtime); - let entry = network.build_entry(); - - runtime.spawn_background_task(|_ctx| async move { - entry.await; - info!("Client finished.") - }); - } -} - -fn client_exit( - client_components: Query<&mut ClientComponent> -){ - for client_component in client_components.iter() { - entry_mutex!(client_component.pad_client, |guard| { - guard.close(); - }) - } -} \ No newline at end of file -- cgit