From 6cd10329df2aa3630f0f20042a282828052d8fa0 Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Sun, 8 Feb 2026 18:15:09 -0800 Subject: [PATCH] extract GameState --- Cargo.lock | 16 +++++++++++ jong-types/Cargo.toml | 2 ++ jong-types/rustfmt.toml | 2 ++ jong-types/src/lib.rs | 47 ++++++++++++++++++++++++++++---- jong/src/game.rs | 28 ++++++++----------- jong/src/stdb/game_state_type.rs | 24 ++++++++++++++++ jong/src/stdb/lobby_table.rs | 1 + jong/src/stdb/lobby_type.rs | 3 ++ jong/src/stdb/mod.rs | 2 ++ jong/src/tui.rs | 11 ++++---- jong/src/tui/input/keyboard.rs | 3 +- justfile | 3 ++ rustfmt.toml | 1 + spacetimedb/src/lib.rs | 3 ++ 14 files changed, 118 insertions(+), 28 deletions(-) create mode 100644 jong-types/rustfmt.toml create mode 100644 jong/src/stdb/game_state_type.rs create mode 100644 rustfmt.toml diff --git a/Cargo.lock b/Cargo.lock index fef7adf..fa24bf0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2531,6 +2531,21 @@ dependencies = [ "serde_core", ] +[[package]] +name = "derive_aliases" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a42564b20fdeb062b38ad78d567d0479b2b318ff679b20895d9a1de3b6896002" +dependencies = [ + "derive_aliases_proc_macro", +] + +[[package]] +name = "derive_aliases_proc_macro" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e81edf3b0f0a7d68f2113aee7cedffa73d1fadea46fc85e468786a7f7aac998c" + [[package]] name = "derive_more" version = "0.99.20" @@ -3752,6 +3767,7 @@ name = "jong-types" version = "0.1.0" dependencies = [ "bevy", + "derive_aliases", "spacetimedb", "strum 0.27.2", ] diff --git a/jong-types/Cargo.toml b/jong-types/Cargo.toml index a32f1b8..e4d5d42 100644 --- a/jong-types/Cargo.toml +++ b/jong-types/Cargo.toml @@ -7,5 +7,7 @@ edition = "2024" [dependencies] bevy.workspace = true +bevy.features = ["bevy_state"] +derive_aliases = "0.4.7" spacetimedb.workspace = true strum.workspace = true diff --git a/jong-types/rustfmt.toml b/jong-types/rustfmt.toml new file mode 100644 index 0000000..0973eba --- /dev/null +++ b/jong-types/rustfmt.toml @@ -0,0 +1,2 @@ +unstable_features = true +merge_derives = false diff --git a/jong-types/src/lib.rs b/jong-types/src/lib.rs index 91d3444..bc2c1b4 100644 --- a/jong-types/src/lib.rs +++ b/jong-types/src/lib.rs @@ -1,13 +1,37 @@ +mod derive_alias { + derive_aliases::define! { + Copy = ::core::clone::Clone, ::core::marker::Copy; + Eq = ::core::cmp::PartialEq, ::core::cmp::Eq; + Ord = ..Eq, ::core::cmp::PartialOrd, ::core::cmp::PartialEq, ::core::cmp::Ord; + + Base = ::core::fmt::Debug, ..Copy, ..Ord; + } +} +use derive_aliases::derive; + use bevy::prelude::*; use spacetimedb::SpacetimeType; use strum::FromRepr; -#[derive(Component, Debug, Clone, Copy, SpacetimeType)] +#[derive(..Base, Hash, Default)] +#[derive(States, SpacetimeType)] +pub enum GameState { + #[default] + None, + Setup, + Deal, + Play, + Exit, +} + +#[derive(..Base)] +#[derive(Component, SpacetimeType)] pub struct Tile { pub suit: Suit, } -#[derive(/* MapEntities, */ Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +#[derive(..Base)] +#[derive(SpacetimeType)] pub enum Suit { Man(Rank), Pin(Rank), @@ -28,12 +52,21 @@ impl Suit { } } -#[derive(Deref, DerefMut, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +#[derive( + ..Base, + Deref, + DerefMut, +)] +#[derive(SpacetimeType)] pub struct Rank { pub number: u8, } -#[derive(FromRepr, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +#[derive( + ..Base, + FromRepr, +)] +#[derive(SpacetimeType)] pub enum Wind { Ton, Nan, @@ -41,7 +74,11 @@ pub enum Wind { Pei, } -#[derive(Debug, FromRepr, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +#[derive( + ..Base, + FromRepr, +)] +#[derive(SpacetimeType)] pub enum Dragon { Haku, Hatsu, diff --git a/jong/src/game.rs b/jong/src/game.rs index 02cbbef..05679a2 100644 --- a/jong/src/game.rs +++ b/jong/src/game.rs @@ -24,22 +24,13 @@ use crate::{ }, tile::{self}, }; +use jong_types::GameState; pub mod hand; pub mod player; pub mod round; pub mod wall; -#[derive(States, Default, Hash, Clone, Eq, Debug, PartialEq, Copy)] -pub enum GameState { - #[default] - None, - Setup, - Deal, - Play, - Exit, -} - #[derive(Message)] pub enum GameMessage { Discarded(Entity), @@ -85,6 +76,7 @@ impl Plugin for Riichi { .add_systems(Update, on_connect) .add_systems(Update, on_disconnect) .add_systems(Update, on_player_insert_update) + // .add_systems(Update, on_lobby_insert_update) .add_systems(OnEnter(GameState::Setup), join_or_create_lobby) .add_systems(OnEnter(GameState::Deal), ||todo!()) // semicolon stopper @@ -148,14 +140,18 @@ fn join_or_create_lobby( ) { if player.lobby_id == 0 { stdb.reducers().join_or_create_lobby(None).unwrap(); - stdb.subscription_builder() - .on_applied(|_| trace!("subbed to lobby table")) + let sub = stdb + .subscription_builder() + .on_applied(|ctx| trace!("subbed to lobby table")) .on_error(|_, err| error!("sub to lobby table failed: {}", err)) - .subscribe(["SELECT l.* FROM lobby l JOIN player p ON l.host_id = p.id"]); + // JOIN player p ON l.host_id = p.id + .subscribe([format!( + "SELECT l.* + FROM lobby l + WHERE l.host_id = {}", + player.id + )]); } else { debug!("already in lobby") } - - // TODO how can this trigger with a reducer or automatically after all players join/ready - next_gamestate.set(GameState::Deal); } diff --git a/jong/src/stdb/game_state_type.rs b/jong/src/stdb/game_state_type.rs new file mode 100644 index 0000000..2e26076 --- /dev/null +++ b/jong/src/stdb/game_state_type.rs @@ -0,0 +1,24 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +#[derive(Copy, Eq, Hash)] +pub enum GameState { + None, + + Setup, + + Deal, + + Play, + + Exit, +} + +impl __sdk::InModule for GameState { + type Module = super::RemoteModule; +} diff --git a/jong/src/stdb/lobby_table.rs b/jong/src/stdb/lobby_table.rs index 62a0aeb..45ee487 100644 --- a/jong/src/stdb/lobby_table.rs +++ b/jong/src/stdb/lobby_table.rs @@ -2,6 +2,7 @@ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. #![allow(unused, clippy::all)] +use super::game_state_type::GameState; use super::lobby_type::Lobby; use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; diff --git a/jong/src/stdb/lobby_type.rs b/jong/src/stdb/lobby_type.rs index 6117233..3b32b90 100644 --- a/jong/src/stdb/lobby_type.rs +++ b/jong/src/stdb/lobby_type.rs @@ -4,11 +4,14 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::game_state_type::GameState; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct Lobby { pub id: u32, pub host_id: u32, + pub game_state: GameState, } impl __sdk::InModule for Lobby { diff --git a/jong/src/stdb/mod.rs b/jong/src/stdb/mod.rs index 3061c2c..68ddd4a 100644 --- a/jong/src/stdb/mod.rs +++ b/jong/src/stdb/mod.rs @@ -11,6 +11,7 @@ pub mod bot_table; pub mod bot_type; pub mod deal_hands_reducer; pub mod dragon_type; +pub mod game_state_type; pub mod hand_table; pub mod hand_type; pub mod join_or_create_lobby_reducer; @@ -35,6 +36,7 @@ pub use bot_table::*; pub use bot_type::Bot; pub use deal_hands_reducer::{deal_hands, set_flags_for_deal_hands, DealHandsCallbackId}; pub use dragon_type::Dragon; +pub use game_state_type::GameState; pub use hand_table::*; pub use hand_type::Hand; pub use join_or_create_lobby_reducer::{ diff --git a/jong/src/tui.rs b/jong/src/tui.rs index f166fb2..b0d60d4 100644 --- a/jong/src/tui.rs +++ b/jong/src/tui.rs @@ -2,14 +2,15 @@ use std::time::Duration; use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin}; use bevy_ratatui::RatatuiPlugins; -use jong::game::{ - GameMessage, GameState, - hand::{Drawn, Hand}, - player::{CurrentPlayer, Player}, -}; use tui_logger::TuiWidgetState; use crate::tui::{input::ConfirmSelect, states::ConsoleWidget}; +use jong::game::{ + GameMessage, + hand::{Drawn, Hand}, + player::{CurrentPlayer, Player}, +}; +use jong_types::GameState; mod input; mod layout; diff --git a/jong/src/tui/input/keyboard.rs b/jong/src/tui/input/keyboard.rs index b879f77..d2415bc 100644 --- a/jong/src/tui/input/keyboard.rs +++ b/jong/src/tui/input/keyboard.rs @@ -4,11 +4,10 @@ use bevy_ratatui::event::KeyMessage; // use ratatui::crossterm::event::KeyCode; use tui_logger::TuiWidgetEvent; -use jong::game::GameState; - use crate::tui::layout::Overlays; use crate::tui::states::ConsoleWidget; use crate::tui::states::TuiState; +use jong_types::GameState; pub(crate) fn keyboard( mut messages: MessageReader, diff --git a/justfile b/justfile index 3950586..c55cca1 100644 --- a/justfile +++ b/justfile @@ -15,3 +15,6 @@ update: spacetime: devenv up + +generate-bindings: + spacetime generate --lang rust --out-dir jong/src/stdb --project-path spacetimedb diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..e1f312a --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +unstable_features = true diff --git a/spacetimedb/src/lib.rs b/spacetimedb/src/lib.rs index f8c1f9b..4c96c59 100644 --- a/spacetimedb/src/lib.rs +++ b/spacetimedb/src/lib.rs @@ -40,6 +40,8 @@ pub struct Lobby { #[index(direct)] #[unique] host_id: u32, + + game_state: GameState, } #[table(name = wall)] @@ -99,6 +101,7 @@ pub fn join_or_create_lobby(ctx: &ReducerContext, lobby: Option) -> Result< let lobby = ctx.db.lobby().insert(Lobby { id: 0, host_id: player.id, + game_state: GameState::None, }); info!("created lobby: {:?}", lobby);