From c12667938e350a7a719a6f34469e1022aaed1e4f Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Fri, 20 Feb 2026 03:20:29 -0800 Subject: [PATCH] (stash) state advancer reducer --- docs/states | 18 --- jong-db/src/db/advance_state_timer_table.rs | 144 ++++++++++++++++++++ jong-db/src/db/advance_state_timer_type.rs | 17 +++ jong-db/src/db/mod.rs | 21 +++ jong-line/src/lib.rs | 5 +- jong-line/src/reducers/lobby.rs | 3 +- jong-line/src/tables.rs | 58 +++++++- jong-line/src/tables/player.rs | 44 ------ jong/src/riichi.rs | 25 ++-- 9 files changed, 252 insertions(+), 83 deletions(-) delete mode 100644 docs/states create mode 100644 jong-db/src/db/advance_state_timer_table.rs create mode 100644 jong-db/src/db/advance_state_timer_type.rs delete mode 100644 jong-line/src/tables/player.rs diff --git a/docs/states b/docs/states deleted file mode 100644 index 13e0595..0000000 --- a/docs/states +++ /dev/null @@ -1,18 +0,0 @@ -gamestate - - none - join_or_create_lobby() - - lobby - set_ready() - add_bot() - start_game() - - setup - shuffle_deal() - - deal - animations?? - - play - discards?? diff --git a/jong-db/src/db/advance_state_timer_table.rs b/jong-db/src/db/advance_state_timer_table.rs new file mode 100644 index 0000000..a6096e0 --- /dev/null +++ b/jong-db/src/db/advance_state_timer_table.rs @@ -0,0 +1,144 @@ +// 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 super::advance_state_timer_type::AdvanceStateTimer; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `advance_state_timer`. +/// +/// Obtain a handle from the [`AdvanceStateTimerTableAccess::advance_state_timer`] method on [`super::RemoteTables`], +/// like `ctx.db.advance_state_timer()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.advance_state_timer().on_insert(...)`. +pub struct AdvanceStateTimerTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `advance_state_timer`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait AdvanceStateTimerTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`AdvanceStateTimerTableHandle`], which mediates access to the table `advance_state_timer`. + fn advance_state_timer(&self) -> AdvanceStateTimerTableHandle<'_>; +} + +impl AdvanceStateTimerTableAccess for super::RemoteTables { + fn advance_state_timer(&self) -> AdvanceStateTimerTableHandle<'_> { + AdvanceStateTimerTableHandle { + imp: self + .imp + .get_table::("advance_state_timer"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct AdvanceStateTimerInsertCallbackId(__sdk::CallbackId); +pub struct AdvanceStateTimerDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for AdvanceStateTimerTableHandle<'ctx> { + type Row = AdvanceStateTimer; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = AdvanceStateTimerInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> AdvanceStateTimerInsertCallbackId { + AdvanceStateTimerInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: AdvanceStateTimerInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = AdvanceStateTimerDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> AdvanceStateTimerDeleteCallbackId { + AdvanceStateTimerDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: AdvanceStateTimerDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("advance_state_timer"); + _table.add_unique_constraint::("scheduled_id", |row| &row.scheduled_id); +} +pub struct AdvanceStateTimerUpdateCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableWithPrimaryKey for AdvanceStateTimerTableHandle<'ctx> { + type UpdateCallbackId = AdvanceStateTimerUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> AdvanceStateTimerUpdateCallbackId { + AdvanceStateTimerUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: AdvanceStateTimerUpdateCallbackId) { + self.imp.remove_on_update(callback.0) + } +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} + +/// Access to the `scheduled_id` unique index on the table `advance_state_timer`, +/// which allows point queries on the field of the same name +/// via the [`AdvanceStateTimerScheduledIdUnique::find`] method. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.advance_state_timer().scheduled_id().find(...)`. +pub struct AdvanceStateTimerScheduledIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +impl<'ctx> AdvanceStateTimerTableHandle<'ctx> { + /// Get a handle on the `scheduled_id` unique index on the table `advance_state_timer`. + pub fn scheduled_id(&self) -> AdvanceStateTimerScheduledIdUnique<'ctx> { + AdvanceStateTimerScheduledIdUnique { + imp: self.imp.get_unique_constraint::("scheduled_id"), + phantom: std::marker::PhantomData, + } + } +} + +impl<'ctx> AdvanceStateTimerScheduledIdUnique<'ctx> { + /// Find the subscribed row whose `scheduled_id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u64) -> Option { + self.imp.find(col_val) + } +} diff --git a/jong-db/src/db/advance_state_timer_type.rs b/jong-db/src/db/advance_state_timer_type.rs new file mode 100644 index 0000000..8411902 --- /dev/null +++ b/jong-db/src/db/advance_state_timer_type.rs @@ -0,0 +1,17 @@ +// 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)] +pub struct AdvanceStateTimer { + pub scheduled_id: u64, + pub scheduled_at: __sdk::ScheduleAt, + pub lobby_id: u32, +} + +impl __sdk::InModule for AdvanceStateTimer { + type Module = super::RemoteModule; +} diff --git a/jong-db/src/db/mod.rs b/jong-db/src/db/mod.rs index fcf6370..3eb7040 100644 --- a/jong-db/src/db/mod.rs +++ b/jong-db/src/db/mod.rs @@ -7,6 +7,8 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; pub mod add_bot_reducer; +pub mod advance_state_timer_table; +pub mod advance_state_timer_type; pub mod bot_table; pub mod bot_type; pub mod clear_all_reducer; @@ -36,6 +38,8 @@ pub mod wall_table; pub mod wind_type; pub use add_bot_reducer::{add_bot, set_flags_for_add_bot, AddBotCallbackId}; +pub use advance_state_timer_table::*; +pub use advance_state_timer_type::AdvanceStateTimer; pub use bot_table::*; pub use bot_type::Bot; pub use clear_all_reducer::{clear_all, set_flags_for_clear_all, ClearAllCallbackId}; @@ -189,6 +193,7 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { #[allow(non_snake_case)] #[doc(hidden)] pub struct DbUpdate { + advance_state_timer: __sdk::TableUpdate, bot: __sdk::TableUpdate, lobby: __sdk::TableUpdate, player: __sdk::TableUpdate, @@ -202,6 +207,9 @@ impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { let mut db_update = DbUpdate::default(); for table_update in raw.tables { match &table_update.table_name[..] { + "advance_state_timer" => db_update + .advance_state_timer + .append(advance_state_timer_table::parse_table_update(table_update)?), "bot" => db_update .bot .append(bot_table::parse_table_update(table_update)?), @@ -243,6 +251,12 @@ impl __sdk::DbUpdate for DbUpdate { ) -> AppliedDiff<'_> { let mut diff = AppliedDiff::default(); + diff.advance_state_timer = cache + .apply_diff_to_table::( + "advance_state_timer", + &self.advance_state_timer, + ) + .with_updates_by_pk(|row| &row.scheduled_id); diff.bot = cache .apply_diff_to_table::("bot", &self.bot) .with_updates_by_pk(|row| &row.id); @@ -267,6 +281,7 @@ impl __sdk::DbUpdate for DbUpdate { #[allow(non_snake_case)] #[doc(hidden)] pub struct AppliedDiff<'r> { + advance_state_timer: __sdk::TableAppliedDiff<'r, AdvanceStateTimer>, bot: __sdk::TableAppliedDiff<'r, Bot>, lobby: __sdk::TableAppliedDiff<'r, Lobby>, player: __sdk::TableAppliedDiff<'r, Player>, @@ -285,6 +300,11 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { event: &EventContext, callbacks: &mut __sdk::DbCallbacks, ) { + callbacks.invoke_table_row_callbacks::( + "advance_state_timer", + &self.advance_state_timer, + event, + ); callbacks.invoke_table_row_callbacks::("bot", &self.bot, event); callbacks.invoke_table_row_callbacks::("lobby", &self.lobby, event); callbacks.invoke_table_row_callbacks::("player", &self.player, event); @@ -1009,6 +1029,7 @@ impl __sdk::SpacetimeModule for RemoteModule { type SubscriptionHandle = SubscriptionHandle; fn register_tables(client_cache: &mut __sdk::ClientCache) { + advance_state_timer_table::register_table(client_cache); bot_table::register_table(client_cache); lobby_table::register_table(client_cache); player_table::register_table(client_cache); diff --git a/jong-line/src/lib.rs b/jong-line/src/lib.rs index b626822..28bf92a 100644 --- a/jong-line/src/lib.rs +++ b/jong-line/src/lib.rs @@ -1,7 +1,9 @@ use log::debug; use spacetimedb::{ReducerContext, Table, reducer}; -use crate::tables::{player::player, *}; +use jong_types::TurnState; + +use crate::tables::*; mod reducers { mod deal; @@ -44,6 +46,7 @@ pub fn login_or_add_player(ctx: &ReducerContext) { hand: vec![], pond: vec![], drawn_tile: None, + turn_state: TurnState::None, }) { debug!("added player: {:?}", player); } else { diff --git a/jong-line/src/reducers/lobby.rs b/jong-line/src/reducers/lobby.rs index 1a4df28..f169dfc 100644 --- a/jong-line/src/reducers/lobby.rs +++ b/jong-line/src/reducers/lobby.rs @@ -1,7 +1,7 @@ use log::info; use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer}; -use crate::tables::{player::player, *}; +use crate::tables::*; #[reducer] pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<(), String> { @@ -19,7 +19,6 @@ pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<( host_player_id: player.id, players: vec![PlayerOrBot::Player { id: player.id }], game_state: jong_types::states::GameState::Lobby, - turn_state: jong_types::states::TurnState::None, dealer_idx: 0, current_idx: 0, }); diff --git a/jong-line/src/tables.rs b/jong-line/src/tables.rs index 17ec267..5939c67 100644 --- a/jong-line/src/tables.rs +++ b/jong-line/src/tables.rs @@ -1,13 +1,10 @@ use spacetimedb::{SpacetimeType, table}; use jong_types::{ - tiles::Tile, states::{GameState, TurnState}, + tiles::Tile, }; -pub mod player; -pub use player::*; - #[derive(Debug, Clone)] #[table(name = lobby, public)] pub struct Lobby { @@ -22,7 +19,6 @@ pub struct Lobby { pub current_idx: u8, pub game_state: GameState, - pub turn_state: TurnState, } #[table(name = wall)] @@ -48,3 +44,55 @@ pub enum PlayerOrBot { Player { id: u32 }, Bot { id: u32 }, } + +#[table(name = advance_state_timer)] +pub struct AdvanceStateTimer { + #[primary_key] + #[auto_inc] + scheduled_id: u64, + scheduled_at: spacetimedb::ScheduleAt, + + lobby_id: u32, +} + +// FIXME this shant be public, use views +#[table(name = player, public)] +#[derive(Debug)] +pub struct Player { + #[primary_key] + pub identity: spacetimedb::Identity, + + #[unique] + #[auto_inc] + pub id: u32, + + pub name: Option, + + #[index(btree)] + pub lobby_id: u32, + pub ready: bool, + + pub turn_state: TurnState, + + pub sort: bool, + + pub hand: Vec, + pub pond: Vec, + + pub drawn_tile: Option, +} + +#[table(name = bot)] +pub struct Bot { + #[primary_key] + #[auto_inc] + pub id: u32, + + #[index(btree)] + pub lobby_id: u32, + + pub hand: Vec, + pub pond: Vec, + + pub drawn_tile: Option, +} diff --git a/jong-line/src/tables/player.rs b/jong-line/src/tables/player.rs deleted file mode 100644 index c3bf342..0000000 --- a/jong-line/src/tables/player.rs +++ /dev/null @@ -1,44 +0,0 @@ -use spacetimedb::Identity; -use spacetimedb::{SpacetimeType, table}; - -use super::DbTile; - -// FIXME this shant be public, use views -#[table(name = player, public)] -#[derive(Debug)] -pub struct Player { - #[primary_key] - pub identity: Identity, - - #[unique] - #[auto_inc] - pub id: u32, - - pub name: Option, - - #[index(btree)] - pub lobby_id: u32, - pub ready: bool, - - pub sort: bool, - - pub hand: Vec, - pub pond: Vec, - - pub drawn_tile: Option, -} - -#[table(name = bot)] -pub struct Bot { - #[primary_key] - #[auto_inc] - pub id: u32, - - #[index(btree)] - pub lobby_id: u32, - - pub hand: Vec, - pub pond: Vec, - - pub drawn_tile: Option, -} diff --git a/jong/src/riichi.rs b/jong/src/riichi.rs index 61ad092..38afe95 100644 --- a/jong/src/riichi.rs +++ b/jong/src/riichi.rs @@ -121,6 +121,18 @@ fn on_player_insert_update( }; for msg in messages.read() { + match msg.new.turn_state { + jong_db::TurnState::None => {} + jong_db::TurnState::Tsumo => { + stdb.reducers().draw_tile().unwrap(); + } + jong_db::TurnState::Menzen => todo!(), + jong_db::TurnState::RiichiKan => todo!(), + jong_db::TurnState::RonChiiPonKan => { + stdb.reducers().skip_call().unwrap(); + } + jong_db::TurnState::End => todo!(), + } let hand_tiles: Vec<_> = msg .new .hand @@ -205,19 +217,6 @@ fn on_lobby_insert_update( } jong_db::GameState::Play => { trace!("game entered play"); - match msg.new.turn_state { - jong_db::TurnState::None => {} - jong_db::TurnState::Tsumo => { - stdb.reducers().draw_tile().unwrap(); - } - jong_db::TurnState::Menzen => todo!(), - jong_db::TurnState::RiichiKan => todo!(), - jong_db::TurnState::RonChiiPonKan => { - stdb.reducers().skip_call().unwrap(); - } - jong_db::TurnState::End => todo!(), - } - next_turnstate.set(msg.new.turn_state.into()); } jong_db::GameState::Exit => { trace!("game enetered exit");