diff --git a/Cargo.lock b/Cargo.lock index 08176cf..b30c07e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1229,6 +1229,7 @@ dependencies = [ "bitflags 2.11.0", "color-eyre", "ratatui", + "smol_str", "tracing", ] diff --git a/devenv.nix b/devenv.nix index af52a59..925cfa6 100644 --- a/devenv.nix +++ b/devenv.nix @@ -18,7 +18,7 @@ # https://devenv.sh/packages/ packages = with pkgs; [ - # lspmux + lspmux pkg-config # spacetimedb diff --git a/jong-db/src/db/add_bot_reducer.rs b/jong-db/src/db/add_bot_reducer.rs index eccf63a..36ed6db 100644 --- a/jong-db/src/db/add_bot_reducer.rs +++ b/jong-db/src/db/add_bot_reducer.rs @@ -2,7 +2,13 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] @@ -14,8 +20,8 @@ impl From for super::Reducer { fn from(args: AddBotArgs) -> Self { Self::AddBot { lobby_id: args.lobby_id, - } - } +} +} } impl __sdk::InModule for AddBotArgs { @@ -34,7 +40,8 @@ pub trait add_bot { /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and its status can be observed by listening for [`Self::on_add_bot`] callbacks. - fn add_bot(&self, lobby_id: u32) -> __sdk::Result<()>; + fn add_bot(&self, lobby_id: u32, +) -> __sdk::Result<()>; /// Register a callback to run whenever we are notified of an invocation of the reducer `add_bot`. /// /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] @@ -42,39 +49,35 @@ pub trait add_bot { /// /// The returned [`AddBotCallbackId`] can be passed to [`Self::remove_on_add_bot`] /// to cancel the callback. - fn on_add_bot( - &self, - callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static, - ) -> AddBotCallbackId; + fn on_add_bot(&self, callback: impl FnMut(&super::ReducerEventContext, &u32, ) + Send + 'static) -> AddBotCallbackId; /// Cancel a callback previously registered by [`Self::on_add_bot`], /// causing it not to run in the future. fn remove_on_add_bot(&self, callback: AddBotCallbackId); } impl add_bot for super::RemoteReducers { - fn add_bot(&self, lobby_id: u32) -> __sdk::Result<()> { - self.imp.call_reducer("add_bot", AddBotArgs { lobby_id }) + fn add_bot(&self, lobby_id: u32, +) -> __sdk::Result<()> { + self.imp.call_reducer("add_bot", AddBotArgs { lobby_id, }) } fn on_add_bot( &self, - mut callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static, + mut callback: impl FnMut(&super::ReducerEventContext, &u32, ) + Send + 'static, ) -> AddBotCallbackId { AddBotCallbackId(self.imp.on_reducer( "add_bot", Box::new(move |ctx: &super::ReducerEventContext| { #[allow(irrefutable_let_patterns)] let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::AddBot { lobby_id }, - .. + event: __sdk::ReducerEvent { + reducer: super::Reducer::AddBot { + lobby_id, }, + .. + }, .. - } = ctx - else { - unreachable!() - }; - callback(ctx, lobby_id) + } = ctx else { unreachable!() }; + callback(ctx, lobby_id, ) }), )) } @@ -102,3 +105,4 @@ impl set_flags_for_add_bot for super::SetReducerFlags { self.imp.set_call_reducer_flags("add_bot", flags); } } + diff --git a/jong-db/src/db/advance_game_reducer.rs b/jong-db/src/db/advance_game_reducer.rs new file mode 100644 index 0000000..fbd576f --- /dev/null +++ b/jong-db/src/db/advance_game_reducer.rs @@ -0,0 +1,109 @@ +// 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, +}; + +use super::game_timer_type::GameTimer; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct AdvanceGameArgs { + pub game_timer: GameTimer, +} + +impl From for super::Reducer { + fn from(args: AdvanceGameArgs) -> Self { + Self::AdvanceGame { + game_timer: args.game_timer, +} +} +} + +impl __sdk::InModule for AdvanceGameArgs { + type Module = super::RemoteModule; +} + +pub struct AdvanceGameCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `advance_game`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait advance_game { + /// Request that the remote module invoke the reducer `advance_game` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_advance_game`] callbacks. + fn advance_game(&self, game_timer: GameTimer, +) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `advance_game`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`AdvanceGameCallbackId`] can be passed to [`Self::remove_on_advance_game`] + /// to cancel the callback. + fn on_advance_game(&self, callback: impl FnMut(&super::ReducerEventContext, &GameTimer, ) + Send + 'static) -> AdvanceGameCallbackId; + /// Cancel a callback previously registered by [`Self::on_advance_game`], + /// causing it not to run in the future. + fn remove_on_advance_game(&self, callback: AdvanceGameCallbackId); +} + +impl advance_game for super::RemoteReducers { + fn advance_game(&self, game_timer: GameTimer, +) -> __sdk::Result<()> { + self.imp.call_reducer("advance_game", AdvanceGameArgs { game_timer, }) + } + fn on_advance_game( + &self, + mut callback: impl FnMut(&super::ReducerEventContext, &GameTimer, ) + Send + 'static, + ) -> AdvanceGameCallbackId { + AdvanceGameCallbackId(self.imp.on_reducer( + "advance_game", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: __sdk::ReducerEvent { + reducer: super::Reducer::AdvanceGame { + game_timer, + }, + .. + }, + .. + } = ctx else { unreachable!() }; + callback(ctx, game_timer, ) + }), + )) + } + fn remove_on_advance_game(&self, callback: AdvanceGameCallbackId) { + self.imp.remove_on_reducer("advance_game", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `advance_game`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_advance_game { + /// Set the call-reducer flags for the reducer `advance_game` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn advance_game(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_advance_game for super::SetReducerFlags { + fn advance_game(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("advance_game", flags); + } +} + diff --git a/jong-db/src/db/bot_table.rs b/jong-db/src/db/bot_table.rs index 7c9d250..25f7dfb 100644 --- a/jong-db/src/db/bot_table.rs +++ b/jong-db/src/db/bot_table.rs @@ -2,9 +2,15 @@ // 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, +}; use super::bot_type::Bot; +use super::turn_state_type::TurnState; use super::db_tile_type::DbTile; -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; /// Table handle for the table `bot`. /// @@ -45,12 +51,8 @@ impl<'ctx> __sdk::Table for BotTableHandle<'ctx> { type Row = Bot; type EventContext = super::EventContext; - fn count(&self) -> u64 { - self.imp.count() - } - fn iter(&self) -> impl Iterator + '_ { - self.imp.iter() - } + fn count(&self) -> u64 { self.imp.count() } + fn iter(&self) -> impl Iterator + '_ { self.imp.iter() } type InsertCallbackId = BotInsertCallbackId; @@ -81,7 +83,8 @@ impl<'ctx> __sdk::Table for BotTableHandle<'ctx> { #[doc(hidden)] pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { - let _table = client_cache.get_or_make_table::("bot"); + + let _table = client_cache.get_or_make_table::("bot"); _table.add_unique_constraint::("id", |row| &row.id); } pub struct BotUpdateCallbackId(__sdk::CallbackId); @@ -101,43 +104,46 @@ impl<'ctx> __sdk::TableWithPrimaryKey for BotTableHandle<'ctx> { } } + #[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() + __sdk::InternalError::failed_parse( + "TableUpdate", + "TableUpdate", + ).with_cause(e).into() }) } -/// Access to the `id` unique index on the table `bot`, -/// which allows point queries on the field of the same name -/// via the [`BotIdUnique::find`] method. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.bot().id().find(...)`. -pub struct BotIdUnique<'ctx> { - imp: __sdk::UniqueConstraintHandle, - phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -impl<'ctx> BotTableHandle<'ctx> { - /// Get a handle on the `id` unique index on the table `bot`. - pub fn id(&self) -> BotIdUnique<'ctx> { - BotIdUnique { - imp: self.imp.get_unique_constraint::("id"), - phantom: std::marker::PhantomData, + /// Access to the `id` unique index on the table `bot`, + /// which allows point queries on the field of the same name + /// via the [`BotIdUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.bot().id().find(...)`. + pub struct BotIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, } - } -} -impl<'ctx> BotIdUnique<'ctx> { - /// Find the subscribed row whose `id` column value is equal to `col_val`, - /// if such a row is present in the client cache. - pub fn find(&self, col_val: &u32) -> Option { - self.imp.find(col_val) - } -} + impl<'ctx> BotTableHandle<'ctx> { + /// Get a handle on the `id` unique index on the table `bot`. + pub fn id(&self) -> BotIdUnique<'ctx> { + BotIdUnique { + imp: self.imp.get_unique_constraint::("id"), + phantom: std::marker::PhantomData, + } + } + } + + impl<'ctx> BotIdUnique<'ctx> { + /// Find the subscribed row whose `id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u32) -> Option { + self.imp.find(col_val) + } + } + \ No newline at end of file diff --git a/jong-db/src/db/bot_type.rs b/jong-db/src/db/bot_type.rs index 23ef7d9..b702466 100644 --- a/jong-db/src/db/bot_type.rs +++ b/jong-db/src/db/bot_type.rs @@ -2,8 +2,14 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; +use super::turn_state_type::TurnState; use super::db_tile_type::DbTile; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] @@ -11,11 +17,14 @@ use super::db_tile_type::DbTile; pub struct Bot { pub id: u32, pub lobby_id: u32, - pub hand: Vec, - pub pond: Vec, - pub drawn_tile: Option, + pub turn_state: TurnState, + pub hand: Vec::, + pub pond: Vec::, + pub working_tile: Option::, } + impl __sdk::InModule for Bot { type Module = super::RemoteModule; } + diff --git a/jong-db/src/db/clear_all_reducer.rs b/jong-db/src/db/clear_all_reducer.rs index 5870024..f33ae7f 100644 --- a/jong-db/src/db/clear_all_reducer.rs +++ b/jong-db/src/db/clear_all_reducer.rs @@ -2,16 +2,23 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] -pub(super) struct ClearAllArgs {} +pub(super) struct ClearAllArgs { + } impl From for super::Reducer { fn from(args: ClearAllArgs) -> Self { Self::ClearAll - } +} } impl __sdk::InModule for ClearAllArgs { @@ -30,7 +37,7 @@ pub trait clear_all { /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and its status can be observed by listening for [`Self::on_clear_all`] callbacks. - fn clear_all(&self) -> __sdk::Result<()>; + fn clear_all(&self, ) -> __sdk::Result<()>; /// Register a callback to run whenever we are notified of an invocation of the reducer `clear_all`. /// /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] @@ -38,39 +45,34 @@ pub trait clear_all { /// /// The returned [`ClearAllCallbackId`] can be passed to [`Self::remove_on_clear_all`] /// to cancel the callback. - fn on_clear_all( - &self, - callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> ClearAllCallbackId; + fn on_clear_all(&self, callback: impl FnMut(&super::ReducerEventContext, ) + Send + 'static) -> ClearAllCallbackId; /// Cancel a callback previously registered by [`Self::on_clear_all`], /// causing it not to run in the future. fn remove_on_clear_all(&self, callback: ClearAllCallbackId); } impl clear_all for super::RemoteReducers { - fn clear_all(&self) -> __sdk::Result<()> { - self.imp.call_reducer("clear_all", ClearAllArgs {}) + fn clear_all(&self, ) -> __sdk::Result<()> { + self.imp.call_reducer("clear_all", ClearAllArgs { }) } fn on_clear_all( &self, - mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + mut callback: impl FnMut(&super::ReducerEventContext, ) + Send + 'static, ) -> ClearAllCallbackId { ClearAllCallbackId(self.imp.on_reducer( "clear_all", Box::new(move |ctx: &super::ReducerEventContext| { #[allow(irrefutable_let_patterns)] let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::ClearAll {}, - .. + event: __sdk::ReducerEvent { + reducer: super::Reducer::ClearAll { + }, + .. + }, .. - } = ctx - else { - unreachable!() - }; - callback(ctx) + } = ctx else { unreachable!() }; + callback(ctx, ) }), )) } @@ -98,3 +100,4 @@ impl set_flags_for_clear_all for super::SetReducerFlags { self.imp.set_call_reducer_flags("clear_all", flags); } } + diff --git a/jong-db/src/db/connect_reducer.rs b/jong-db/src/db/connect_reducer.rs new file mode 100644 index 0000000..e82580d --- /dev/null +++ b/jong-db/src/db/connect_reducer.rs @@ -0,0 +1,103 @@ +// 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(super) struct ConnectArgs { + } + +impl From for super::Reducer { + fn from(args: ConnectArgs) -> Self { + Self::Connect +} +} + +impl __sdk::InModule for ConnectArgs { + type Module = super::RemoteModule; +} + +pub struct ConnectCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `connect`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait connect { + /// Request that the remote module invoke the reducer `connect` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_connect`] callbacks. + fn connect(&self, ) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `connect`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`ConnectCallbackId`] can be passed to [`Self::remove_on_connect`] + /// to cancel the callback. + fn on_connect(&self, callback: impl FnMut(&super::ReducerEventContext, ) + Send + 'static) -> ConnectCallbackId; + /// Cancel a callback previously registered by [`Self::on_connect`], + /// causing it not to run in the future. + fn remove_on_connect(&self, callback: ConnectCallbackId); +} + +impl connect for super::RemoteReducers { + fn connect(&self, ) -> __sdk::Result<()> { + self.imp.call_reducer("connect", ConnectArgs { }) + } + fn on_connect( + &self, + mut callback: impl FnMut(&super::ReducerEventContext, ) + Send + 'static, + ) -> ConnectCallbackId { + ConnectCallbackId(self.imp.on_reducer( + "connect", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: __sdk::ReducerEvent { + reducer: super::Reducer::Connect { + + }, + .. + }, + .. + } = ctx else { unreachable!() }; + callback(ctx, ) + }), + )) + } + fn remove_on_connect(&self, callback: ConnectCallbackId) { + self.imp.remove_on_reducer("connect", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `connect`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_connect { + /// Set the call-reducer flags for the reducer `connect` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn connect(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_connect for super::SetReducerFlags { + fn connect(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("connect", flags); + } +} + diff --git a/jong-db/src/db/db_tile_type.rs b/jong-db/src/db/db_tile_type.rs index cf5c736..94cb0a9 100644 --- a/jong-db/src/db/db_tile_type.rs +++ b/jong-db/src/db/db_tile_type.rs @@ -2,7 +2,12 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; use super::tile_type::Tile; @@ -13,6 +18,8 @@ pub struct DbTile { pub tile: Tile, } + impl __sdk::InModule for DbTile { type Module = super::RemoteModule; } + diff --git a/jong-db/src/db/db_wall_type.rs b/jong-db/src/db/db_wall_type.rs index 20688c7..7bb7ba5 100644 --- a/jong-db/src/db/db_wall_type.rs +++ b/jong-db/src/db/db_wall_type.rs @@ -2,7 +2,12 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; use super::db_tile_type::DbTile; @@ -10,9 +15,11 @@ use super::db_tile_type::DbTile; #[sats(crate = __lib)] pub struct DbWall { pub lobby_id: u32, - pub tiles: Vec, + pub tiles: Vec::, } + impl __sdk::InModule for DbWall { type Module = super::RemoteModule; } + diff --git a/jong-db/src/db/discard_tile_reducer.rs b/jong-db/src/db/discard_tile_reducer.rs index c3bcb15..204877f 100644 --- a/jong-db/src/db/discard_tile_reducer.rs +++ b/jong-db/src/db/discard_tile_reducer.rs @@ -2,7 +2,13 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] @@ -14,8 +20,8 @@ impl From for super::Reducer { fn from(args: DiscardTileArgs) -> Self { Self::DiscardTile { tile_id: args.tile_id, - } - } +} +} } impl __sdk::InModule for DiscardTileArgs { @@ -34,7 +40,8 @@ pub trait discard_tile { /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and its status can be observed by listening for [`Self::on_discard_tile`] callbacks. - fn discard_tile(&self, tile_id: u32) -> __sdk::Result<()>; + fn discard_tile(&self, tile_id: u32, +) -> __sdk::Result<()>; /// Register a callback to run whenever we are notified of an invocation of the reducer `discard_tile`. /// /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] @@ -42,40 +49,35 @@ pub trait discard_tile { /// /// The returned [`DiscardTileCallbackId`] can be passed to [`Self::remove_on_discard_tile`] /// to cancel the callback. - fn on_discard_tile( - &self, - callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static, - ) -> DiscardTileCallbackId; + fn on_discard_tile(&self, callback: impl FnMut(&super::ReducerEventContext, &u32, ) + Send + 'static) -> DiscardTileCallbackId; /// Cancel a callback previously registered by [`Self::on_discard_tile`], /// causing it not to run in the future. fn remove_on_discard_tile(&self, callback: DiscardTileCallbackId); } impl discard_tile for super::RemoteReducers { - fn discard_tile(&self, tile_id: u32) -> __sdk::Result<()> { - self.imp - .call_reducer("discard_tile", DiscardTileArgs { tile_id }) + fn discard_tile(&self, tile_id: u32, +) -> __sdk::Result<()> { + self.imp.call_reducer("discard_tile", DiscardTileArgs { tile_id, }) } fn on_discard_tile( &self, - mut callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static, + mut callback: impl FnMut(&super::ReducerEventContext, &u32, ) + Send + 'static, ) -> DiscardTileCallbackId { DiscardTileCallbackId(self.imp.on_reducer( "discard_tile", Box::new(move |ctx: &super::ReducerEventContext| { #[allow(irrefutable_let_patterns)] let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::DiscardTile { tile_id }, - .. + event: __sdk::ReducerEvent { + reducer: super::Reducer::DiscardTile { + tile_id, }, + .. + }, .. - } = ctx - else { - unreachable!() - }; - callback(ctx, tile_id) + } = ctx else { unreachable!() }; + callback(ctx, tile_id, ) }), )) } @@ -103,3 +105,4 @@ impl set_flags_for_discard_tile for super::SetReducerFlags { self.imp.set_call_reducer_flags("discard_tile", flags); } } + diff --git a/jong-db/src/db/disconnect_reducer.rs b/jong-db/src/db/disconnect_reducer.rs new file mode 100644 index 0000000..795b9ec --- /dev/null +++ b/jong-db/src/db/disconnect_reducer.rs @@ -0,0 +1,103 @@ +// 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(super) struct DisconnectArgs { + } + +impl From for super::Reducer { + fn from(args: DisconnectArgs) -> Self { + Self::Disconnect +} +} + +impl __sdk::InModule for DisconnectArgs { + type Module = super::RemoteModule; +} + +pub struct DisconnectCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `disconnect`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait disconnect { + /// Request that the remote module invoke the reducer `disconnect` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_disconnect`] callbacks. + fn disconnect(&self, ) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `disconnect`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`DisconnectCallbackId`] can be passed to [`Self::remove_on_disconnect`] + /// to cancel the callback. + fn on_disconnect(&self, callback: impl FnMut(&super::ReducerEventContext, ) + Send + 'static) -> DisconnectCallbackId; + /// Cancel a callback previously registered by [`Self::on_disconnect`], + /// causing it not to run in the future. + fn remove_on_disconnect(&self, callback: DisconnectCallbackId); +} + +impl disconnect for super::RemoteReducers { + fn disconnect(&self, ) -> __sdk::Result<()> { + self.imp.call_reducer("disconnect", DisconnectArgs { }) + } + fn on_disconnect( + &self, + mut callback: impl FnMut(&super::ReducerEventContext, ) + Send + 'static, + ) -> DisconnectCallbackId { + DisconnectCallbackId(self.imp.on_reducer( + "disconnect", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: __sdk::ReducerEvent { + reducer: super::Reducer::Disconnect { + + }, + .. + }, + .. + } = ctx else { unreachable!() }; + callback(ctx, ) + }), + )) + } + fn remove_on_disconnect(&self, callback: DisconnectCallbackId) { + self.imp.remove_on_reducer("disconnect", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `disconnect`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_disconnect { + /// Set the call-reducer flags for the reducer `disconnect` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn disconnect(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_disconnect for super::SetReducerFlags { + fn disconnect(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("disconnect", flags); + } +} + diff --git a/jong-db/src/db/dragon_type.rs b/jong-db/src/db/dragon_type.rs index 4b954b1..58733f5 100644 --- a/jong-db/src/db/dragon_type.rs +++ b/jong-db/src/db/dragon_type.rs @@ -2,7 +2,12 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] @@ -13,8 +18,12 @@ pub enum Dragon { Hatsu, Chun, + } + + impl __sdk::InModule for Dragon { type Module = super::RemoteModule; } + diff --git a/jong-db/src/db/game_state_type.rs b/jong-db/src/db/game_state_type.rs index b8cafa4..7bb60cb 100644 --- a/jong-db/src/db/game_state_type.rs +++ b/jong-db/src/db/game_state_type.rs @@ -2,7 +2,12 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] @@ -19,8 +24,12 @@ pub enum GameState { Play, Exit, + } + + impl __sdk::InModule for GameState { type Module = super::RemoteModule; } + diff --git a/jong-db/src/db/game_timer_table.rs b/jong-db/src/db/game_timer_table.rs new file mode 100644 index 0000000..db3138b --- /dev/null +++ b/jong-db/src/db/game_timer_table.rs @@ -0,0 +1,178 @@ +// 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, +}; +use super::game_timer_type::GameTimer; + +/// Table handle for the table `game_timer`. +/// +/// Obtain a handle from the [`GameTimerTableAccess::game_timer`] method on [`super::RemoteTables`], +/// like `ctx.db.game_timer()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.game_timer().on_insert(...)`. +pub struct GameTimerTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `game_timer`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait GameTimerTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`GameTimerTableHandle`], which mediates access to the table `game_timer`. + fn game_timer(&self) -> GameTimerTableHandle<'_>; +} + +impl GameTimerTableAccess for super::RemoteTables { + fn game_timer(&self) -> GameTimerTableHandle<'_> { + GameTimerTableHandle { + imp: self.imp.get_table::("game_timer"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct GameTimerInsertCallbackId(__sdk::CallbackId); +pub struct GameTimerDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for GameTimerTableHandle<'ctx> { + type Row = GameTimer; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { self.imp.count() } + fn iter(&self) -> impl Iterator + '_ { self.imp.iter() } + + type InsertCallbackId = GameTimerInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> GameTimerInsertCallbackId { + GameTimerInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: GameTimerInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = GameTimerDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> GameTimerDeleteCallbackId { + GameTimerDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: GameTimerDeleteCallbackId) { + 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::("game_timer"); + _table.add_unique_constraint::("id", |row| &row.id); + _table.add_unique_constraint::("lobby_id", |row| &row.lobby_id); +} +pub struct GameTimerUpdateCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableWithPrimaryKey for GameTimerTableHandle<'ctx> { + type UpdateCallbackId = GameTimerUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> GameTimerUpdateCallbackId { + GameTimerUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: GameTimerUpdateCallbackId) { + 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 `id` unique index on the table `game_timer`, + /// which allows point queries on the field of the same name + /// via the [`GameTimerIdUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.game_timer().id().find(...)`. + pub struct GameTimerIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, + } + + impl<'ctx> GameTimerTableHandle<'ctx> { + /// Get a handle on the `id` unique index on the table `game_timer`. + pub fn id(&self) -> GameTimerIdUnique<'ctx> { + GameTimerIdUnique { + imp: self.imp.get_unique_constraint::("id"), + phantom: std::marker::PhantomData, + } + } + } + + impl<'ctx> GameTimerIdUnique<'ctx> { + /// Find the subscribed row whose `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) + } + } + + /// Access to the `lobby_id` unique index on the table `game_timer`, + /// which allows point queries on the field of the same name + /// via the [`GameTimerLobbyIdUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.game_timer().lobby_id().find(...)`. + pub struct GameTimerLobbyIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, + } + + impl<'ctx> GameTimerTableHandle<'ctx> { + /// Get a handle on the `lobby_id` unique index on the table `game_timer`. + pub fn lobby_id(&self) -> GameTimerLobbyIdUnique<'ctx> { + GameTimerLobbyIdUnique { + imp: self.imp.get_unique_constraint::("lobby_id"), + phantom: std::marker::PhantomData, + } + } + } + + impl<'ctx> GameTimerLobbyIdUnique<'ctx> { + /// Find the subscribed row whose `lobby_id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u32) -> Option { + self.imp.find(col_val) + } + } + \ No newline at end of file diff --git a/jong-db/src/db/game_timer_type.rs b/jong-db/src/db/game_timer_type.rs new file mode 100644 index 0000000..19af105 --- /dev/null +++ b/jong-db/src/db/game_timer_type.rs @@ -0,0 +1,25 @@ +// 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 GameTimer { + pub id: u64, + pub lobby_id: u32, + pub scheduled_at: __sdk::ScheduleAt, +} + + +impl __sdk::InModule for GameTimer { + type Module = super::RemoteModule; +} + diff --git a/jong-db/src/db/join_or_create_lobby_reducer.rs b/jong-db/src/db/join_or_create_lobby_reducer.rs index 2545903..c9aec78 100644 --- a/jong-db/src/db/join_or_create_lobby_reducer.rs +++ b/jong-db/src/db/join_or_create_lobby_reducer.rs @@ -2,7 +2,13 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] @@ -14,8 +20,8 @@ impl From for super::Reducer { fn from(args: JoinOrCreateLobbyArgs) -> Self { Self::JoinOrCreateLobby { lobby_id: args.lobby_id, - } - } +} +} } impl __sdk::InModule for JoinOrCreateLobbyArgs { @@ -34,7 +40,8 @@ pub trait join_or_create_lobby { /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and its status can be observed by listening for [`Self::on_join_or_create_lobby`] callbacks. - fn join_or_create_lobby(&self, lobby_id: u32) -> __sdk::Result<()>; + fn join_or_create_lobby(&self, lobby_id: u32, +) -> __sdk::Result<()>; /// Register a callback to run whenever we are notified of an invocation of the reducer `join_or_create_lobby`. /// /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] @@ -42,46 +49,40 @@ pub trait join_or_create_lobby { /// /// The returned [`JoinOrCreateLobbyCallbackId`] can be passed to [`Self::remove_on_join_or_create_lobby`] /// to cancel the callback. - fn on_join_or_create_lobby( - &self, - callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static, - ) -> JoinOrCreateLobbyCallbackId; + fn on_join_or_create_lobby(&self, callback: impl FnMut(&super::ReducerEventContext, &u32, ) + Send + 'static) -> JoinOrCreateLobbyCallbackId; /// Cancel a callback previously registered by [`Self::on_join_or_create_lobby`], /// causing it not to run in the future. fn remove_on_join_or_create_lobby(&self, callback: JoinOrCreateLobbyCallbackId); } impl join_or_create_lobby for super::RemoteReducers { - fn join_or_create_lobby(&self, lobby_id: u32) -> __sdk::Result<()> { - self.imp - .call_reducer("join_or_create_lobby", JoinOrCreateLobbyArgs { lobby_id }) + fn join_or_create_lobby(&self, lobby_id: u32, +) -> __sdk::Result<()> { + self.imp.call_reducer("join_or_create_lobby", JoinOrCreateLobbyArgs { lobby_id, }) } fn on_join_or_create_lobby( &self, - mut callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static, + mut callback: impl FnMut(&super::ReducerEventContext, &u32, ) + Send + 'static, ) -> JoinOrCreateLobbyCallbackId { JoinOrCreateLobbyCallbackId(self.imp.on_reducer( "join_or_create_lobby", Box::new(move |ctx: &super::ReducerEventContext| { #[allow(irrefutable_let_patterns)] let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::JoinOrCreateLobby { lobby_id }, - .. + event: __sdk::ReducerEvent { + reducer: super::Reducer::JoinOrCreateLobby { + lobby_id, }, + .. + }, .. - } = ctx - else { - unreachable!() - }; - callback(ctx, lobby_id) + } = ctx else { unreachable!() }; + callback(ctx, lobby_id, ) }), )) } fn remove_on_join_or_create_lobby(&self, callback: JoinOrCreateLobbyCallbackId) { - self.imp - .remove_on_reducer("join_or_create_lobby", callback.0) + self.imp.remove_on_reducer("join_or_create_lobby", callback.0) } } @@ -101,7 +102,7 @@ pub trait set_flags_for_join_or_create_lobby { impl set_flags_for_join_or_create_lobby for super::SetReducerFlags { fn join_or_create_lobby(&self, flags: __ws::CallReducerFlags) { - self.imp - .set_call_reducer_flags("join_or_create_lobby", flags); + self.imp.set_call_reducer_flags("join_or_create_lobby", flags); } } + diff --git a/jong-db/src/db/lobby_table.rs b/jong-db/src/db/lobby_table.rs index 98b9f62..e403a30 100644 --- a/jong-db/src/db/lobby_table.rs +++ b/jong-db/src/db/lobby_table.rs @@ -2,11 +2,15 @@ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. #![allow(unused, clippy::all)] -use super::game_state_type::GameState; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; use super::lobby_type::Lobby; use super::player_or_bot_type::PlayerOrBot; -use super::turn_state_type::TurnState; -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::game_state_type::GameState; /// Table handle for the table `lobby`. /// @@ -47,12 +51,8 @@ impl<'ctx> __sdk::Table for LobbyTableHandle<'ctx> { type Row = Lobby; type EventContext = super::EventContext; - fn count(&self) -> u64 { - self.imp.count() - } - fn iter(&self) -> impl Iterator + '_ { - self.imp.iter() - } + fn count(&self) -> u64 { self.imp.count() } + fn iter(&self) -> impl Iterator + '_ { self.imp.iter() } type InsertCallbackId = LobbyInsertCallbackId; @@ -83,9 +83,9 @@ impl<'ctx> __sdk::Table for LobbyTableHandle<'ctx> { #[doc(hidden)] pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { - let _table = client_cache.get_or_make_table::("lobby"); + + let _table = client_cache.get_or_make_table::("lobby"); _table.add_unique_constraint::("id", |row| &row.id); - _table.add_unique_constraint::("host_player_id", |row| &row.host_player_id); } pub struct LobbyUpdateCallbackId(__sdk::CallbackId); @@ -104,73 +104,46 @@ impl<'ctx> __sdk::TableWithPrimaryKey for LobbyTableHandle<'ctx> { } } + #[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() + __sdk::InternalError::failed_parse( + "TableUpdate", + "TableUpdate", + ).with_cause(e).into() }) } -/// Access to the `id` unique index on the table `lobby`, -/// which allows point queries on the field of the same name -/// via the [`LobbyIdUnique::find`] method. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.lobby().id().find(...)`. -pub struct LobbyIdUnique<'ctx> { - imp: __sdk::UniqueConstraintHandle, - phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -impl<'ctx> LobbyTableHandle<'ctx> { - /// Get a handle on the `id` unique index on the table `lobby`. - pub fn id(&self) -> LobbyIdUnique<'ctx> { - LobbyIdUnique { - imp: self.imp.get_unique_constraint::("id"), - phantom: std::marker::PhantomData, + /// Access to the `id` unique index on the table `lobby`, + /// which allows point queries on the field of the same name + /// via the [`LobbyIdUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.lobby().id().find(...)`. + pub struct LobbyIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, } - } -} -impl<'ctx> LobbyIdUnique<'ctx> { - /// Find the subscribed row whose `id` column value is equal to `col_val`, - /// if such a row is present in the client cache. - pub fn find(&self, col_val: &u32) -> Option { - self.imp.find(col_val) - } -} - -/// Access to the `host_player_id` unique index on the table `lobby`, -/// which allows point queries on the field of the same name -/// via the [`LobbyHostPlayerIdUnique::find`] method. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.lobby().host_player_id().find(...)`. -pub struct LobbyHostPlayerIdUnique<'ctx> { - imp: __sdk::UniqueConstraintHandle, - phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -impl<'ctx> LobbyTableHandle<'ctx> { - /// Get a handle on the `host_player_id` unique index on the table `lobby`. - pub fn host_player_id(&self) -> LobbyHostPlayerIdUnique<'ctx> { - LobbyHostPlayerIdUnique { - imp: self.imp.get_unique_constraint::("host_player_id"), - phantom: std::marker::PhantomData, + impl<'ctx> LobbyTableHandle<'ctx> { + /// Get a handle on the `id` unique index on the table `lobby`. + pub fn id(&self) -> LobbyIdUnique<'ctx> { + LobbyIdUnique { + imp: self.imp.get_unique_constraint::("id"), + phantom: std::marker::PhantomData, + } + } } - } -} -impl<'ctx> LobbyHostPlayerIdUnique<'ctx> { - /// Find the subscribed row whose `host_player_id` column value is equal to `col_val`, - /// if such a row is present in the client cache. - pub fn find(&self, col_val: &u32) -> Option { - self.imp.find(col_val) - } -} + impl<'ctx> LobbyIdUnique<'ctx> { + /// Find the subscribed row whose `id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u32) -> Option { + self.imp.find(col_val) + } + } + \ No newline at end of file diff --git a/jong-db/src/db/lobby_type.rs b/jong-db/src/db/lobby_type.rs index a295a91..34621a1 100644 --- a/jong-db/src/db/lobby_type.rs +++ b/jong-db/src/db/lobby_type.rs @@ -2,24 +2,28 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; -use super::game_state_type::GameState; use super::player_or_bot_type::PlayerOrBot; -use super::turn_state_type::TurnState; +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_player_id: u32, - pub players: Vec, + pub players: Vec::, pub dealer_idx: u8, pub current_idx: u8, pub game_state: GameState, - pub turn_state: TurnState, } + impl __sdk::InModule for Lobby { type Module = super::RemoteModule; } + diff --git a/jong-db/src/db/logged_out_player_table.rs b/jong-db/src/db/logged_out_player_table.rs new file mode 100644 index 0000000..a66b89e --- /dev/null +++ b/jong-db/src/db/logged_out_player_table.rs @@ -0,0 +1,178 @@ +// 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, +}; +use super::player_type::Player; + +/// Table handle for the table `logged_out_player`. +/// +/// Obtain a handle from the [`LoggedOutPlayerTableAccess::logged_out_player`] method on [`super::RemoteTables`], +/// like `ctx.db.logged_out_player()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.logged_out_player().on_insert(...)`. +pub struct LoggedOutPlayerTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `logged_out_player`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait LoggedOutPlayerTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`LoggedOutPlayerTableHandle`], which mediates access to the table `logged_out_player`. + fn logged_out_player(&self) -> LoggedOutPlayerTableHandle<'_>; +} + +impl LoggedOutPlayerTableAccess for super::RemoteTables { + fn logged_out_player(&self) -> LoggedOutPlayerTableHandle<'_> { + LoggedOutPlayerTableHandle { + imp: self.imp.get_table::("logged_out_player"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct LoggedOutPlayerInsertCallbackId(__sdk::CallbackId); +pub struct LoggedOutPlayerDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for LoggedOutPlayerTableHandle<'ctx> { + type Row = Player; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { self.imp.count() } + fn iter(&self) -> impl Iterator + '_ { self.imp.iter() } + + type InsertCallbackId = LoggedOutPlayerInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> LoggedOutPlayerInsertCallbackId { + LoggedOutPlayerInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: LoggedOutPlayerInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = LoggedOutPlayerDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> LoggedOutPlayerDeleteCallbackId { + LoggedOutPlayerDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: LoggedOutPlayerDeleteCallbackId) { + 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::("logged_out_player"); + _table.add_unique_constraint::("id", |row| &row.id); + _table.add_unique_constraint::<__sdk::Identity>("identity", |row| &row.identity); +} +pub struct LoggedOutPlayerUpdateCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableWithPrimaryKey for LoggedOutPlayerTableHandle<'ctx> { + type UpdateCallbackId = LoggedOutPlayerUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> LoggedOutPlayerUpdateCallbackId { + LoggedOutPlayerUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: LoggedOutPlayerUpdateCallbackId) { + 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 `id` unique index on the table `logged_out_player`, + /// which allows point queries on the field of the same name + /// via the [`LoggedOutPlayerIdUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.logged_out_player().id().find(...)`. + pub struct LoggedOutPlayerIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, + } + + impl<'ctx> LoggedOutPlayerTableHandle<'ctx> { + /// Get a handle on the `id` unique index on the table `logged_out_player`. + pub fn id(&self) -> LoggedOutPlayerIdUnique<'ctx> { + LoggedOutPlayerIdUnique { + imp: self.imp.get_unique_constraint::("id"), + phantom: std::marker::PhantomData, + } + } + } + + impl<'ctx> LoggedOutPlayerIdUnique<'ctx> { + /// Find the subscribed row whose `id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u32) -> Option { + self.imp.find(col_val) + } + } + + /// Access to the `identity` unique index on the table `logged_out_player`, + /// which allows point queries on the field of the same name + /// via the [`LoggedOutPlayerIdentityUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.logged_out_player().identity().find(...)`. + pub struct LoggedOutPlayerIdentityUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, + } + + impl<'ctx> LoggedOutPlayerTableHandle<'ctx> { + /// Get a handle on the `identity` unique index on the table `logged_out_player`. + pub fn identity(&self) -> LoggedOutPlayerIdentityUnique<'ctx> { + LoggedOutPlayerIdentityUnique { + imp: self.imp.get_unique_constraint::<__sdk::Identity>("identity"), + phantom: std::marker::PhantomData, + } + } + } + + impl<'ctx> LoggedOutPlayerIdentityUnique<'ctx> { + /// Find the subscribed row whose `identity` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &__sdk::Identity) -> Option { + self.imp.find(col_val) + } + } + \ No newline at end of file diff --git a/jong-db/src/db/mod.rs b/jong-db/src/db/mod.rs index 3eb7040..4d46508 100644 --- a/jong-db/src/db/mod.rs +++ b/jong-db/src/db/mod.rs @@ -4,73 +4,80 @@ // This was generated using spacetimedb cli version 1.11.3 (commit 02449737ca3b29e7e39679fccbef541a50f32094). #![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +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; pub mod db_tile_type; pub mod db_wall_type; -pub mod discard_tile_reducer; pub mod dragon_type; -pub mod draw_tile_reducer; pub mod game_state_type; -pub mod join_or_create_lobby_reducer; -pub mod lobby_table; +pub mod game_timer_type; pub mod lobby_type; -pub mod login_or_add_player_reducer; -pub mod player_or_bot_type; -pub mod player_table; pub mod player_type; +pub mod player_clock_type; +pub mod player_hand_type; +pub mod player_or_bot_type; pub mod rank_type; -pub mod set_ready_reducer; -pub mod shuffle_deal_reducer; -pub mod skip_call_reducer; -pub mod start_game_reducer; pub mod suit_type; -pub mod tile_table; pub mod tile_type; pub mod turn_state_type; -pub mod wall_table; pub mod wind_type; +pub mod add_bot_reducer; +pub mod advance_game_reducer; +pub mod clear_all_reducer; +pub mod connect_reducer; +pub mod discard_tile_reducer; +pub mod disconnect_reducer; +pub mod join_or_create_lobby_reducer; +pub mod set_ready_reducer; +pub mod bot_table; +pub mod game_timer_table; +pub mod lobby_table; +pub mod logged_out_player_table; +pub mod player_table; +pub mod player_clock_table; +pub mod player_hand_table; +pub mod tile_table; +pub mod wall_table; -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}; pub use db_tile_type::DbTile; pub use db_wall_type::DbWall; -pub use discard_tile_reducer::{discard_tile, set_flags_for_discard_tile, DiscardTileCallbackId}; pub use dragon_type::Dragon; -pub use draw_tile_reducer::{draw_tile, set_flags_for_draw_tile, DrawTileCallbackId}; pub use game_state_type::GameState; -pub use join_or_create_lobby_reducer::{ - join_or_create_lobby, set_flags_for_join_or_create_lobby, JoinOrCreateLobbyCallbackId, -}; -pub use lobby_table::*; +pub use game_timer_type::GameTimer; pub use lobby_type::Lobby; -pub use login_or_add_player_reducer::{ - login_or_add_player, set_flags_for_login_or_add_player, LoginOrAddPlayerCallbackId, -}; -pub use player_or_bot_type::PlayerOrBot; -pub use player_table::*; pub use player_type::Player; +pub use player_clock_type::PlayerClock; +pub use player_hand_type::PlayerHand; +pub use player_or_bot_type::PlayerOrBot; pub use rank_type::Rank; -pub use set_ready_reducer::{set_flags_for_set_ready, set_ready, SetReadyCallbackId}; -pub use shuffle_deal_reducer::{set_flags_for_shuffle_deal, shuffle_deal, ShuffleDealCallbackId}; -pub use skip_call_reducer::{set_flags_for_skip_call, skip_call, SkipCallCallbackId}; -pub use start_game_reducer::{set_flags_for_start_game, start_game, StartGameCallbackId}; pub use suit_type::Suit; -pub use tile_table::*; pub use tile_type::Tile; pub use turn_state_type::TurnState; -pub use wall_table::*; pub use wind_type::Wind; +pub use bot_table::*; +pub use game_timer_table::*; +pub use lobby_table::*; +pub use logged_out_player_table::*; +pub use player_table::*; +pub use player_clock_table::*; +pub use player_hand_table::*; +pub use tile_table::*; +pub use wall_table::*; +pub use add_bot_reducer::{add_bot, set_flags_for_add_bot, AddBotCallbackId}; +pub use advance_game_reducer::{advance_game, set_flags_for_advance_game, AdvanceGameCallbackId}; +pub use clear_all_reducer::{clear_all, set_flags_for_clear_all, ClearAllCallbackId}; +pub use connect_reducer::{connect, set_flags_for_connect, ConnectCallbackId}; +pub use discard_tile_reducer::{discard_tile, set_flags_for_discard_tile, DiscardTileCallbackId}; +pub use disconnect_reducer::{disconnect, set_flags_for_disconnect, DisconnectCallbackId}; +pub use join_or_create_lobby_reducer::{join_or_create_lobby, set_flags_for_join_or_create_lobby, JoinOrCreateLobbyCallbackId}; +pub use set_ready_reducer::{set_ready, set_flags_for_set_ready, SetReadyCallbackId}; #[derive(Clone, PartialEq, Debug)] @@ -80,18 +87,27 @@ pub use wind_type::Wind; /// to indicate which reducer caused the event. pub enum Reducer { - AddBot { lobby_id: u32 }, - ClearAll, - DiscardTile { tile_id: u32 }, - DrawTile, - JoinOrCreateLobby { lobby_id: u32 }, - LoginOrAddPlayer, - SetReady { ready: bool }, - ShuffleDeal { lobby_id: u32 }, - SkipCall, - StartGame, + AddBot { + lobby_id: u32, +} , + AdvanceGame { + game_timer: GameTimer, +} , + ClearAll , + Connect , + DiscardTile { + tile_id: u32, +} , + Disconnect , + JoinOrCreateLobby { + lobby_id: u32, +} , + SetReady { + ready: bool, +} , } + impl __sdk::InModule for Reducer { type Module = RemoteModule; } @@ -99,140 +115,74 @@ impl __sdk::InModule for Reducer { impl __sdk::Reducer for Reducer { fn reducer_name(&self) -> &'static str { match self { - Reducer::AddBot { .. } => "add_bot", + Reducer::AddBot { .. } => "add_bot", + Reducer::AdvanceGame { .. } => "advance_game", Reducer::ClearAll => "clear_all", + Reducer::Connect => "connect", Reducer::DiscardTile { .. } => "discard_tile", - Reducer::DrawTile => "draw_tile", + Reducer::Disconnect => "disconnect", Reducer::JoinOrCreateLobby { .. } => "join_or_create_lobby", - Reducer::LoginOrAddPlayer => "login_or_add_player", Reducer::SetReady { .. } => "set_ready", - Reducer::ShuffleDeal { .. } => "shuffle_deal", - Reducer::SkipCall => "skip_call", - Reducer::StartGame => "start_game", _ => unreachable!(), - } - } +} +} } impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { - type Error = __sdk::Error; - fn try_from(value: __ws::ReducerCallInfo<__ws::BsatnFormat>) -> __sdk::Result { + type Error = __sdk::Error; +fn try_from(value: __ws::ReducerCallInfo<__ws::BsatnFormat>) -> __sdk::Result { match &value.reducer_name[..] { - "add_bot" => Ok(__sdk::parse_reducer_args::( - "add_bot", - &value.args, - )? - .into()), - "clear_all" => Ok( - __sdk::parse_reducer_args::( - "clear_all", - &value.args, - )? - .into(), - ), - "discard_tile" => Ok( - __sdk::parse_reducer_args::( - "discard_tile", - &value.args, - )? - .into(), - ), - "draw_tile" => Ok( - __sdk::parse_reducer_args::( - "draw_tile", - &value.args, - )? - .into(), - ), - "join_or_create_lobby" => Ok(__sdk::parse_reducer_args::< - join_or_create_lobby_reducer::JoinOrCreateLobbyArgs, - >("join_or_create_lobby", &value.args)? - .into()), - "login_or_add_player" => Ok(__sdk::parse_reducer_args::< - login_or_add_player_reducer::LoginOrAddPlayerArgs, - >("login_or_add_player", &value.args)? - .into()), - "set_ready" => Ok( - __sdk::parse_reducer_args::( - "set_ready", - &value.args, - )? - .into(), - ), - "shuffle_deal" => Ok( - __sdk::parse_reducer_args::( - "shuffle_deal", - &value.args, - )? - .into(), - ), - "skip_call" => Ok( - __sdk::parse_reducer_args::( - "skip_call", - &value.args, - )? - .into(), - ), - "start_game" => Ok( - __sdk::parse_reducer_args::( - "start_game", - &value.args, - )? - .into(), - ), - unknown => { - Err( - __sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo") - .into(), - ) - } - } - } + "add_bot" => Ok(__sdk::parse_reducer_args::("add_bot", &value.args)?.into()), + "advance_game" => Ok(__sdk::parse_reducer_args::("advance_game", &value.args)?.into()), + "clear_all" => Ok(__sdk::parse_reducer_args::("clear_all", &value.args)?.into()), + "connect" => Ok(__sdk::parse_reducer_args::("connect", &value.args)?.into()), + "discard_tile" => Ok(__sdk::parse_reducer_args::("discard_tile", &value.args)?.into()), + "disconnect" => Ok(__sdk::parse_reducer_args::("disconnect", &value.args)?.into()), + "join_or_create_lobby" => Ok(__sdk::parse_reducer_args::("join_or_create_lobby", &value.args)?.into()), + "set_ready" => Ok(__sdk::parse_reducer_args::("set_ready", &value.args)?.into()), + unknown => Err(__sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo").into()), +} +} } #[derive(Default)] #[allow(non_snake_case)] #[doc(hidden)] pub struct DbUpdate { - advance_state_timer: __sdk::TableUpdate, - bot: __sdk::TableUpdate, + bot: __sdk::TableUpdate, + game_timer: __sdk::TableUpdate, lobby: __sdk::TableUpdate, + logged_out_player: __sdk::TableUpdate, player: __sdk::TableUpdate, + player_clock: __sdk::TableUpdate, + player_hand: __sdk::TableUpdate, tile: __sdk::TableUpdate, wall: __sdk::TableUpdate, } + impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { type Error = __sdk::Error; fn try_from(raw: __ws::DatabaseUpdate<__ws::BsatnFormat>) -> Result { 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)?), - "lobby" => db_update - .lobby - .append(lobby_table::parse_table_update(table_update)?), - "player" => db_update - .player - .append(player_table::parse_table_update(table_update)?), - "tile" => db_update - .tile - .append(tile_table::parse_table_update(table_update)?), - "wall" => db_update - .wall - .append(wall_table::parse_table_update(table_update)?), + + "bot" => db_update.bot.append(bot_table::parse_table_update(table_update)?), + "game_timer" => db_update.game_timer.append(game_timer_table::parse_table_update(table_update)?), + "lobby" => db_update.lobby.append(lobby_table::parse_table_update(table_update)?), + "logged_out_player" => db_update.logged_out_player.append(logged_out_player_table::parse_table_update(table_update)?), + "player" => db_update.player.append(player_table::parse_table_update(table_update)?), + "player_clock" => db_update.player_clock.append(player_clock_table::parse_table_update(table_update)?), + "player_hand" => db_update.player_hand.append(player_hand_table::parse_table_update(table_update)?), + "tile" => db_update.tile.append(tile_table::parse_table_update(table_update)?), + "wall" => db_update.wall.append(wall_table::parse_table_update(table_update)?), unknown => { return Err(__sdk::InternalError::unknown_name( "table", unknown, "DatabaseUpdate", - ) - .into()); + ).into()); } } } @@ -245,73 +195,58 @@ impl __sdk::InModule for DbUpdate { } impl __sdk::DbUpdate for DbUpdate { - fn apply_to_client_cache( - &self, - cache: &mut __sdk::ClientCache, - ) -> AppliedDiff<'_> { - let mut diff = AppliedDiff::default(); + fn apply_to_client_cache(&self, cache: &mut __sdk::ClientCache) -> AppliedDiff<'_> { + let mut diff = AppliedDiff::default(); + + diff.bot = cache.apply_diff_to_table::("bot", &self.bot).with_updates_by_pk(|row| &row.id); + diff.game_timer = cache.apply_diff_to_table::("game_timer", &self.game_timer).with_updates_by_pk(|row| &row.id); + diff.lobby = cache.apply_diff_to_table::("lobby", &self.lobby).with_updates_by_pk(|row| &row.id); + diff.logged_out_player = cache.apply_diff_to_table::("logged_out_player", &self.logged_out_player).with_updates_by_pk(|row| &row.identity); + diff.player = cache.apply_diff_to_table::("player", &self.player).with_updates_by_pk(|row| &row.identity); + diff.player_clock = cache.apply_diff_to_table::("player_clock", &self.player_clock).with_updates_by_pk(|row| &row.id); + diff.player_hand = cache.apply_diff_to_table::("player_hand", &self.player_hand).with_updates_by_pk(|row| &row.id); + diff.tile = cache.apply_diff_to_table::("tile", &self.tile).with_updates_by_pk(|row| &row.id); + diff.wall = cache.apply_diff_to_table::("wall", &self.wall).with_updates_by_pk(|row| &row.lobby_id); - 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); - diff.lobby = cache - .apply_diff_to_table::("lobby", &self.lobby) - .with_updates_by_pk(|row| &row.id); - diff.player = cache - .apply_diff_to_table::("player", &self.player) - .with_updates_by_pk(|row| &row.identity); - diff.tile = cache - .apply_diff_to_table::("tile", &self.tile) - .with_updates_by_pk(|row| &row.id); - diff.wall = cache - .apply_diff_to_table::("wall", &self.wall) - .with_updates_by_pk(|row| &row.lobby_id); - - diff - } + diff + } } #[derive(Default)] #[allow(non_snake_case)] #[doc(hidden)] pub struct AppliedDiff<'r> { - advance_state_timer: __sdk::TableAppliedDiff<'r, AdvanceStateTimer>, - bot: __sdk::TableAppliedDiff<'r, Bot>, + bot: __sdk::TableAppliedDiff<'r, Bot>, + game_timer: __sdk::TableAppliedDiff<'r, GameTimer>, lobby: __sdk::TableAppliedDiff<'r, Lobby>, + logged_out_player: __sdk::TableAppliedDiff<'r, Player>, player: __sdk::TableAppliedDiff<'r, Player>, + player_clock: __sdk::TableAppliedDiff<'r, PlayerClock>, + player_hand: __sdk::TableAppliedDiff<'r, PlayerHand>, tile: __sdk::TableAppliedDiff<'r, DbTile>, wall: __sdk::TableAppliedDiff<'r, DbWall>, __unused: std::marker::PhantomData<&'r ()>, } + impl __sdk::InModule for AppliedDiff<'_> { type Module = RemoteModule; } impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { - fn invoke_row_callbacks( - &self, - 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); + fn invoke_row_callbacks(&self, event: &EventContext, callbacks: &mut __sdk::DbCallbacks) { + callbacks.invoke_table_row_callbacks::("bot", &self.bot, event); + callbacks.invoke_table_row_callbacks::("game_timer", &self.game_timer, event); callbacks.invoke_table_row_callbacks::("lobby", &self.lobby, event); + callbacks.invoke_table_row_callbacks::("logged_out_player", &self.logged_out_player, event); callbacks.invoke_table_row_callbacks::("player", &self.player, event); + callbacks.invoke_table_row_callbacks::("player_clock", &self.player_clock, event); + callbacks.invoke_table_row_callbacks::("player_hand", &self.player_hand, event); callbacks.invoke_table_row_callbacks::("tile", &self.tile, event); callbacks.invoke_table_row_callbacks::("wall", &self.wall, event); - } } +} + #[doc(hidden)] pub struct RemoteModule; @@ -564,6 +499,7 @@ impl __sdk::SubscriptionHandle for SubscriptionHandle { fn unsubscribe(self) -> __sdk::Result<()> { self.imp.unsubscribe_then(None) } + } /// Alias trait for a [`__sdk::DbContext`] connected to this module, @@ -571,25 +507,19 @@ impl __sdk::SubscriptionHandle for SubscriptionHandle { /// /// Users can use this trait as a boundary on definitions which should accept /// either a [`DbConnection`] or an [`EventContext`] and operate on either. -pub trait RemoteDbContext: - __sdk::DbContext< +pub trait RemoteDbContext: __sdk::DbContext< DbView = RemoteTables, Reducers = RemoteReducers, SetReducerFlags = SetReducerFlags, SubscriptionBuilder = __sdk::SubscriptionBuilder, -> -{ -} -impl< - Ctx: __sdk::DbContext< - DbView = RemoteTables, - Reducers = RemoteReducers, - SetReducerFlags = SetReducerFlags, - SubscriptionBuilder = __sdk::SubscriptionBuilder, - >, - > RemoteDbContext for Ctx -{ -} +> {} +impl, +>> RemoteDbContext for Ctx {} + /// An [`__sdk::DbContext`] augmented with a [`__sdk::Event`], /// passed to [`__sdk::Table::on_insert`], [`__sdk::Table::on_delete`] and [`__sdk::TableWithPrimaryKey::on_update`] callbacks. @@ -1014,6 +944,7 @@ impl __sdk::DbContext for ErrorContext { impl __sdk::ErrorContext for ErrorContext {} impl __sdk::SpacetimeModule for RemoteModule { + type DbConnection = DbConnection; type EventContext = EventContext; type ReducerEventContext = ReducerEventContext; @@ -1028,12 +959,15 @@ impl __sdk::SpacetimeModule for RemoteModule { type AppliedDiff<'r> = AppliedDiff<'r>; 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); +fn register_tables(client_cache: &mut __sdk::ClientCache) { + bot_table::register_table(client_cache); + game_timer_table::register_table(client_cache); lobby_table::register_table(client_cache); + logged_out_player_table::register_table(client_cache); player_table::register_table(client_cache); + player_clock_table::register_table(client_cache); + player_hand_table::register_table(client_cache); tile_table::register_table(client_cache); wall_table::register_table(client_cache); - } +} } diff --git a/jong-db/src/db/player_clock_table.rs b/jong-db/src/db/player_clock_table.rs new file mode 100644 index 0000000..41dc148 --- /dev/null +++ b/jong-db/src/db/player_clock_table.rs @@ -0,0 +1,178 @@ +// 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, +}; +use super::player_clock_type::PlayerClock; + +/// Table handle for the table `player_clock`. +/// +/// Obtain a handle from the [`PlayerClockTableAccess::player_clock`] method on [`super::RemoteTables`], +/// like `ctx.db.player_clock()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.player_clock().on_insert(...)`. +pub struct PlayerClockTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `player_clock`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait PlayerClockTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`PlayerClockTableHandle`], which mediates access to the table `player_clock`. + fn player_clock(&self) -> PlayerClockTableHandle<'_>; +} + +impl PlayerClockTableAccess for super::RemoteTables { + fn player_clock(&self) -> PlayerClockTableHandle<'_> { + PlayerClockTableHandle { + imp: self.imp.get_table::("player_clock"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct PlayerClockInsertCallbackId(__sdk::CallbackId); +pub struct PlayerClockDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for PlayerClockTableHandle<'ctx> { + type Row = PlayerClock; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { self.imp.count() } + fn iter(&self) -> impl Iterator + '_ { self.imp.iter() } + + type InsertCallbackId = PlayerClockInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PlayerClockInsertCallbackId { + PlayerClockInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: PlayerClockInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = PlayerClockDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PlayerClockDeleteCallbackId { + PlayerClockDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: PlayerClockDeleteCallbackId) { + 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::("player_clock"); + _table.add_unique_constraint::("id", |row| &row.id); + _table.add_unique_constraint::("player_id", |row| &row.player_id); +} +pub struct PlayerClockUpdateCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableWithPrimaryKey for PlayerClockTableHandle<'ctx> { + type UpdateCallbackId = PlayerClockUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> PlayerClockUpdateCallbackId { + PlayerClockUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: PlayerClockUpdateCallbackId) { + 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 `id` unique index on the table `player_clock`, + /// which allows point queries on the field of the same name + /// via the [`PlayerClockIdUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.player_clock().id().find(...)`. + pub struct PlayerClockIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, + } + + impl<'ctx> PlayerClockTableHandle<'ctx> { + /// Get a handle on the `id` unique index on the table `player_clock`. + pub fn id(&self) -> PlayerClockIdUnique<'ctx> { + PlayerClockIdUnique { + imp: self.imp.get_unique_constraint::("id"), + phantom: std::marker::PhantomData, + } + } + } + + impl<'ctx> PlayerClockIdUnique<'ctx> { + /// Find the subscribed row whose `id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u32) -> Option { + self.imp.find(col_val) + } + } + + /// Access to the `player_id` unique index on the table `player_clock`, + /// which allows point queries on the field of the same name + /// via the [`PlayerClockPlayerIdUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.player_clock().player_id().find(...)`. + pub struct PlayerClockPlayerIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, + } + + impl<'ctx> PlayerClockTableHandle<'ctx> { + /// Get a handle on the `player_id` unique index on the table `player_clock`. + pub fn player_id(&self) -> PlayerClockPlayerIdUnique<'ctx> { + PlayerClockPlayerIdUnique { + imp: self.imp.get_unique_constraint::("player_id"), + phantom: std::marker::PhantomData, + } + } + } + + impl<'ctx> PlayerClockPlayerIdUnique<'ctx> { + /// Find the subscribed row whose `player_id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u32) -> Option { + self.imp.find(col_val) + } + } + \ No newline at end of file diff --git a/jong-db/src/db/player_clock_type.rs b/jong-db/src/db/player_clock_type.rs new file mode 100644 index 0000000..6c533e6 --- /dev/null +++ b/jong-db/src/db/player_clock_type.rs @@ -0,0 +1,26 @@ +// 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 PlayerClock { + pub id: u32, + pub player_id: u32, + pub renewable: u16, + pub total: u16, +} + + +impl __sdk::InModule for PlayerClock { + type Module = super::RemoteModule; +} + diff --git a/jong-db/src/db/player_hand_table.rs b/jong-db/src/db/player_hand_table.rs new file mode 100644 index 0000000..609edd8 --- /dev/null +++ b/jong-db/src/db/player_hand_table.rs @@ -0,0 +1,180 @@ +// 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, +}; +use super::player_hand_type::PlayerHand; +use super::turn_state_type::TurnState; +use super::db_tile_type::DbTile; + +/// Table handle for the table `player_hand`. +/// +/// Obtain a handle from the [`PlayerHandTableAccess::player_hand`] method on [`super::RemoteTables`], +/// like `ctx.db.player_hand()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.player_hand().on_insert(...)`. +pub struct PlayerHandTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `player_hand`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait PlayerHandTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`PlayerHandTableHandle`], which mediates access to the table `player_hand`. + fn player_hand(&self) -> PlayerHandTableHandle<'_>; +} + +impl PlayerHandTableAccess for super::RemoteTables { + fn player_hand(&self) -> PlayerHandTableHandle<'_> { + PlayerHandTableHandle { + imp: self.imp.get_table::("player_hand"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct PlayerHandInsertCallbackId(__sdk::CallbackId); +pub struct PlayerHandDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for PlayerHandTableHandle<'ctx> { + type Row = PlayerHand; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { self.imp.count() } + fn iter(&self) -> impl Iterator + '_ { self.imp.iter() } + + type InsertCallbackId = PlayerHandInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PlayerHandInsertCallbackId { + PlayerHandInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: PlayerHandInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = PlayerHandDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PlayerHandDeleteCallbackId { + PlayerHandDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: PlayerHandDeleteCallbackId) { + 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::("player_hand"); + _table.add_unique_constraint::("id", |row| &row.id); + _table.add_unique_constraint::("player_id", |row| &row.player_id); +} +pub struct PlayerHandUpdateCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableWithPrimaryKey for PlayerHandTableHandle<'ctx> { + type UpdateCallbackId = PlayerHandUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> PlayerHandUpdateCallbackId { + PlayerHandUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: PlayerHandUpdateCallbackId) { + 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 `id` unique index on the table `player_hand`, + /// which allows point queries on the field of the same name + /// via the [`PlayerHandIdUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.player_hand().id().find(...)`. + pub struct PlayerHandIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, + } + + impl<'ctx> PlayerHandTableHandle<'ctx> { + /// Get a handle on the `id` unique index on the table `player_hand`. + pub fn id(&self) -> PlayerHandIdUnique<'ctx> { + PlayerHandIdUnique { + imp: self.imp.get_unique_constraint::("id"), + phantom: std::marker::PhantomData, + } + } + } + + impl<'ctx> PlayerHandIdUnique<'ctx> { + /// Find the subscribed row whose `id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u32) -> Option { + self.imp.find(col_val) + } + } + + /// Access to the `player_id` unique index on the table `player_hand`, + /// which allows point queries on the field of the same name + /// via the [`PlayerHandPlayerIdUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.player_hand().player_id().find(...)`. + pub struct PlayerHandPlayerIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, + } + + impl<'ctx> PlayerHandTableHandle<'ctx> { + /// Get a handle on the `player_id` unique index on the table `player_hand`. + pub fn player_id(&self) -> PlayerHandPlayerIdUnique<'ctx> { + PlayerHandPlayerIdUnique { + imp: self.imp.get_unique_constraint::("player_id"), + phantom: std::marker::PhantomData, + } + } + } + + impl<'ctx> PlayerHandPlayerIdUnique<'ctx> { + /// Find the subscribed row whose `player_id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u32) -> Option { + self.imp.find(col_val) + } + } + \ No newline at end of file diff --git a/jong-db/src/db/player_hand_type.rs b/jong-db/src/db/player_hand_type.rs new file mode 100644 index 0000000..7e62fa6 --- /dev/null +++ b/jong-db/src/db/player_hand_type.rs @@ -0,0 +1,30 @@ +// 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, +}; + +use super::turn_state_type::TurnState; +use super::db_tile_type::DbTile; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct PlayerHand { + pub id: u32, + pub player_id: u32, + pub turn_state: TurnState, + pub pond: Vec::, + pub hand: Vec::, + pub working_tile: Option::, +} + + +impl __sdk::InModule for PlayerHand { + type Module = super::RemoteModule; +} + diff --git a/jong-db/src/db/player_or_bot_type.rs b/jong-db/src/db/player_or_bot_type.rs index 538d940..eb5d35c 100644 --- a/jong-db/src/db/player_or_bot_type.rs +++ b/jong-db/src/db/player_or_bot_type.rs @@ -2,7 +2,13 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] @@ -10,8 +16,12 @@ pub enum PlayerOrBot { Player(u32), Bot(u32), + } + + impl __sdk::InModule for PlayerOrBot { type Module = super::RemoteModule; } + diff --git a/jong-db/src/db/player_table.rs b/jong-db/src/db/player_table.rs index ee7b127..0aa30cd 100644 --- a/jong-db/src/db/player_table.rs +++ b/jong-db/src/db/player_table.rs @@ -2,9 +2,13 @@ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. #![allow(unused, clippy::all)] -use super::db_tile_type::DbTile; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; use super::player_type::Player; -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; /// Table handle for the table `player`. /// @@ -45,12 +49,8 @@ impl<'ctx> __sdk::Table for PlayerTableHandle<'ctx> { type Row = Player; type EventContext = super::EventContext; - fn count(&self) -> u64 { - self.imp.count() - } - fn iter(&self) -> impl Iterator + '_ { - self.imp.iter() - } + fn count(&self) -> u64 { self.imp.count() } + fn iter(&self) -> impl Iterator + '_ { self.imp.iter() } type InsertCallbackId = PlayerInsertCallbackId; @@ -81,9 +81,10 @@ impl<'ctx> __sdk::Table for PlayerTableHandle<'ctx> { #[doc(hidden)] pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { - let _table = client_cache.get_or_make_table::("player"); - _table.add_unique_constraint::<__sdk::Identity>("identity", |row| &row.identity); + + let _table = client_cache.get_or_make_table::("player"); _table.add_unique_constraint::("id", |row| &row.id); + _table.add_unique_constraint::<__sdk::Identity>("identity", |row| &row.identity); } pub struct PlayerUpdateCallbackId(__sdk::CallbackId); @@ -102,75 +103,76 @@ impl<'ctx> __sdk::TableWithPrimaryKey for PlayerTableHandle<'ctx> { } } + #[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() + __sdk::InternalError::failed_parse( + "TableUpdate", + "TableUpdate", + ).with_cause(e).into() }) } -/// Access to the `identity` unique index on the table `player`, -/// which allows point queries on the field of the same name -/// via the [`PlayerIdentityUnique::find`] method. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.player().identity().find(...)`. -pub struct PlayerIdentityUnique<'ctx> { - imp: __sdk::UniqueConstraintHandle, - phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -impl<'ctx> PlayerTableHandle<'ctx> { - /// Get a handle on the `identity` unique index on the table `player`. - pub fn identity(&self) -> PlayerIdentityUnique<'ctx> { - PlayerIdentityUnique { - imp: self - .imp - .get_unique_constraint::<__sdk::Identity>("identity"), - phantom: std::marker::PhantomData, + /// Access to the `id` unique index on the table `player`, + /// which allows point queries on the field of the same name + /// via the [`PlayerIdUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.player().id().find(...)`. + pub struct PlayerIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, } - } -} -impl<'ctx> PlayerIdentityUnique<'ctx> { - /// Find the subscribed row whose `identity` column value is equal to `col_val`, - /// if such a row is present in the client cache. - pub fn find(&self, col_val: &__sdk::Identity) -> Option { - self.imp.find(col_val) - } -} - -/// Access to the `id` unique index on the table `player`, -/// which allows point queries on the field of the same name -/// via the [`PlayerIdUnique::find`] method. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.player().id().find(...)`. -pub struct PlayerIdUnique<'ctx> { - imp: __sdk::UniqueConstraintHandle, - phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -impl<'ctx> PlayerTableHandle<'ctx> { - /// Get a handle on the `id` unique index on the table `player`. - pub fn id(&self) -> PlayerIdUnique<'ctx> { - PlayerIdUnique { - imp: self.imp.get_unique_constraint::("id"), - phantom: std::marker::PhantomData, + impl<'ctx> PlayerTableHandle<'ctx> { + /// Get a handle on the `id` unique index on the table `player`. + pub fn id(&self) -> PlayerIdUnique<'ctx> { + PlayerIdUnique { + imp: self.imp.get_unique_constraint::("id"), + phantom: std::marker::PhantomData, + } + } } - } -} -impl<'ctx> PlayerIdUnique<'ctx> { - /// Find the subscribed row whose `id` column value is equal to `col_val`, - /// if such a row is present in the client cache. - pub fn find(&self, col_val: &u32) -> Option { - self.imp.find(col_val) - } -} + impl<'ctx> PlayerIdUnique<'ctx> { + /// Find the subscribed row whose `id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u32) -> Option { + self.imp.find(col_val) + } + } + + /// Access to the `identity` unique index on the table `player`, + /// which allows point queries on the field of the same name + /// via the [`PlayerIdentityUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.player().identity().find(...)`. + pub struct PlayerIdentityUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, + } + + impl<'ctx> PlayerTableHandle<'ctx> { + /// Get a handle on the `identity` unique index on the table `player`. + pub fn identity(&self) -> PlayerIdentityUnique<'ctx> { + PlayerIdentityUnique { + imp: self.imp.get_unique_constraint::<__sdk::Identity>("identity"), + phantom: std::marker::PhantomData, + } + } + } + + impl<'ctx> PlayerIdentityUnique<'ctx> { + /// Find the subscribed row whose `identity` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &__sdk::Identity) -> Option { + self.imp.find(col_val) + } + } + \ No newline at end of file diff --git a/jong-db/src/db/player_type.rs b/jong-db/src/db/player_type.rs index 582ca86..4e0df5a 100644 --- a/jong-db/src/db/player_type.rs +++ b/jong-db/src/db/player_type.rs @@ -2,24 +2,27 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; -use super::db_tile_type::DbTile; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct Player { - pub identity: __sdk::Identity, pub id: u32, - pub name: Option, + pub identity: __sdk::Identity, + pub name: Option::, pub lobby_id: u32, pub ready: bool, pub sort: bool, - pub hand: Vec, - pub pond: Vec, - pub drawn_tile: Option, } + impl __sdk::InModule for Player { type Module = super::RemoteModule; } + diff --git a/jong-db/src/db/rank_type.rs b/jong-db/src/db/rank_type.rs index 5b40b70..53c89f3 100644 --- a/jong-db/src/db/rank_type.rs +++ b/jong-db/src/db/rank_type.rs @@ -2,7 +2,13 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] @@ -10,6 +16,8 @@ pub struct Rank { pub number: u8, } + impl __sdk::InModule for Rank { type Module = super::RemoteModule; } + diff --git a/jong-db/src/db/set_ready_reducer.rs b/jong-db/src/db/set_ready_reducer.rs index bebd7cf..901b840 100644 --- a/jong-db/src/db/set_ready_reducer.rs +++ b/jong-db/src/db/set_ready_reducer.rs @@ -2,7 +2,13 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] @@ -12,8 +18,10 @@ pub(super) struct SetReadyArgs { impl From for super::Reducer { fn from(args: SetReadyArgs) -> Self { - Self::SetReady { ready: args.ready } - } + Self::SetReady { + ready: args.ready, +} +} } impl __sdk::InModule for SetReadyArgs { @@ -32,7 +40,8 @@ pub trait set_ready { /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and its status can be observed by listening for [`Self::on_set_ready`] callbacks. - fn set_ready(&self, ready: bool) -> __sdk::Result<()>; + fn set_ready(&self, ready: bool, +) -> __sdk::Result<()>; /// Register a callback to run whenever we are notified of an invocation of the reducer `set_ready`. /// /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] @@ -40,39 +49,35 @@ pub trait set_ready { /// /// The returned [`SetReadyCallbackId`] can be passed to [`Self::remove_on_set_ready`] /// to cancel the callback. - fn on_set_ready( - &self, - callback: impl FnMut(&super::ReducerEventContext, &bool) + Send + 'static, - ) -> SetReadyCallbackId; + fn on_set_ready(&self, callback: impl FnMut(&super::ReducerEventContext, &bool, ) + Send + 'static) -> SetReadyCallbackId; /// Cancel a callback previously registered by [`Self::on_set_ready`], /// causing it not to run in the future. fn remove_on_set_ready(&self, callback: SetReadyCallbackId); } impl set_ready for super::RemoteReducers { - fn set_ready(&self, ready: bool) -> __sdk::Result<()> { - self.imp.call_reducer("set_ready", SetReadyArgs { ready }) + fn set_ready(&self, ready: bool, +) -> __sdk::Result<()> { + self.imp.call_reducer("set_ready", SetReadyArgs { ready, }) } fn on_set_ready( &self, - mut callback: impl FnMut(&super::ReducerEventContext, &bool) + Send + 'static, + mut callback: impl FnMut(&super::ReducerEventContext, &bool, ) + Send + 'static, ) -> SetReadyCallbackId { SetReadyCallbackId(self.imp.on_reducer( "set_ready", Box::new(move |ctx: &super::ReducerEventContext| { #[allow(irrefutable_let_patterns)] let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::SetReady { ready }, - .. + event: __sdk::ReducerEvent { + reducer: super::Reducer::SetReady { + ready, }, + .. + }, .. - } = ctx - else { - unreachable!() - }; - callback(ctx, ready) + } = ctx else { unreachable!() }; + callback(ctx, ready, ) }), )) } @@ -100,3 +105,4 @@ impl set_flags_for_set_ready for super::SetReducerFlags { self.imp.set_call_reducer_flags("set_ready", flags); } } + diff --git a/jong-db/src/db/suit_type.rs b/jong-db/src/db/suit_type.rs index be17c21..53d5b31 100644 --- a/jong-db/src/db/suit_type.rs +++ b/jong-db/src/db/suit_type.rs @@ -2,11 +2,16 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; -use super::dragon_type::Dragon; use super::rank_type::Rank; use super::wind_type::Wind; +use super::dragon_type::Dragon; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] @@ -20,8 +25,12 @@ pub enum Suit { Wind(Wind), Dragon(Dragon), + } + + impl __sdk::InModule for Suit { type Module = super::RemoteModule; } + diff --git a/jong-db/src/db/tile_table.rs b/jong-db/src/db/tile_table.rs index 8d188eb..9075ccf 100644 --- a/jong-db/src/db/tile_table.rs +++ b/jong-db/src/db/tile_table.rs @@ -2,9 +2,14 @@ // 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, +}; use super::db_tile_type::DbTile; use super::tile_type::Tile; -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; /// Table handle for the table `tile`. /// @@ -45,12 +50,8 @@ impl<'ctx> __sdk::Table for TileTableHandle<'ctx> { type Row = DbTile; type EventContext = super::EventContext; - fn count(&self) -> u64 { - self.imp.count() - } - fn iter(&self) -> impl Iterator + '_ { - self.imp.iter() - } + fn count(&self) -> u64 { self.imp.count() } + fn iter(&self) -> impl Iterator + '_ { self.imp.iter() } type InsertCallbackId = TileInsertCallbackId; @@ -81,7 +82,8 @@ impl<'ctx> __sdk::Table for TileTableHandle<'ctx> { #[doc(hidden)] pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { - let _table = client_cache.get_or_make_table::("tile"); + + let _table = client_cache.get_or_make_table::("tile"); _table.add_unique_constraint::("id", |row| &row.id); } pub struct TileUpdateCallbackId(__sdk::CallbackId); @@ -101,43 +103,46 @@ impl<'ctx> __sdk::TableWithPrimaryKey for TileTableHandle<'ctx> { } } + #[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() + __sdk::InternalError::failed_parse( + "TableUpdate", + "TableUpdate", + ).with_cause(e).into() }) } -/// Access to the `id` unique index on the table `tile`, -/// which allows point queries on the field of the same name -/// via the [`TileIdUnique::find`] method. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.tile().id().find(...)`. -pub struct TileIdUnique<'ctx> { - imp: __sdk::UniqueConstraintHandle, - phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -impl<'ctx> TileTableHandle<'ctx> { - /// Get a handle on the `id` unique index on the table `tile`. - pub fn id(&self) -> TileIdUnique<'ctx> { - TileIdUnique { - imp: self.imp.get_unique_constraint::("id"), - phantom: std::marker::PhantomData, + /// Access to the `id` unique index on the table `tile`, + /// which allows point queries on the field of the same name + /// via the [`TileIdUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.tile().id().find(...)`. + pub struct TileIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, } - } -} -impl<'ctx> TileIdUnique<'ctx> { - /// Find the subscribed row whose `id` column value is equal to `col_val`, - /// if such a row is present in the client cache. - pub fn find(&self, col_val: &u32) -> Option { - self.imp.find(col_val) - } -} + impl<'ctx> TileTableHandle<'ctx> { + /// Get a handle on the `id` unique index on the table `tile`. + pub fn id(&self) -> TileIdUnique<'ctx> { + TileIdUnique { + imp: self.imp.get_unique_constraint::("id"), + phantom: std::marker::PhantomData, + } + } + } + + impl<'ctx> TileIdUnique<'ctx> { + /// Find the subscribed row whose `id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u32) -> Option { + self.imp.find(col_val) + } + } + \ No newline at end of file diff --git a/jong-db/src/db/tile_type.rs b/jong-db/src/db/tile_type.rs index 64b1919..6c56495 100644 --- a/jong-db/src/db/tile_type.rs +++ b/jong-db/src/db/tile_type.rs @@ -2,7 +2,12 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; use super::suit_type::Suit; @@ -12,6 +17,8 @@ pub struct Tile { pub suit: Suit, } + impl __sdk::InModule for Tile { type Module = super::RemoteModule; } + diff --git a/jong-db/src/db/turn_state_type.rs b/jong-db/src/db/turn_state_type.rs index e09ddbe..681e72c 100644 --- a/jong-db/src/db/turn_state_type.rs +++ b/jong-db/src/db/turn_state_type.rs @@ -2,7 +2,12 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] @@ -19,8 +24,12 @@ pub enum TurnState { RonChiiPonKan, End, + } + + impl __sdk::InModule for TurnState { type Module = super::RemoteModule; } + diff --git a/jong-db/src/db/wall_table.rs b/jong-db/src/db/wall_table.rs index 1f920d6..e9f4d46 100644 --- a/jong-db/src/db/wall_table.rs +++ b/jong-db/src/db/wall_table.rs @@ -2,9 +2,14 @@ // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. #![allow(unused, clippy::all)] -use super::db_tile_type::DbTile; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; use super::db_wall_type::DbWall; -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::db_tile_type::DbTile; /// Table handle for the table `wall`. /// @@ -45,12 +50,8 @@ impl<'ctx> __sdk::Table for WallTableHandle<'ctx> { type Row = DbWall; type EventContext = super::EventContext; - fn count(&self) -> u64 { - self.imp.count() - } - fn iter(&self) -> impl Iterator + '_ { - self.imp.iter() - } + fn count(&self) -> u64 { self.imp.count() } + fn iter(&self) -> impl Iterator + '_ { self.imp.iter() } type InsertCallbackId = WallInsertCallbackId; @@ -81,7 +82,8 @@ impl<'ctx> __sdk::Table for WallTableHandle<'ctx> { #[doc(hidden)] pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { - let _table = client_cache.get_or_make_table::("wall"); + + let _table = client_cache.get_or_make_table::("wall"); _table.add_unique_constraint::("lobby_id", |row| &row.lobby_id); } pub struct WallUpdateCallbackId(__sdk::CallbackId); @@ -101,43 +103,46 @@ impl<'ctx> __sdk::TableWithPrimaryKey for WallTableHandle<'ctx> { } } + #[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() + __sdk::InternalError::failed_parse( + "TableUpdate", + "TableUpdate", + ).with_cause(e).into() }) } -/// Access to the `lobby_id` unique index on the table `wall`, -/// which allows point queries on the field of the same name -/// via the [`WallLobbyIdUnique::find`] method. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.wall().lobby_id().find(...)`. -pub struct WallLobbyIdUnique<'ctx> { - imp: __sdk::UniqueConstraintHandle, - phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -impl<'ctx> WallTableHandle<'ctx> { - /// Get a handle on the `lobby_id` unique index on the table `wall`. - pub fn lobby_id(&self) -> WallLobbyIdUnique<'ctx> { - WallLobbyIdUnique { - imp: self.imp.get_unique_constraint::("lobby_id"), - phantom: std::marker::PhantomData, + /// Access to the `lobby_id` unique index on the table `wall`, + /// which allows point queries on the field of the same name + /// via the [`WallLobbyIdUnique::find`] method. + /// + /// Users are encouraged not to explicitly reference this type, + /// but to directly chain method calls, + /// like `ctx.db.wall().lobby_id().find(...)`. + pub struct WallLobbyIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, } - } -} -impl<'ctx> WallLobbyIdUnique<'ctx> { - /// Find the subscribed row whose `lobby_id` column value is equal to `col_val`, - /// if such a row is present in the client cache. - pub fn find(&self, col_val: &u32) -> Option { - self.imp.find(col_val) - } -} + impl<'ctx> WallTableHandle<'ctx> { + /// Get a handle on the `lobby_id` unique index on the table `wall`. + pub fn lobby_id(&self) -> WallLobbyIdUnique<'ctx> { + WallLobbyIdUnique { + imp: self.imp.get_unique_constraint::("lobby_id"), + phantom: std::marker::PhantomData, + } + } + } + + impl<'ctx> WallLobbyIdUnique<'ctx> { + /// Find the subscribed row whose `lobby_id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u32) -> Option { + self.imp.find(col_val) + } + } + \ No newline at end of file diff --git a/jong-db/src/db/wind_type.rs b/jong-db/src/db/wind_type.rs index a1c3965..8f9800c 100644 --- a/jong-db/src/db/wind_type.rs +++ b/jong-db/src/db/wind_type.rs @@ -2,7 +2,12 @@ // 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}; +use spacetimedb_sdk::__codegen::{ + self as __sdk, + __lib, + __sats, + __ws, +}; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] @@ -15,8 +20,12 @@ pub enum Wind { Shaa, Pei, + } + + impl __sdk::InModule for Wind { type Module = super::RemoteModule; } + diff --git a/jong-line/src/lib.rs b/jong-line/src/lib.rs index 28bf92a..adcca63 100644 --- a/jong-line/src/lib.rs +++ b/jong-line/src/lib.rs @@ -1,15 +1,9 @@ use log::debug; use spacetimedb::{ReducerContext, Table, reducer}; -use jong_types::TurnState; - use crate::tables::*; -mod reducers { - mod deal; - mod hand; - mod lobby; -} +mod reducers; mod tables; #[reducer] @@ -32,27 +26,40 @@ pub fn clear_all(ctx: &ReducerContext) { } #[reducer(client_connected)] -pub fn login_or_add_player(ctx: &ReducerContext) { - let identity = ctx.sender; - - // TODO remove player on disconnect - if let Ok(player) = ctx.db.player().try_insert(Player { - identity, - id: 0, - name: None, - lobby_id: 0, - ready: false, - sort: true, - hand: vec![], - pond: vec![], - drawn_tile: None, - turn_state: TurnState::None, - }) { - debug!("added player: {:?}", player); +pub fn connect(ctx: &ReducerContext) -> Result<(), String> { + let player = if let Some(player) = ctx.db.logged_out_player().identity().find(ctx.sender) { + let player = ctx.db.player().insert(player); + ctx.db.logged_out_player().identity().delete(ctx.sender); + player } else { - let player = ctx.db.player().identity().find(identity).unwrap(); - debug!("player {:?} has reconnected", player) - } + ctx.db.player().try_insert(Player { + identity: ctx.sender, + id: 0, + name: None, + lobby_id: 0, + ready: false, + sort: true, + })? + }; + + debug!("player connected: {:?}", player); + + Ok(()) +} + +#[reducer(client_disconnected)] +pub fn disconnect(ctx: &ReducerContext) -> Result<(), String> { + let player = ctx + .db + .player() + .identity() + .find(ctx.sender) + .ok_or_else(|| format!("can't find player {}", ctx.sender))?; + + ctx.db.logged_out_player().insert(player); + ctx.db.player().identity().delete(ctx.sender); + + Ok(()) } // #[reducer(init)] @@ -65,11 +72,6 @@ pub fn login_or_add_player(ctx: &ReducerContext) { // // Called everytime a new client connects // } -// #[reducer(client_disconnected)] -// pub fn identity_disconnected(_ctx: &ReducerContext) { -// // Called everytime a client disconnects -// } - // #[reducer] // pub fn add(ctx: &ReducerContext, name: String) { // ctx.db.player().insert(Player { name }); diff --git a/jong-line/src/reducers.rs b/jong-line/src/reducers.rs new file mode 100644 index 0000000..a9ce012 --- /dev/null +++ b/jong-line/src/reducers.rs @@ -0,0 +1,118 @@ +use std::time::Duration; + +use spacetimedb::{ReducerContext, ScheduleAt::Interval, reducer}; + +use jong_types::{GameState, TurnState}; + +use crate::{ + reducers::deal::shuffle_deal, + tables::{ + GameTimer, PlayerClock, PlayerOrBot, bot, game_timer, lobby as _, player_clock, + player_hand, wall, + }, +}; + +mod deal; +mod hand; +mod lobby; + +#[reducer] +pub fn advance_game(ctx: &ReducerContext, mut game_timer: GameTimer) -> Result<(), String> { + // checks every second (or more? when users make moves) on whether to advance the game's various states + // TODO this, or allow player/debug to call this? + if !ctx.sender_auth().is_internal() { + return Err("This reducer can only be called by the scheduler".to_string()); + } + + if let Some(mut lobby) = ctx.db.lobby().id().find(game_timer.lobby_id) { + match lobby.game_state { + GameState::Setup => { + // TODO reduce interval beforehand so we don't wait a second? + // TODO keep a count to clear stale lobbies + lobby.game_state = GameState::Deal; + } + GameState::Deal => { + // TODO reduce interval beforehand so this can animate? + shuffle_deal(ctx, lobby.id); + } + GameState::Play => { + let curr_player = lobby.players.get(lobby.current_idx as usize).unwrap(); + match curr_player { + PlayerOrBot::Player { id: player_id } => { + let mut clock = ctx.db.player_clock().player_id().find(player_id).unwrap(); + let mut hand = ctx.db.player_hand().player_id().find(player_id).unwrap(); + match hand.turn_state { + TurnState::None => { + // TODO draw tile + if let Some(mut wall) = ctx.db.wall().lobby_id().find(lobby.id) + && let Some(tile) = wall.tiles.pop() + { + hand.working_tile = Some(tile); + hand.turn_state = TurnState::Tsumo; + ctx.db.wall().lobby_id().update(wall); + ctx.db.player_hand().id().update(hand); + } else { + // TODO out of tiles + todo!() + } + } + TurnState::Tsumo => { + if clock.tick() { + ctx.db.player_clock().id().update(clock); + } else { + // TODO auto-discard + } + } + TurnState::Menzen => {} + TurnState::RiichiKan => {} + TurnState::RonChiiPonKan => {} + TurnState::End => {} + } + } + PlayerOrBot::Bot { id: bot_id } => { + let b = ctx.db.bot().id().find(bot_id).unwrap(); + } + } + } + GameState::Exit => { + ctx.db.game_timer().id().delete(game_timer.id); + ctx.db.lobby().id().delete(lobby.id); + // TODO reset all player lobbies, delete bots, etc? + // is there a way to do this automatically, or rely on elsewhere's checks clearing the state? + return Ok(()); + } + + // TODO handle stale lobbies + // TODO should this delete the timer? + _ => Err(format!("lobby {} in impossible state", lobby.id))?, + } + + ctx.db.game_timer().id().update(game_timer); + } else { + ctx.db.game_timer().id().delete(game_timer.id); + Err(format!( + "ran schedule {} for empty lobby {}", + game_timer.id, game_timer.lobby_id + ))?; + } + + Ok(()) +} + +impl PlayerClock { + fn tick(&mut self) -> bool { + if self.renewable > 0 { + self.renewable -= 1; + true + } else if self.total > 0 { + self.total -= 1; + true + } else { + false + } + } + + fn renew(&mut self) { + self.renewable = 5; + } +} diff --git a/jong-line/src/reducers/deal.rs b/jong-line/src/reducers/deal.rs index e6e280f..a82e78a 100644 --- a/jong-line/src/reducers/deal.rs +++ b/jong-line/src/reducers/deal.rs @@ -1,18 +1,13 @@ use log::debug; use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer}; -use super::hand::deal_hands; use crate::tables::*; -#[reducer] pub fn shuffle_deal(ctx: &ReducerContext, lobby_id: u32) { debug!("lobby_id: {lobby_id}"); let mut lobby = ctx.db.lobby().id().find(lobby_id).unwrap(); - if lobby.game_state == jong_types::states::GameState::Setup { - lobby.game_state = jong_types::states::GameState::Deal; - lobby = ctx.db.lobby().id().update(lobby); - + if lobby.game_state == jong_types::states::GameState::Deal { let tiles = new_shuffled_wall(ctx); ctx.db.wall().insert(DbWall { @@ -24,7 +19,6 @@ pub fn shuffle_deal(ctx: &ReducerContext, lobby_id: u32) { deal_hands(ctx, lobby_id); lobby.game_state = jong_types::states::GameState::Play; - lobby.turn_state = jong_types::states::TurnState::Tsumo; ctx.db.lobby().id().update(lobby); } } @@ -39,3 +33,32 @@ pub fn new_shuffled_wall(ctx: &ReducerContext) -> Vec { wall } + +pub fn deal_hands(ctx: &ReducerContext, lobby_id: u32) { + let players = ctx.db.player().lobby_id().filter(lobby_id); + let bots = ctx.db.bot().lobby_id().filter(lobby_id); + + let mut wall = ctx.db.wall().lobby_id().find(lobby_id).unwrap(); + + // FIXME rectify deal orders + for player in players { + let mut tiles = wall.tiles.split_off(wall.tiles.len() - 13); + wall = ctx.db.wall().lobby_id().update(wall); + tiles.sort_by_key(|t| t.tile); + ctx.db.player_hand().insert(PlayerHand { + id: 0, + player_id: player.id, + turn_state: jong_types::TurnState::None, + pond: vec![], + hand: tiles, + working_tile: None, + }); + } + for mut bot in bots { + let mut tiles = wall.tiles.split_off(wall.tiles.len() - 13); + wall = ctx.db.wall().lobby_id().update(wall); + tiles.sort_by_key(|t| t.tile); + bot.hand = tiles; + ctx.db.bot().id().update(bot); + } +} diff --git a/jong-line/src/reducers/hand.rs b/jong-line/src/reducers/hand.rs index 842926a..be7b48f 100644 --- a/jong-line/src/reducers/hand.rs +++ b/jong-line/src/reducers/hand.rs @@ -1,66 +1,27 @@ use log::{debug, trace}; use spacetimedb::{ReducerContext, reducer}; -use crate::tables::{player::player, *}; use jong_types::states::TurnState; -pub fn deal_hands(ctx: &ReducerContext, lobby_id: u32) { - let players = ctx.db.player().lobby_id().filter(lobby_id); - let bots = ctx.db.bot().lobby_id().filter(lobby_id); - - let mut wall = ctx.db.wall().lobby_id().find(lobby_id).unwrap(); - - // FIXME rectify deal orders - for mut player in players { - let mut tiles = wall.tiles.split_off(wall.tiles.len() - 13); - wall = ctx.db.wall().lobby_id().update(wall); - tiles.sort_by_key(|t| t.tile); - player.hand = tiles; - ctx.db.player().id().update(player); - } - for mut bot in bots { - let mut tiles = wall.tiles.split_off(wall.tiles.len() - 13); - wall = ctx.db.wall().lobby_id().update(wall); - tiles.sort_by_key(|t| t.tile); - bot.hand = tiles; - ctx.db.bot().id().update(bot); - } -} - -#[reducer] -pub fn draw_tile(ctx: &ReducerContext) { - let mut player = ctx.db.player().identity().find(ctx.sender).unwrap(); - let mut wall = ctx.db.wall().lobby_id().find(player.lobby_id).unwrap(); - - // TODO if no more tiles, exhaust somehow - - player.drawn_tile = wall.tiles.pop(); - - ctx.db.wall().lobby_id().update(wall); - ctx.db.player().id().update(player); -} +use crate::tables::*; // TODO make sure this can't be called or just error here? #[reducer] pub fn discard_tile(ctx: &ReducerContext, tile_id: u32) -> Result<(), String> { - let mut player = ctx.db.player().identity().find(ctx.sender).unwrap(); - let mut lobby = ctx.db.lobby().id().find(player.lobby_id).unwrap(); + let player = ctx.db.player().identity().find(ctx.sender).unwrap(); + let mut hand = ctx.db.player_hand().player_id().find(player.id).unwrap(); let dealt_tile = if let Some(dealt) = ctx.db.tile().id().find(tile_id) { - if let Some(drawn) = player.drawn_tile { + if let Some(drawn) = hand.working_tile { if drawn.id == dealt.id { // dealt from drawn tile dealt - } else if let Some((i, _)) = player - .hand - .iter() - .enumerate() - .find(|(_, t)| t.id == tile_id) + } else if let Some((i, _)) = hand.hand.iter().enumerate().find(|(_, t)| t.id == tile_id) { // dealt from hand - let dealt = player.hand.remove(i); - player.hand.push(drawn); - player.hand.sort_by_key(|t| t.tile); + let dealt = hand.hand.remove(i); + hand.hand.push(drawn); + hand.hand.sort_by_key(|t| t.tile); dealt } else { @@ -82,54 +43,53 @@ pub fn discard_tile(ctx: &ReducerContext, tile_id: u32) -> Result<(), String> { )); }; - player.pond.push(dealt_tile); - player.drawn_tile = None; - lobby.turn_state = TurnState::RonChiiPonKan; + hand.pond.push(dealt_tile); + hand.working_tile = None; + hand.turn_state = TurnState::None; - let player = ctx.db.player().id().update(player); - ctx.db.lobby().id().update(lobby); + ctx.db.player_hand().id().update(hand); debug!("player {} discarded tile {:?}", player.id, dealt_tile.tile); Ok(()) } -#[reducer] -pub fn skip_call(ctx: &ReducerContext) { - trace!("skip_call"); +// #[reducer] +// pub fn skip_call(ctx: &ReducerContext) { +// trace!("skip_call"); - let player = ctx.db.player().identity().find(ctx.sender).unwrap(); - let mut lobby = ctx.db.lobby().id().find(player.lobby_id).unwrap(); +// let player = ctx.db.player().identity().find(ctx.sender).unwrap(); +// let mut lobby = ctx.db.lobby().id().find(player.lobby_id).unwrap(); - lobby.turn_state = TurnState::Tsumo; - lobby.current_idx += 1; - if lobby.current_idx >= 3 { - lobby.current_idx = 0; - } +// lobby.turn_state = TurnState::Tsumo; +// lobby.current_idx += 1; +// if lobby.current_idx >= 3 { +// lobby.current_idx = 0; +// } - // FIXME where better can this go - bot_moves(ctx, &mut lobby); +// // FIXME where better can this go +// bot_moves(ctx, &mut lobby); - ctx.db.player().id().update(player); - ctx.db.lobby().id().update(lobby); -} +// ctx.db.player().id().update(player); +// ctx.db.lobby().id().update(lobby); +// } -fn bot_moves(ctx: &ReducerContext, lobby: &mut Lobby) { - let mut wall = ctx.db.wall().lobby_id().find(lobby.id).unwrap(); - if let Some(PlayerOrBot::Bot { id }) = lobby.players.get(lobby.current_idx as usize + 1) { - let mut bot = ctx.db.bot().id().find(id).unwrap(); - bot.pond.push(wall.tiles.pop().unwrap()); - ctx.db.bot().id().update(bot); - lobby.turn_state = TurnState::RonChiiPonKan; - } else { - lobby.turn_state = TurnState::Tsumo; - } +// fn bot_moves(ctx: &ReducerContext, lobby: &mut Lobby) { +// let mut wall = ctx.db.wall().lobby_id().find(lobby.id).unwrap(); +// if let Some(PlayerOrBot::Bot { id }) = lobby.players.get(lobby.current_idx as usize + 1) { +// let mut bot = ctx.db.bot().id().find(id).unwrap(); +// bot.pond.push(wall.tiles.pop().unwrap()); +// ctx.db.bot().id().update(bot); +// lobby.turn_state = TurnState::RonChiiPonKan; +// } else { +// lobby.turn_state = TurnState::Tsumo; +// } - lobby.current_idx += 1; - if lobby.current_idx >= 3 { - lobby.current_idx = 0; - } -} +// lobby.current_idx += 1; +// if lobby.current_idx >= 3 { +// lobby.current_idx = 0; +// } +// } // #[view(name = view_player_hand, public)] // pub fn view_player_hand(ctx: &ViewContext) -> Option { diff --git a/jong-line/src/reducers/lobby.rs b/jong-line/src/reducers/lobby.rs index f169dfc..b51aeac 100644 --- a/jong-line/src/reducers/lobby.rs +++ b/jong-line/src/reducers/lobby.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use log::info; use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer}; @@ -5,18 +7,16 @@ use crate::tables::*; #[reducer] pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<(), String> { - let ok_or = ctx + let mut player = ctx .db .player() .identity() .find(ctx.sender) .ok_or(format!("cannot find player {}", ctx.sender))?; - let mut player = ok_or; if lobby_id == 0 { let lobby = ctx.db.lobby().insert(Lobby { id: 0, - host_player_id: player.id, players: vec![PlayerOrBot::Player { id: player.id }], game_state: jong_types::states::GameState::Lobby, dealer_idx: 0, @@ -49,7 +49,8 @@ pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> { lobby_id, hand: vec![], pond: vec![], - drawn_tile: None, + working_tile: None, + turn_state: jong_types::TurnState::None, }); lobby.players.push(PlayerOrBot::Bot { id: bot.id }); ctx.db.lobby().id().update(lobby); @@ -61,29 +62,33 @@ pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> { } #[reducer] -pub fn set_ready(ctx: &ReducerContext, ready: bool) { +pub fn set_ready(ctx: &ReducerContext, ready: bool) -> Result<(), String> { let mut player = ctx.db.player().identity().find(ctx.sender).unwrap(); player.ready = ready; + player = ctx.db.player().identity().update(player); - ctx.db.player().identity().update(player); -} - -#[reducer] -pub fn start_game(ctx: &ReducerContext) { - let player = ctx.db.player().identity().find(ctx.sender).unwrap(); - if let Some(mut lobby) = ctx.db.lobby().host_player_id().find(player.id) + if let Some(mut lobby) = ctx.db.lobby().id().find(player.lobby_id) && lobby.players.len() == 4 - && lobby.players.iter().all(|p| match p { - PlayerOrBot::Player { id } => ctx.db.player().id().find(id).is_some_and(|p| p.ready), - PlayerOrBot::Bot { id } => ctx.db.bot().id().find(id).is_some(), - }) + && ctx.db.player().lobby_id().filter(lobby.id).all(|p| p.ready) { lobby.game_state = jong_types::states::GameState::Setup; lobby.players.shuffle(&mut ctx.rng()); - lobby.dealer_idx += 1; - if lobby.dealer_idx > 3 { - lobby.dealer_idx = 0; - } - ctx.db.lobby().id().update(lobby); + let lobby = ctx.db.lobby().id().update(lobby); + + // TODO should we schedule this outside so that we can clear out stale lobbies? + ctx.db.game_timer().insert(GameTimer { + id: 0, + lobby_id: lobby.id, + scheduled_at: spacetimedb::ScheduleAt::Interval(Duration::from_secs(1).into()), + }); + } else { + // if lobby doesn't exist, reset player state + player.lobby_id = 0; + player.ready = false; + player = ctx.db.player().identity().update(player); + + return Err(format!("couldn't find lobby with id: {}", player.lobby_id)); } + + Ok(()) } diff --git a/jong-line/src/tables.rs b/jong-line/src/tables.rs index 5939c67..a8ef7d5 100644 --- a/jong-line/src/tables.rs +++ b/jong-line/src/tables.rs @@ -1,3 +1,5 @@ +use std::time::Instant; + use spacetimedb::{SpacetimeType, table}; use jong_types::{ @@ -5,6 +7,8 @@ use jong_types::{ tiles::Tile, }; +use crate::reducers::advance_game; + #[derive(Debug, Clone)] #[table(name = lobby, public)] pub struct Lobby { @@ -12,8 +16,6 @@ pub struct Lobby { #[auto_inc] pub id: u32, - #[unique] - pub host_player_id: u32, pub players: Vec, pub dealer_idx: u8, pub current_idx: u8, @@ -45,41 +47,55 @@ pub enum PlayerOrBot { 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)] +#[table(name = logged_out_player)] #[derive(Debug)] pub struct Player { - #[primary_key] - pub identity: spacetimedb::Identity, - #[unique] #[auto_inc] pub id: u32, + #[primary_key] + pub identity: spacetimedb::Identity, + pub name: Option, #[index(btree)] pub lobby_id: u32, pub ready: bool, + pub sort: bool, +} + +#[table(name = player_clock, public)] +pub struct PlayerClock { + #[primary_key] + pub id: u32, + + #[unique] + pub player_id: u32, + + pub renewable: u16, + pub total: u16, +} + +#[table(name = player_hand)] +pub struct PlayerHand { + #[primary_key] + #[auto_inc] + pub id: u32, + + #[unique] + pub player_id: u32, + pub turn_state: TurnState, - pub sort: bool, - - pub hand: Vec, pub pond: Vec, + pub hand: Vec, - pub drawn_tile: Option, + /// drawn or callable tile + pub working_tile: Option, } #[table(name = bot)] @@ -91,8 +107,22 @@ pub struct Bot { #[index(btree)] pub lobby_id: u32, + pub turn_state: TurnState, + pub hand: Vec, pub pond: Vec, - pub drawn_tile: Option, + pub working_tile: Option, +} + +#[table(name = game_timer, scheduled(advance_game))] +pub struct GameTimer { + #[primary_key] + #[auto_inc] + pub id: u64, + + #[unique] + pub lobby_id: u32, + + pub scheduled_at: spacetimedb::ScheduleAt, } diff --git a/jong/src/riichi.rs b/jong/src/riichi.rs index 38afe95..c8aa7d7 100644 --- a/jong/src/riichi.rs +++ b/jong/src/riichi.rs @@ -4,7 +4,7 @@ use bevy_spacetimedb::{ }; use jong_db::{self, DbConnection, LobbyTableAccess, PlayerTableAccess, RemoteTables}; -use jong_db::{add_bot, draw_tile, set_ready, shuffle_deal, skip_call, start_game}; +use jong_db::{add_bot, set_ready}; use jong_types::*; pub mod player; @@ -121,7 +121,7 @@ fn on_player_insert_update( }; for msg in messages.read() { - match msg.new.turn_state { + /* match msg.new.turn_state { jong_db::TurnState::None => {} jong_db::TurnState::Tsumo => { stdb.reducers().draw_tile().unwrap(); @@ -171,7 +171,7 @@ fn on_player_insert_update( if let Some(dbt) = &msg.new.drawn_tile { debug!("drew tile with id: {}", dbt.id); commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id), Drawn)); - } + } */ } } @@ -205,12 +205,12 @@ fn on_lobby_insert_update( stdb.reducers().add_bot(player.lobby_id).unwrap(); } stdb.reducers().set_ready(true).unwrap(); - stdb.reducers().start_game().unwrap(); + // stdb.reducers().start_game().unwrap(); } } jong_db::GameState::Setup => { trace!("game entered setup"); - stdb.reducers().shuffle_deal(player.lobby_id).unwrap(); + // stdb.reducers().shuffle_deal(player.lobby_id).unwrap(); } jong_db::GameState::Deal => { trace!("game entered deal"); diff --git a/jong/src/tui/input/keyboard.rs b/jong/src/tui/input/keyboard.rs index be09002..91b8901 100644 --- a/jong/src/tui/input/keyboard.rs +++ b/jong/src/tui/input/keyboard.rs @@ -3,7 +3,6 @@ use bevy_ratatui::crossterm::event::KeyCode; use bevy_ratatui::event::KeyMessage; use jong_db::PlayerTableAccess; use jong_db::join_or_create_lobby; -use jong_db::start_game; use tui_logger::TuiWidgetEvent; use jong::SpacetimeDB;