extract GameState

This commit is contained in:
Tao Tien 2026-02-08 18:15:09 -08:00
parent 78c199b61e
commit 6cd10329df
14 changed files with 118 additions and 28 deletions

16
Cargo.lock generated
View file

@ -2531,6 +2531,21 @@ dependencies = [
"serde_core", "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]] [[package]]
name = "derive_more" name = "derive_more"
version = "0.99.20" version = "0.99.20"
@ -3752,6 +3767,7 @@ name = "jong-types"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bevy", "bevy",
"derive_aliases",
"spacetimedb", "spacetimedb",
"strum 0.27.2", "strum 0.27.2",
] ]

View file

@ -7,5 +7,7 @@ edition = "2024"
[dependencies] [dependencies]
bevy.workspace = true bevy.workspace = true
bevy.features = ["bevy_state"]
derive_aliases = "0.4.7"
spacetimedb.workspace = true spacetimedb.workspace = true
strum.workspace = true strum.workspace = true

2
jong-types/rustfmt.toml Normal file
View file

@ -0,0 +1,2 @@
unstable_features = true
merge_derives = false

View file

@ -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 bevy::prelude::*;
use spacetimedb::SpacetimeType; use spacetimedb::SpacetimeType;
use strum::FromRepr; 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 struct Tile {
pub suit: Suit, pub suit: Suit,
} }
#[derive(/* MapEntities, */ Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] #[derive(..Base)]
#[derive(SpacetimeType)]
pub enum Suit { pub enum Suit {
Man(Rank), Man(Rank),
Pin(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 struct Rank {
pub number: u8, pub number: u8,
} }
#[derive(FromRepr, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] #[derive(
..Base,
FromRepr,
)]
#[derive(SpacetimeType)]
pub enum Wind { pub enum Wind {
Ton, Ton,
Nan, Nan,
@ -41,7 +74,11 @@ pub enum Wind {
Pei, Pei,
} }
#[derive(Debug, FromRepr, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] #[derive(
..Base,
FromRepr,
)]
#[derive(SpacetimeType)]
pub enum Dragon { pub enum Dragon {
Haku, Haku,
Hatsu, Hatsu,

View file

@ -24,22 +24,13 @@ use crate::{
}, },
tile::{self}, tile::{self},
}; };
use jong_types::GameState;
pub mod hand; pub mod hand;
pub mod player; pub mod player;
pub mod round; pub mod round;
pub mod wall; pub mod wall;
#[derive(States, Default, Hash, Clone, Eq, Debug, PartialEq, Copy)]
pub enum GameState {
#[default]
None,
Setup,
Deal,
Play,
Exit,
}
#[derive(Message)] #[derive(Message)]
pub enum GameMessage { pub enum GameMessage {
Discarded(Entity), Discarded(Entity),
@ -85,6 +76,7 @@ impl Plugin for Riichi {
.add_systems(Update, on_connect) .add_systems(Update, on_connect)
.add_systems(Update, on_disconnect) .add_systems(Update, on_disconnect)
.add_systems(Update, on_player_insert_update) .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::Setup), join_or_create_lobby)
.add_systems(OnEnter(GameState::Deal), ||todo!()) .add_systems(OnEnter(GameState::Deal), ||todo!())
// semicolon stopper // semicolon stopper
@ -148,14 +140,18 @@ fn join_or_create_lobby(
) { ) {
if player.lobby_id == 0 { if player.lobby_id == 0 {
stdb.reducers().join_or_create_lobby(None).unwrap(); stdb.reducers().join_or_create_lobby(None).unwrap();
stdb.subscription_builder() let sub = stdb
.on_applied(|_| trace!("subbed to lobby table")) .subscription_builder()
.on_applied(|ctx| trace!("subbed to lobby table"))
.on_error(|_, err| error!("sub to lobby table failed: {}", err)) .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 { } else {
debug!("already in lobby") debug!("already in lobby")
} }
// TODO how can this trigger with a reducer or automatically after all players join/ready
next_gamestate.set(GameState::Deal);
} }

View file

@ -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;
}

View file

@ -2,6 +2,7 @@
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)] #![allow(unused, clippy::all)]
use super::game_state_type::GameState;
use super::lobby_type::Lobby; use super::lobby_type::Lobby;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};

View file

@ -4,11 +4,14 @@
#![allow(unused, clippy::all)] #![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; 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)] #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)] #[sats(crate = __lib)]
pub struct Lobby { pub struct Lobby {
pub id: u32, pub id: u32,
pub host_id: u32, pub host_id: u32,
pub game_state: GameState,
} }
impl __sdk::InModule for Lobby { impl __sdk::InModule for Lobby {

View file

@ -11,6 +11,7 @@ pub mod bot_table;
pub mod bot_type; pub mod bot_type;
pub mod deal_hands_reducer; pub mod deal_hands_reducer;
pub mod dragon_type; pub mod dragon_type;
pub mod game_state_type;
pub mod hand_table; pub mod hand_table;
pub mod hand_type; pub mod hand_type;
pub mod join_or_create_lobby_reducer; pub mod join_or_create_lobby_reducer;
@ -35,6 +36,7 @@ pub use bot_table::*;
pub use bot_type::Bot; pub use bot_type::Bot;
pub use deal_hands_reducer::{deal_hands, set_flags_for_deal_hands, DealHandsCallbackId}; pub use deal_hands_reducer::{deal_hands, set_flags_for_deal_hands, DealHandsCallbackId};
pub use dragon_type::Dragon; pub use dragon_type::Dragon;
pub use game_state_type::GameState;
pub use hand_table::*; pub use hand_table::*;
pub use hand_type::Hand; pub use hand_type::Hand;
pub use join_or_create_lobby_reducer::{ pub use join_or_create_lobby_reducer::{

View file

@ -2,14 +2,15 @@ use std::time::Duration;
use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin}; use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin};
use bevy_ratatui::RatatuiPlugins; use bevy_ratatui::RatatuiPlugins;
use jong::game::{
GameMessage, GameState,
hand::{Drawn, Hand},
player::{CurrentPlayer, Player},
};
use tui_logger::TuiWidgetState; use tui_logger::TuiWidgetState;
use crate::tui::{input::ConfirmSelect, states::ConsoleWidget}; use crate::tui::{input::ConfirmSelect, states::ConsoleWidget};
use jong::game::{
GameMessage,
hand::{Drawn, Hand},
player::{CurrentPlayer, Player},
};
use jong_types::GameState;
mod input; mod input;
mod layout; mod layout;

View file

@ -4,11 +4,10 @@ use bevy_ratatui::event::KeyMessage;
// use ratatui::crossterm::event::KeyCode; // use ratatui::crossterm::event::KeyCode;
use tui_logger::TuiWidgetEvent; use tui_logger::TuiWidgetEvent;
use jong::game::GameState;
use crate::tui::layout::Overlays; use crate::tui::layout::Overlays;
use crate::tui::states::ConsoleWidget; use crate::tui::states::ConsoleWidget;
use crate::tui::states::TuiState; use crate::tui::states::TuiState;
use jong_types::GameState;
pub(crate) fn keyboard( pub(crate) fn keyboard(
mut messages: MessageReader<KeyMessage>, mut messages: MessageReader<KeyMessage>,

View file

@ -15,3 +15,6 @@ update:
spacetime: spacetime:
devenv up devenv up
generate-bindings:
spacetime generate --lang rust --out-dir jong/src/stdb --project-path spacetimedb

1
rustfmt.toml Normal file
View file

@ -0,0 +1 @@
unstable_features = true

View file

@ -40,6 +40,8 @@ pub struct Lobby {
#[index(direct)] #[index(direct)]
#[unique] #[unique]
host_id: u32, host_id: u32,
game_state: GameState,
} }
#[table(name = wall)] #[table(name = wall)]
@ -99,6 +101,7 @@ pub fn join_or_create_lobby(ctx: &ReducerContext, lobby: Option<u32>) -> Result<
let lobby = ctx.db.lobby().insert(Lobby { let lobby = ctx.db.lobby().insert(Lobby {
id: 0, id: 0,
host_id: player.id, host_id: player.id,
game_state: GameState::None,
}); });
info!("created lobby: {:?}", lobby); info!("created lobby: {:?}", lobby);