Compare commits

..

No commits in common. "222459f828f05f2b693b3b1ace201310f532b95d" and "c12667938e350a7a719a6f34469e1022aaed1e4f" have entirely different histories.

43 changed files with 1290 additions and 2598 deletions

View file

@ -1,2 +1 @@
jong-db jong-db
bevy_spacetimedb

938
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -6,16 +6,16 @@ members = ["jong", "jong-types", "jong-line", "jong-db"]
jong = { version = "0.1.0", path = "jong" } jong = { version = "0.1.0", path = "jong" }
jong-types = { version = "0.1.0", path = "jong-types" } jong-types = { version = "0.1.0", path = "jong-types" }
bevy.version = "0.18" bevy.version = "0.17.3"
bevy.default-features = false bevy.default-features = false
bevy_ratatui = "0.11.1" bevy_ratatui = "0.10.0"
bevy_spacetimedb = "0.7" bevy_spacetimedb = "0.7"
spacetimedb.version = "1.12.*" spacetimedb.version = "1.11.*"
spacetimedb.features = ["unstable"] spacetimedb.features = ["unstable"]
spacetimedb-sdk = "1.12.*" spacetimedb-sdk = "1.11.*"
strum.version = "0.27.2" strum.version = "0.27.2"
strum.features = ["derive"] strum.features = ["derive"]
@ -35,4 +35,5 @@ opt-level = 1
opt-level = 3 opt-level = 3
[patch.crates-io] [patch.crates-io]
bevy_spacetimedb = { path = "bevy_spacetimedb/bevy_spacetimedb" } bevy_ratatui = { path = "/home/tao/clones/bevy_ratatui" }
# bevy_spacetimedb = { path = "/home/tao/clones/bevy_spacetimedb/bevy_spacetimedb" }

View file

@ -3,10 +3,10 @@
"devenv": { "devenv": {
"locked": { "locked": {
"dir": "src/modules", "dir": "src/modules",
"lastModified": 1771672827, "lastModified": 1771157881,
"owner": "cachix", "owner": "cachix",
"repo": "devenv", "repo": "devenv",
"rev": "6757a742f6393c7070f159eed9a59cbe20690aa3", "rev": "b0b3dfa70ec90fa49f672e579f186faf4f61bd4b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -125,10 +125,10 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1771729765, "lastModified": 1771211437,
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "be926cb1a76e8450ab2b92121b2e88d09fa4d41c", "rev": "c62195b3d6e1bb11e0c2fb2a494117d3b55d410f",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -18,13 +18,13 @@
# https://devenv.sh/packages/ # https://devenv.sh/packages/
packages = with pkgs; [ packages = with pkgs; [
lspmux # lspmux
pkg-config pkg-config
# spacetimedb # spacetimedb
openssl openssl
binaryen binaryen
# spacetimedb spacetimedb
# bevy Linux # bevy Linux
# Audio (Linux only) # Audio (Linux only)

View file

@ -1,107 +0,0 @@
// 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<AdvanceGameArgs> 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);
}
}

View file

@ -0,0 +1,144 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use super::advance_state_timer_type::AdvanceStateTimer;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// Table handle for the table `advance_state_timer`.
///
/// Obtain a handle from the [`AdvanceStateTimerTableAccess::advance_state_timer`] method on [`super::RemoteTables`],
/// like `ctx.db.advance_state_timer()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.advance_state_timer().on_insert(...)`.
pub struct AdvanceStateTimerTableHandle<'ctx> {
imp: __sdk::TableHandle<AdvanceStateTimer>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the table `advance_state_timer`.
///
/// Implemented for [`super::RemoteTables`].
pub trait AdvanceStateTimerTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`AdvanceStateTimerTableHandle`], which mediates access to the table `advance_state_timer`.
fn advance_state_timer(&self) -> AdvanceStateTimerTableHandle<'_>;
}
impl AdvanceStateTimerTableAccess for super::RemoteTables {
fn advance_state_timer(&self) -> AdvanceStateTimerTableHandle<'_> {
AdvanceStateTimerTableHandle {
imp: self
.imp
.get_table::<AdvanceStateTimer>("advance_state_timer"),
ctx: std::marker::PhantomData,
}
}
}
pub struct AdvanceStateTimerInsertCallbackId(__sdk::CallbackId);
pub struct AdvanceStateTimerDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::Table for AdvanceStateTimerTableHandle<'ctx> {
type Row = AdvanceStateTimer;
type EventContext = super::EventContext;
fn count(&self) -> u64 {
self.imp.count()
}
fn iter(&self) -> impl Iterator<Item = AdvanceStateTimer> + '_ {
self.imp.iter()
}
type InsertCallbackId = AdvanceStateTimerInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> AdvanceStateTimerInsertCallbackId {
AdvanceStateTimerInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: AdvanceStateTimerInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
type DeleteCallbackId = AdvanceStateTimerDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> AdvanceStateTimerDeleteCallbackId {
AdvanceStateTimerDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: AdvanceStateTimerDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
#[doc(hidden)]
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<AdvanceStateTimer>("advance_state_timer");
_table.add_unique_constraint::<u64>("scheduled_id", |row| &row.scheduled_id);
}
pub struct AdvanceStateTimerUpdateCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::TableWithPrimaryKey for AdvanceStateTimerTableHandle<'ctx> {
type UpdateCallbackId = AdvanceStateTimerUpdateCallbackId;
fn on_update(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
) -> AdvanceStateTimerUpdateCallbackId {
AdvanceStateTimerUpdateCallbackId(self.imp.on_update(Box::new(callback)))
}
fn remove_on_update(&self, callback: AdvanceStateTimerUpdateCallbackId) {
self.imp.remove_on_update(callback.0)
}
}
#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::TableUpdate<__ws::BsatnFormat>,
) -> __sdk::Result<__sdk::TableUpdate<AdvanceStateTimer>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<AdvanceStateTimer>", "TableUpdate")
.with_cause(e)
.into()
})
}
/// Access to the `scheduled_id` unique index on the table `advance_state_timer`,
/// which allows point queries on the field of the same name
/// via the [`AdvanceStateTimerScheduledIdUnique::find`] method.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.advance_state_timer().scheduled_id().find(...)`.
pub struct AdvanceStateTimerScheduledIdUnique<'ctx> {
imp: __sdk::UniqueConstraintHandle<AdvanceStateTimer, u64>,
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
impl<'ctx> AdvanceStateTimerTableHandle<'ctx> {
/// Get a handle on the `scheduled_id` unique index on the table `advance_state_timer`.
pub fn scheduled_id(&self) -> AdvanceStateTimerScheduledIdUnique<'ctx> {
AdvanceStateTimerScheduledIdUnique {
imp: self.imp.get_unique_constraint::<u64>("scheduled_id"),
phantom: std::marker::PhantomData,
}
}
}
impl<'ctx> AdvanceStateTimerScheduledIdUnique<'ctx> {
/// Find the subscribed row whose `scheduled_id` column value is equal to `col_val`,
/// if such a row is present in the client cache.
pub fn find(&self, col_val: &u64) -> Option<AdvanceStateTimer> {
self.imp.find(col_val)
}
}

View file

@ -0,0 +1,17 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct AdvanceStateTimer {
pub scheduled_id: u64,
pub scheduled_at: __sdk::ScheduleAt,
pub lobby_id: u32,
}
impl __sdk::InModule for AdvanceStateTimer {
type Module = super::RemoteModule;
}

View file

@ -4,7 +4,6 @@
#![allow(unused, clippy::all)] #![allow(unused, clippy::all)]
use super::bot_type::Bot; use super::bot_type::Bot;
use super::db_tile_type::DbTile; use super::db_tile_type::DbTile;
use super::turn_state_type::TurnState;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// Table handle for the table `bot`. /// Table handle for the table `bot`.
@ -142,19 +141,3 @@ impl<'ctx> BotIdUnique<'ctx> {
self.imp.find(col_val) self.imp.find(col_val)
} }
} }
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `Bot`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait botQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `Bot`.
fn bot(&self) -> __sdk::__query_builder::Table<Bot>;
}
impl botQueryTableAccess for __sdk::QueryTableAccessor {
fn bot(&self) -> __sdk::__query_builder::Table<Bot> {
__sdk::__query_builder::Table::new("bot")
}
}

View file

@ -5,63 +5,17 @@
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; use super::db_tile_type::DbTile;
use super::turn_state_type::TurnState;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)] #[sats(crate = __lib)]
pub struct Bot { pub struct Bot {
pub id: u32, pub id: u32,
pub lobby_id: u32, pub lobby_id: u32,
pub turn_state: TurnState,
pub hand: Vec<DbTile>, pub hand: Vec<DbTile>,
pub pond: Vec<DbTile>, pub pond: Vec<DbTile>,
pub working_tile: Option<DbTile>, pub drawn_tile: Option<DbTile>,
} }
impl __sdk::InModule for Bot { impl __sdk::InModule for Bot {
type Module = super::RemoteModule; type Module = super::RemoteModule;
} }
/// Column accessor struct for the table `Bot`.
///
/// Provides typed access to columns for query building.
pub struct BotCols {
pub id: __sdk::__query_builder::Col<Bot, u32>,
pub lobby_id: __sdk::__query_builder::Col<Bot, u32>,
pub turn_state: __sdk::__query_builder::Col<Bot, TurnState>,
pub hand: __sdk::__query_builder::Col<Bot, Vec<DbTile>>,
pub pond: __sdk::__query_builder::Col<Bot, Vec<DbTile>>,
pub working_tile: __sdk::__query_builder::Col<Bot, Option<DbTile>>,
}
impl __sdk::__query_builder::HasCols for Bot {
type Cols = BotCols;
fn cols(table_name: &'static str) -> Self::Cols {
BotCols {
id: __sdk::__query_builder::Col::new(table_name, "id"),
lobby_id: __sdk::__query_builder::Col::new(table_name, "lobby_id"),
turn_state: __sdk::__query_builder::Col::new(table_name, "turn_state"),
hand: __sdk::__query_builder::Col::new(table_name, "hand"),
pond: __sdk::__query_builder::Col::new(table_name, "pond"),
working_tile: __sdk::__query_builder::Col::new(table_name, "working_tile"),
}
}
}
/// Indexed column accessor struct for the table `Bot`.
///
/// Provides typed access to indexed columns for query building.
pub struct BotIxCols {
pub id: __sdk::__query_builder::IxCol<Bot, u32>,
pub lobby_id: __sdk::__query_builder::IxCol<Bot, u32>,
}
impl __sdk::__query_builder::HasIxCols for Bot {
type IxCols = BotIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
BotIxCols {
id: __sdk::__query_builder::IxCol::new(table_name, "id"),
lobby_id: __sdk::__query_builder::IxCol::new(table_name, "lobby_id"),
}
}
}

View file

@ -16,37 +16,3 @@ pub struct DbTile {
impl __sdk::InModule for DbTile { impl __sdk::InModule for DbTile {
type Module = super::RemoteModule; type Module = super::RemoteModule;
} }
/// Column accessor struct for the table `DbTile`.
///
/// Provides typed access to columns for query building.
pub struct DbTileCols {
pub id: __sdk::__query_builder::Col<DbTile, u32>,
pub tile: __sdk::__query_builder::Col<DbTile, Tile>,
}
impl __sdk::__query_builder::HasCols for DbTile {
type Cols = DbTileCols;
fn cols(table_name: &'static str) -> Self::Cols {
DbTileCols {
id: __sdk::__query_builder::Col::new(table_name, "id"),
tile: __sdk::__query_builder::Col::new(table_name, "tile"),
}
}
}
/// Indexed column accessor struct for the table `DbTile`.
///
/// Provides typed access to indexed columns for query building.
pub struct DbTileIxCols {
pub id: __sdk::__query_builder::IxCol<DbTile, u32>,
}
impl __sdk::__query_builder::HasIxCols for DbTile {
type IxCols = DbTileIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
DbTileIxCols {
id: __sdk::__query_builder::IxCol::new(table_name, "id"),
}
}
}

View file

@ -16,37 +16,3 @@ pub struct DbWall {
impl __sdk::InModule for DbWall { impl __sdk::InModule for DbWall {
type Module = super::RemoteModule; type Module = super::RemoteModule;
} }
/// Column accessor struct for the table `DbWall`.
///
/// Provides typed access to columns for query building.
pub struct DbWallCols {
pub lobby_id: __sdk::__query_builder::Col<DbWall, u32>,
pub tiles: __sdk::__query_builder::Col<DbWall, Vec<DbTile>>,
}
impl __sdk::__query_builder::HasCols for DbWall {
type Cols = DbWallCols;
fn cols(table_name: &'static str) -> Self::Cols {
DbWallCols {
lobby_id: __sdk::__query_builder::Col::new(table_name, "lobby_id"),
tiles: __sdk::__query_builder::Col::new(table_name, "tiles"),
}
}
}
/// Indexed column accessor struct for the table `DbWall`.
///
/// Provides typed access to indexed columns for query building.
pub struct DbWallIxCols {
pub lobby_id: __sdk::__query_builder::IxCol<DbWall, u32>,
}
impl __sdk::__query_builder::HasIxCols for DbWall {
type IxCols = DbWallIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
DbWallIxCols {
lobby_id: __sdk::__query_builder::IxCol::new(table_name, "lobby_id"),
}
}
}

View file

@ -6,63 +6,63 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)] #[sats(crate = __lib)]
pub(super) struct ConnectArgs {} pub(super) struct DrawTileArgs {}
impl From<ConnectArgs> for super::Reducer { impl From<DrawTileArgs> for super::Reducer {
fn from(args: ConnectArgs) -> Self { fn from(args: DrawTileArgs) -> Self {
Self::Connect Self::DrawTile
} }
} }
impl __sdk::InModule for ConnectArgs { impl __sdk::InModule for DrawTileArgs {
type Module = super::RemoteModule; type Module = super::RemoteModule;
} }
pub struct ConnectCallbackId(__sdk::CallbackId); pub struct DrawTileCallbackId(__sdk::CallbackId);
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
/// Extension trait for access to the reducer `connect`. /// Extension trait for access to the reducer `draw_tile`.
/// ///
/// Implemented for [`super::RemoteReducers`]. /// Implemented for [`super::RemoteReducers`].
pub trait connect { pub trait draw_tile {
/// Request that the remote module invoke the reducer `connect` to run as soon as possible. /// Request that the remote module invoke the reducer `draw_tile` to run as soon as possible.
/// ///
/// This method returns immediately, and errors only if we are unable to send the request. /// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future, /// The reducer will run asynchronously in the future,
/// and its status can be observed by listening for [`Self::on_connect`] callbacks. /// and its status can be observed by listening for [`Self::on_draw_tile`] callbacks.
fn connect(&self) -> __sdk::Result<()>; fn draw_tile(&self) -> __sdk::Result<()>;
/// Register a callback to run whenever we are notified of an invocation of the reducer `connect`. /// Register a callback to run whenever we are notified of an invocation of the reducer `draw_tile`.
/// ///
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
/// to determine the reducer's status. /// to determine the reducer's status.
/// ///
/// The returned [`ConnectCallbackId`] can be passed to [`Self::remove_on_connect`] /// The returned [`DrawTileCallbackId`] can be passed to [`Self::remove_on_draw_tile`]
/// to cancel the callback. /// to cancel the callback.
fn on_connect( fn on_draw_tile(
&self, &self,
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> ConnectCallbackId; ) -> DrawTileCallbackId;
/// Cancel a callback previously registered by [`Self::on_connect`], /// Cancel a callback previously registered by [`Self::on_draw_tile`],
/// causing it not to run in the future. /// causing it not to run in the future.
fn remove_on_connect(&self, callback: ConnectCallbackId); fn remove_on_draw_tile(&self, callback: DrawTileCallbackId);
} }
impl connect for super::RemoteReducers { impl draw_tile for super::RemoteReducers {
fn connect(&self) -> __sdk::Result<()> { fn draw_tile(&self) -> __sdk::Result<()> {
self.imp.call_reducer("connect", ConnectArgs {}) self.imp.call_reducer("draw_tile", DrawTileArgs {})
} }
fn on_connect( fn on_draw_tile(
&self, &self,
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> ConnectCallbackId { ) -> DrawTileCallbackId {
ConnectCallbackId(self.imp.on_reducer( DrawTileCallbackId(self.imp.on_reducer(
"connect", "draw_tile",
Box::new(move |ctx: &super::ReducerEventContext| { Box::new(move |ctx: &super::ReducerEventContext| {
#[allow(irrefutable_let_patterns)] #[allow(irrefutable_let_patterns)]
let super::ReducerEventContext { let super::ReducerEventContext {
event: event:
__sdk::ReducerEvent { __sdk::ReducerEvent {
reducer: super::Reducer::Connect {}, reducer: super::Reducer::DrawTile {},
.. ..
}, },
.. ..
@ -74,27 +74,27 @@ impl connect for super::RemoteReducers {
}), }),
)) ))
} }
fn remove_on_connect(&self, callback: ConnectCallbackId) { fn remove_on_draw_tile(&self, callback: DrawTileCallbackId) {
self.imp.remove_on_reducer("connect", callback.0) self.imp.remove_on_reducer("draw_tile", callback.0)
} }
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[doc(hidden)] #[doc(hidden)]
/// Extension trait for setting the call-flags for the reducer `connect`. /// Extension trait for setting the call-flags for the reducer `draw_tile`.
/// ///
/// Implemented for [`super::SetReducerFlags`]. /// Implemented for [`super::SetReducerFlags`].
/// ///
/// This type is currently unstable and may be removed without a major version bump. /// This type is currently unstable and may be removed without a major version bump.
pub trait set_flags_for_connect { pub trait set_flags_for_draw_tile {
/// Set the call-reducer flags for the reducer `connect` to `flags`. /// Set the call-reducer flags for the reducer `draw_tile` to `flags`.
/// ///
/// This type is currently unstable and may be removed without a major version bump. /// This type is currently unstable and may be removed without a major version bump.
fn connect(&self, flags: __ws::CallReducerFlags); fn draw_tile(&self, flags: __ws::CallReducerFlags);
} }
impl set_flags_for_connect for super::SetReducerFlags { impl set_flags_for_draw_tile for super::SetReducerFlags {
fn connect(&self, flags: __ws::CallReducerFlags) { fn draw_tile(&self, flags: __ws::CallReducerFlags) {
self.imp.set_call_reducer_flags("connect", flags); self.imp.set_call_reducer_flags("draw_tile", flags);
} }
} }

View file

@ -1,189 +0,0 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use super::game_timer_type::GameTimer;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// 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<GameTimer>,
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::<GameTimer>("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<Item = GameTimer> + '_ {
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<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<GameTimer>("game_timer");
_table.add_unique_constraint::<u64>("id", |row| &row.id);
_table.add_unique_constraint::<u32>("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<GameTimer>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<GameTimer>", "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<GameTimer, u64>,
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::<u64>("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<GameTimer> {
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<GameTimer, u32>,
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::<u32>("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<GameTimer> {
self.imp.find(col_val)
}
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `GameTimer`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait game_timerQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `GameTimer`.
fn game_timer(&self) -> __sdk::__query_builder::Table<GameTimer>;
}
impl game_timerQueryTableAccess for __sdk::QueryTableAccessor {
fn game_timer(&self) -> __sdk::__query_builder::Table<GameTimer> {
__sdk::__query_builder::Table::new("game_timer")
}
}

View file

@ -1,55 +0,0 @@
// 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;
}
/// Column accessor struct for the table `GameTimer`.
///
/// Provides typed access to columns for query building.
pub struct GameTimerCols {
pub id: __sdk::__query_builder::Col<GameTimer, u64>,
pub lobby_id: __sdk::__query_builder::Col<GameTimer, u32>,
pub scheduled_at: __sdk::__query_builder::Col<GameTimer, __sdk::ScheduleAt>,
}
impl __sdk::__query_builder::HasCols for GameTimer {
type Cols = GameTimerCols;
fn cols(table_name: &'static str) -> Self::Cols {
GameTimerCols {
id: __sdk::__query_builder::Col::new(table_name, "id"),
lobby_id: __sdk::__query_builder::Col::new(table_name, "lobby_id"),
scheduled_at: __sdk::__query_builder::Col::new(table_name, "scheduled_at"),
}
}
}
/// Indexed column accessor struct for the table `GameTimer`.
///
/// Provides typed access to indexed columns for query building.
pub struct GameTimerIxCols {
pub id: __sdk::__query_builder::IxCol<GameTimer, u64>,
pub lobby_id: __sdk::__query_builder::IxCol<GameTimer, u32>,
}
impl __sdk::__query_builder::HasIxCols for GameTimer {
type IxCols = GameTimerIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
GameTimerIxCols {
id: __sdk::__query_builder::IxCol::new(table_name, "id"),
lobby_id: __sdk::__query_builder::IxCol::new(table_name, "lobby_id"),
}
}
}

View file

@ -5,6 +5,7 @@
use super::game_state_type::GameState; use super::game_state_type::GameState;
use super::lobby_type::Lobby; use super::lobby_type::Lobby;
use super::player_or_bot_type::PlayerOrBot; use super::player_or_bot_type::PlayerOrBot;
use super::turn_state_type::TurnState;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// Table handle for the table `lobby`. /// Table handle for the table `lobby`.
@ -84,6 +85,7 @@ impl<'ctx> __sdk::Table for LobbyTableHandle<'ctx> {
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) { pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<Lobby>("lobby"); let _table = client_cache.get_or_make_table::<Lobby>("lobby");
_table.add_unique_constraint::<u32>("id", |row| &row.id); _table.add_unique_constraint::<u32>("id", |row| &row.id);
_table.add_unique_constraint::<u32>("host_player_id", |row| &row.host_player_id);
} }
pub struct LobbyUpdateCallbackId(__sdk::CallbackId); pub struct LobbyUpdateCallbackId(__sdk::CallbackId);
@ -143,18 +145,32 @@ impl<'ctx> LobbyIdUnique<'ctx> {
} }
} }
#[allow(non_camel_case_types)] /// Access to the `host_player_id` unique index on the table `lobby`,
/// Extension trait for query builder access to the table `Lobby`. /// which allows point queries on the field of the same name
/// via the [`LobbyHostPlayerIdUnique::find`] method.
/// ///
/// Implemented for [`__sdk::QueryTableAccessor`]. /// Users are encouraged not to explicitly reference this type,
pub trait lobbyQueryTableAccess { /// but to directly chain method calls,
#[allow(non_snake_case)] /// like `ctx.db.lobby().host_player_id().find(...)`.
/// Get a query builder for the table `Lobby`. pub struct LobbyHostPlayerIdUnique<'ctx> {
fn lobby(&self) -> __sdk::__query_builder::Table<Lobby>; imp: __sdk::UniqueConstraintHandle<Lobby, u32>,
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
} }
impl lobbyQueryTableAccess for __sdk::QueryTableAccessor { impl<'ctx> LobbyTableHandle<'ctx> {
fn lobby(&self) -> __sdk::__query_builder::Table<Lobby> { /// Get a handle on the `host_player_id` unique index on the table `lobby`.
__sdk::__query_builder::Table::new("lobby") pub fn host_player_id(&self) -> LobbyHostPlayerIdUnique<'ctx> {
LobbyHostPlayerIdUnique {
imp: self.imp.get_unique_constraint::<u32>("host_player_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<Lobby> {
self.imp.find(col_val)
} }
} }

View file

@ -6,57 +6,20 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::game_state_type::GameState; use super::game_state_type::GameState;
use super::player_or_bot_type::PlayerOrBot; use super::player_or_bot_type::PlayerOrBot;
use super::turn_state_type::TurnState;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)] #[sats(crate = __lib)]
pub struct Lobby { pub struct Lobby {
pub id: u32, pub id: u32,
pub host_player_id: u32,
pub players: Vec<PlayerOrBot>, pub players: Vec<PlayerOrBot>,
pub dealer_idx: u8, pub dealer_idx: u8,
pub current_idx: u8, pub current_idx: u8,
pub game_state: GameState, pub game_state: GameState,
pub turn_state: TurnState,
} }
impl __sdk::InModule for Lobby { impl __sdk::InModule for Lobby {
type Module = super::RemoteModule; type Module = super::RemoteModule;
} }
/// Column accessor struct for the table `Lobby`.
///
/// Provides typed access to columns for query building.
pub struct LobbyCols {
pub id: __sdk::__query_builder::Col<Lobby, u32>,
pub players: __sdk::__query_builder::Col<Lobby, Vec<PlayerOrBot>>,
pub dealer_idx: __sdk::__query_builder::Col<Lobby, u8>,
pub current_idx: __sdk::__query_builder::Col<Lobby, u8>,
pub game_state: __sdk::__query_builder::Col<Lobby, GameState>,
}
impl __sdk::__query_builder::HasCols for Lobby {
type Cols = LobbyCols;
fn cols(table_name: &'static str) -> Self::Cols {
LobbyCols {
id: __sdk::__query_builder::Col::new(table_name, "id"),
players: __sdk::__query_builder::Col::new(table_name, "players"),
dealer_idx: __sdk::__query_builder::Col::new(table_name, "dealer_idx"),
current_idx: __sdk::__query_builder::Col::new(table_name, "current_idx"),
game_state: __sdk::__query_builder::Col::new(table_name, "game_state"),
}
}
}
/// Indexed column accessor struct for the table `Lobby`.
///
/// Provides typed access to indexed columns for query building.
pub struct LobbyIxCols {
pub id: __sdk::__query_builder::IxCol<Lobby, u32>,
}
impl __sdk::__query_builder::HasIxCols for Lobby {
type IxCols = LobbyIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
LobbyIxCols {
id: __sdk::__query_builder::IxCol::new(table_name, "id"),
}
}
}

View file

@ -1,191 +0,0 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use super::player_type::Player;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// 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<Player>,
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::<Player>("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<Item = Player> + '_ {
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<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<Player>("logged_out_player");
_table.add_unique_constraint::<u32>("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<Player>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<Player>", "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<Player, u32>,
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::<u32>("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<Player> {
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<Player, __sdk::Identity>,
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<Player> {
self.imp.find(col_val)
}
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `Player`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait logged_out_playerQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `Player`.
fn logged_out_player(&self) -> __sdk::__query_builder::Table<Player>;
}
impl logged_out_playerQueryTableAccess for __sdk::QueryTableAccessor {
fn logged_out_player(&self) -> __sdk::__query_builder::Table<Player> {
__sdk::__query_builder::Table::new("logged_out_player")
}
}

View file

@ -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 LoginOrAddPlayerArgs {}
impl From<LoginOrAddPlayerArgs> for super::Reducer {
fn from(args: LoginOrAddPlayerArgs) -> Self {
Self::LoginOrAddPlayer
}
}
impl __sdk::InModule for LoginOrAddPlayerArgs {
type Module = super::RemoteModule;
}
pub struct LoginOrAddPlayerCallbackId(__sdk::CallbackId);
#[allow(non_camel_case_types)]
/// Extension trait for access to the reducer `login_or_add_player`.
///
/// Implemented for [`super::RemoteReducers`].
pub trait login_or_add_player {
/// Request that the remote module invoke the reducer `login_or_add_player` 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_login_or_add_player`] callbacks.
fn login_or_add_player(&self) -> __sdk::Result<()>;
/// Register a callback to run whenever we are notified of an invocation of the reducer `login_or_add_player`.
///
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
/// to determine the reducer's status.
///
/// The returned [`LoginOrAddPlayerCallbackId`] can be passed to [`Self::remove_on_login_or_add_player`]
/// to cancel the callback.
fn on_login_or_add_player(
&self,
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> LoginOrAddPlayerCallbackId;
/// Cancel a callback previously registered by [`Self::on_login_or_add_player`],
/// causing it not to run in the future.
fn remove_on_login_or_add_player(&self, callback: LoginOrAddPlayerCallbackId);
}
impl login_or_add_player for super::RemoteReducers {
fn login_or_add_player(&self) -> __sdk::Result<()> {
self.imp
.call_reducer("login_or_add_player", LoginOrAddPlayerArgs {})
}
fn on_login_or_add_player(
&self,
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> LoginOrAddPlayerCallbackId {
LoginOrAddPlayerCallbackId(self.imp.on_reducer(
"login_or_add_player",
Box::new(move |ctx: &super::ReducerEventContext| {
#[allow(irrefutable_let_patterns)]
let super::ReducerEventContext {
event:
__sdk::ReducerEvent {
reducer: super::Reducer::LoginOrAddPlayer {},
..
},
..
} = ctx
else {
unreachable!()
};
callback(ctx)
}),
))
}
fn remove_on_login_or_add_player(&self, callback: LoginOrAddPlayerCallbackId) {
self.imp
.remove_on_reducer("login_or_add_player", callback.0)
}
}
#[allow(non_camel_case_types)]
#[doc(hidden)]
/// Extension trait for setting the call-flags for the reducer `login_or_add_player`.
///
/// Implemented for [`super::SetReducerFlags`].
///
/// This type is currently unstable and may be removed without a major version bump.
pub trait set_flags_for_login_or_add_player {
/// Set the call-reducer flags for the reducer `login_or_add_player` to `flags`.
///
/// This type is currently unstable and may be removed without a major version bump.
fn login_or_add_player(&self, flags: __ws::CallReducerFlags);
}
impl set_flags_for_login_or_add_player for super::SetReducerFlags {
fn login_or_add_player(&self, flags: __ws::CallReducerFlags) {
self.imp
.set_call_reducer_flags("login_or_add_player", flags);
}
}

View file

@ -1,80 +1,74 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
// This was generated using spacetimedb cli version 1.12.0 (commit 4fdb8d923f39ed592931ad4c7e6391ed99b9fe3a). // This was generated using spacetimedb cli version 1.11.3 (commit 02449737ca3b29e7e39679fccbef541a50f32094).
#![allow(unused, clippy::all)] #![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
pub mod add_bot_reducer; pub mod add_bot_reducer;
pub mod advance_game_reducer; pub mod advance_state_timer_table;
pub mod advance_state_timer_type;
pub mod bot_table; pub mod bot_table;
pub mod bot_type; pub mod bot_type;
pub mod clear_all_reducer; pub mod clear_all_reducer;
pub mod connect_reducer;
pub mod db_tile_type; pub mod db_tile_type;
pub mod db_wall_type; pub mod db_wall_type;
pub mod discard_tile_reducer; pub mod discard_tile_reducer;
pub mod disconnect_reducer;
pub mod dragon_type; pub mod dragon_type;
pub mod draw_tile_reducer;
pub mod game_state_type; pub mod game_state_type;
pub mod game_timer_table;
pub mod game_timer_type;
pub mod join_or_create_lobby_reducer; pub mod join_or_create_lobby_reducer;
pub mod lobby_table; pub mod lobby_table;
pub mod lobby_type; pub mod lobby_type;
pub mod logged_out_player_table; pub mod login_or_add_player_reducer;
pub mod player_clock_table;
pub mod player_clock_type;
pub mod player_hand_table;
pub mod player_hand_type;
pub mod player_or_bot_type; pub mod player_or_bot_type;
pub mod player_table; pub mod player_table;
pub mod player_type; pub mod player_type;
pub mod rank_type; pub mod rank_type;
pub mod set_ready_reducer; 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 suit_type;
pub mod tile_table; pub mod tile_table;
pub mod tile_type; pub mod tile_type;
pub mod turn_state_type; pub mod turn_state_type;
pub mod view_hand_table;
pub mod wall_table; pub mod wall_table;
pub mod wind_type; pub mod wind_type;
pub use add_bot_reducer::{add_bot, set_flags_for_add_bot, AddBotCallbackId}; 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 advance_state_timer_table::*;
pub use advance_state_timer_type::AdvanceStateTimer;
pub use bot_table::*; pub use bot_table::*;
pub use bot_type::Bot; pub use bot_type::Bot;
pub use clear_all_reducer::{clear_all, set_flags_for_clear_all, ClearAllCallbackId}; 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 db_tile_type::DbTile; pub use db_tile_type::DbTile;
pub use db_wall_type::DbWall; pub use db_wall_type::DbWall;
pub use discard_tile_reducer::{discard_tile, set_flags_for_discard_tile, DiscardTileCallbackId}; 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 dragon_type::Dragon; 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 game_state_type::GameState;
pub use game_timer_table::*;
pub use game_timer_type::GameTimer;
pub use join_or_create_lobby_reducer::{ pub use join_or_create_lobby_reducer::{
join_or_create_lobby, set_flags_for_join_or_create_lobby, JoinOrCreateLobbyCallbackId, join_or_create_lobby, set_flags_for_join_or_create_lobby, JoinOrCreateLobbyCallbackId,
}; };
pub use lobby_table::*; pub use lobby_table::*;
pub use lobby_type::Lobby; pub use lobby_type::Lobby;
pub use logged_out_player_table::*; pub use login_or_add_player_reducer::{
pub use player_clock_table::*; login_or_add_player, set_flags_for_login_or_add_player, LoginOrAddPlayerCallbackId,
pub use player_clock_type::PlayerClock; };
pub use player_hand_table::*;
pub use player_hand_type::PlayerHand;
pub use player_or_bot_type::PlayerOrBot; pub use player_or_bot_type::PlayerOrBot;
pub use player_table::*; pub use player_table::*;
pub use player_type::Player; pub use player_type::Player;
pub use rank_type::Rank; pub use rank_type::Rank;
pub use set_ready_reducer::{set_flags_for_set_ready, set_ready, SetReadyCallbackId}; 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 suit_type::Suit;
pub use tile_table::*; pub use tile_table::*;
pub use tile_type::Tile; pub use tile_type::Tile;
pub use turn_state_type::TurnState; pub use turn_state_type::TurnState;
pub use view_hand_table::*;
pub use wall_table::*; pub use wall_table::*;
pub use wind_type::Wind; pub use wind_type::Wind;
@ -87,13 +81,15 @@ pub use wind_type::Wind;
pub enum Reducer { pub enum Reducer {
AddBot { lobby_id: u32 }, AddBot { lobby_id: u32 },
AdvanceGame { game_timer: GameTimer },
ClearAll, ClearAll,
Connect,
DiscardTile { tile_id: u32 }, DiscardTile { tile_id: u32 },
Disconnect, DrawTile,
JoinOrCreateLobby { lobby_id: u32 }, JoinOrCreateLobby { lobby_id: u32 },
LoginOrAddPlayer,
SetReady { ready: bool }, SetReady { ready: bool },
ShuffleDeal { lobby_id: u32 },
SkipCall,
StartGame,
} }
impl __sdk::InModule for Reducer { impl __sdk::InModule for Reducer {
@ -104,13 +100,15 @@ impl __sdk::Reducer for Reducer {
fn reducer_name(&self) -> &'static str { fn reducer_name(&self) -> &'static str {
match self { match self {
Reducer::AddBot { .. } => "add_bot", Reducer::AddBot { .. } => "add_bot",
Reducer::AdvanceGame { .. } => "advance_game",
Reducer::ClearAll => "clear_all", Reducer::ClearAll => "clear_all",
Reducer::Connect => "connect",
Reducer::DiscardTile { .. } => "discard_tile", Reducer::DiscardTile { .. } => "discard_tile",
Reducer::Disconnect => "disconnect", Reducer::DrawTile => "draw_tile",
Reducer::JoinOrCreateLobby { .. } => "join_or_create_lobby", Reducer::JoinOrCreateLobby { .. } => "join_or_create_lobby",
Reducer::LoginOrAddPlayer => "login_or_add_player",
Reducer::SetReady { .. } => "set_ready", Reducer::SetReady { .. } => "set_ready",
Reducer::ShuffleDeal { .. } => "shuffle_deal",
Reducer::SkipCall => "skip_call",
Reducer::StartGame => "start_game",
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -124,13 +122,6 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer {
&value.args, &value.args,
)? )?
.into()), .into()),
"advance_game" => Ok(
__sdk::parse_reducer_args::<advance_game_reducer::AdvanceGameArgs>(
"advance_game",
&value.args,
)?
.into(),
),
"clear_all" => Ok( "clear_all" => Ok(
__sdk::parse_reducer_args::<clear_all_reducer::ClearAllArgs>( __sdk::parse_reducer_args::<clear_all_reducer::ClearAllArgs>(
"clear_all", "clear_all",
@ -138,11 +129,6 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer {
)? )?
.into(), .into(),
), ),
"connect" => Ok(__sdk::parse_reducer_args::<connect_reducer::ConnectArgs>(
"connect",
&value.args,
)?
.into()),
"discard_tile" => Ok( "discard_tile" => Ok(
__sdk::parse_reducer_args::<discard_tile_reducer::DiscardTileArgs>( __sdk::parse_reducer_args::<discard_tile_reducer::DiscardTileArgs>(
"discard_tile", "discard_tile",
@ -150,9 +136,9 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer {
)? )?
.into(), .into(),
), ),
"disconnect" => Ok( "draw_tile" => Ok(
__sdk::parse_reducer_args::<disconnect_reducer::DisconnectArgs>( __sdk::parse_reducer_args::<draw_tile_reducer::DrawTileArgs>(
"disconnect", "draw_tile",
&value.args, &value.args,
)? )?
.into(), .into(),
@ -161,6 +147,10 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer {
join_or_create_lobby_reducer::JoinOrCreateLobbyArgs, join_or_create_lobby_reducer::JoinOrCreateLobbyArgs,
>("join_or_create_lobby", &value.args)? >("join_or_create_lobby", &value.args)?
.into()), .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( "set_ready" => Ok(
__sdk::parse_reducer_args::<set_ready_reducer::SetReadyArgs>( __sdk::parse_reducer_args::<set_ready_reducer::SetReadyArgs>(
"set_ready", "set_ready",
@ -168,6 +158,27 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer {
)? )?
.into(), .into(),
), ),
"shuffle_deal" => Ok(
__sdk::parse_reducer_args::<shuffle_deal_reducer::ShuffleDealArgs>(
"shuffle_deal",
&value.args,
)?
.into(),
),
"skip_call" => Ok(
__sdk::parse_reducer_args::<skip_call_reducer::SkipCallArgs>(
"skip_call",
&value.args,
)?
.into(),
),
"start_game" => Ok(
__sdk::parse_reducer_args::<start_game_reducer::StartGameArgs>(
"start_game",
&value.args,
)?
.into(),
),
unknown => { unknown => {
Err( Err(
__sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo") __sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo")
@ -182,15 +193,11 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer {
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[doc(hidden)] #[doc(hidden)]
pub struct DbUpdate { pub struct DbUpdate {
advance_state_timer: __sdk::TableUpdate<AdvanceStateTimer>,
bot: __sdk::TableUpdate<Bot>, bot: __sdk::TableUpdate<Bot>,
game_timer: __sdk::TableUpdate<GameTimer>,
lobby: __sdk::TableUpdate<Lobby>, lobby: __sdk::TableUpdate<Lobby>,
logged_out_player: __sdk::TableUpdate<Player>,
player: __sdk::TableUpdate<Player>, player: __sdk::TableUpdate<Player>,
player_clock: __sdk::TableUpdate<PlayerClock>,
player_hand: __sdk::TableUpdate<PlayerHand>,
tile: __sdk::TableUpdate<DbTile>, tile: __sdk::TableUpdate<DbTile>,
view_hand: __sdk::TableUpdate<PlayerHand>,
wall: __sdk::TableUpdate<DbWall>, wall: __sdk::TableUpdate<DbWall>,
} }
@ -200,33 +207,21 @@ impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate {
let mut db_update = DbUpdate::default(); let mut db_update = DbUpdate::default();
for table_update in raw.tables { for table_update in raw.tables {
match &table_update.table_name[..] { 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" => db_update
.bot .bot
.append(bot_table::parse_table_update(table_update)?), .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" => db_update
.lobby .lobby
.append(lobby_table::parse_table_update(table_update)?), .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" => db_update
.player .player
.append(player_table::parse_table_update(table_update)?), .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" => db_update
.tile .tile
.append(tile_table::parse_table_update(table_update)?), .append(tile_table::parse_table_update(table_update)?),
"view_hand" => db_update
.view_hand
.append(view_hand_table::parse_table_update(table_update)?),
"wall" => db_update "wall" => db_update
.wall .wall
.append(wall_table::parse_table_update(table_update)?), .append(wall_table::parse_table_update(table_update)?),
@ -256,34 +251,27 @@ impl __sdk::DbUpdate for DbUpdate {
) -> AppliedDiff<'_> { ) -> AppliedDiff<'_> {
let mut diff = AppliedDiff::default(); let mut diff = AppliedDiff::default();
diff.advance_state_timer = cache
.apply_diff_to_table::<AdvanceStateTimer>(
"advance_state_timer",
&self.advance_state_timer,
)
.with_updates_by_pk(|row| &row.scheduled_id);
diff.bot = cache diff.bot = cache
.apply_diff_to_table::<Bot>("bot", &self.bot) .apply_diff_to_table::<Bot>("bot", &self.bot)
.with_updates_by_pk(|row| &row.id); .with_updates_by_pk(|row| &row.id);
diff.game_timer = cache
.apply_diff_to_table::<GameTimer>("game_timer", &self.game_timer)
.with_updates_by_pk(|row| &row.id);
diff.lobby = cache diff.lobby = cache
.apply_diff_to_table::<Lobby>("lobby", &self.lobby) .apply_diff_to_table::<Lobby>("lobby", &self.lobby)
.with_updates_by_pk(|row| &row.id); .with_updates_by_pk(|row| &row.id);
diff.logged_out_player = cache
.apply_diff_to_table::<Player>("logged_out_player", &self.logged_out_player)
.with_updates_by_pk(|row| &row.identity);
diff.player = cache diff.player = cache
.apply_diff_to_table::<Player>("player", &self.player) .apply_diff_to_table::<Player>("player", &self.player)
.with_updates_by_pk(|row| &row.identity); .with_updates_by_pk(|row| &row.identity);
diff.player_clock = cache
.apply_diff_to_table::<PlayerClock>("player_clock", &self.player_clock)
.with_updates_by_pk(|row| &row.id);
diff.player_hand = cache
.apply_diff_to_table::<PlayerHand>("player_hand", &self.player_hand)
.with_updates_by_pk(|row| &row.id);
diff.tile = cache diff.tile = cache
.apply_diff_to_table::<DbTile>("tile", &self.tile) .apply_diff_to_table::<DbTile>("tile", &self.tile)
.with_updates_by_pk(|row| &row.id); .with_updates_by_pk(|row| &row.id);
diff.wall = cache diff.wall = cache
.apply_diff_to_table::<DbWall>("wall", &self.wall) .apply_diff_to_table::<DbWall>("wall", &self.wall)
.with_updates_by_pk(|row| &row.lobby_id); .with_updates_by_pk(|row| &row.lobby_id);
diff.view_hand = cache.apply_diff_to_table::<PlayerHand>("view_hand", &self.view_hand);
diff diff
} }
@ -293,15 +281,11 @@ impl __sdk::DbUpdate for DbUpdate {
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[doc(hidden)] #[doc(hidden)]
pub struct AppliedDiff<'r> { 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>, lobby: __sdk::TableAppliedDiff<'r, Lobby>,
logged_out_player: __sdk::TableAppliedDiff<'r, Player>,
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>, tile: __sdk::TableAppliedDiff<'r, DbTile>,
view_hand: __sdk::TableAppliedDiff<'r, PlayerHand>,
wall: __sdk::TableAppliedDiff<'r, DbWall>, wall: __sdk::TableAppliedDiff<'r, DbWall>,
__unused: std::marker::PhantomData<&'r ()>, __unused: std::marker::PhantomData<&'r ()>,
} }
@ -316,23 +300,15 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
event: &EventContext, event: &EventContext,
callbacks: &mut __sdk::DbCallbacks<RemoteModule>, callbacks: &mut __sdk::DbCallbacks<RemoteModule>,
) { ) {
callbacks.invoke_table_row_callbacks::<AdvanceStateTimer>(
"advance_state_timer",
&self.advance_state_timer,
event,
);
callbacks.invoke_table_row_callbacks::<Bot>("bot", &self.bot, event); callbacks.invoke_table_row_callbacks::<Bot>("bot", &self.bot, event);
callbacks.invoke_table_row_callbacks::<GameTimer>("game_timer", &self.game_timer, event);
callbacks.invoke_table_row_callbacks::<Lobby>("lobby", &self.lobby, event); callbacks.invoke_table_row_callbacks::<Lobby>("lobby", &self.lobby, event);
callbacks.invoke_table_row_callbacks::<Player>(
"logged_out_player",
&self.logged_out_player,
event,
);
callbacks.invoke_table_row_callbacks::<Player>("player", &self.player, event); callbacks.invoke_table_row_callbacks::<Player>("player", &self.player, event);
callbacks.invoke_table_row_callbacks::<PlayerClock>(
"player_clock",
&self.player_clock,
event,
);
callbacks.invoke_table_row_callbacks::<PlayerHand>("player_hand", &self.player_hand, event);
callbacks.invoke_table_row_callbacks::<DbTile>("tile", &self.tile, event); callbacks.invoke_table_row_callbacks::<DbTile>("tile", &self.tile, event);
callbacks.invoke_table_row_callbacks::<PlayerHand>("view_hand", &self.view_hand, event);
callbacks.invoke_table_row_callbacks::<DbWall>("wall", &self.wall, event); callbacks.invoke_table_row_callbacks::<DbWall>("wall", &self.wall, event);
} }
} }
@ -1051,18 +1027,13 @@ impl __sdk::SpacetimeModule for RemoteModule {
type DbUpdate = DbUpdate; type DbUpdate = DbUpdate;
type AppliedDiff<'r> = AppliedDiff<'r>; type AppliedDiff<'r> = AppliedDiff<'r>;
type SubscriptionHandle = SubscriptionHandle; type SubscriptionHandle = SubscriptionHandle;
type QueryBuilder = __sdk::QueryBuilder;
fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) { fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
advance_state_timer_table::register_table(client_cache);
bot_table::register_table(client_cache); bot_table::register_table(client_cache);
game_timer_table::register_table(client_cache);
lobby_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_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); tile_table::register_table(client_cache);
view_hand_table::register_table(client_cache);
wall_table::register_table(client_cache); wall_table::register_table(client_cache);
} }
} }

View file

@ -1,189 +0,0 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use super::player_clock_type::PlayerClock;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// 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<PlayerClock>,
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::<PlayerClock>("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<Item = PlayerClock> + '_ {
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<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<PlayerClock>("player_clock");
_table.add_unique_constraint::<u32>("id", |row| &row.id);
_table.add_unique_constraint::<u32>("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<PlayerClock>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<PlayerClock>", "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<PlayerClock, u32>,
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::<u32>("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<PlayerClock> {
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<PlayerClock, u32>,
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::<u32>("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<PlayerClock> {
self.imp.find(col_val)
}
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `PlayerClock`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait player_clockQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `PlayerClock`.
fn player_clock(&self) -> __sdk::__query_builder::Table<PlayerClock>;
}
impl player_clockQueryTableAccess for __sdk::QueryTableAccessor {
fn player_clock(&self) -> __sdk::__query_builder::Table<PlayerClock> {
__sdk::__query_builder::Table::new("player_clock")
}
}

View file

@ -1,58 +0,0 @@
// 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;
}
/// Column accessor struct for the table `PlayerClock`.
///
/// Provides typed access to columns for query building.
pub struct PlayerClockCols {
pub id: __sdk::__query_builder::Col<PlayerClock, u32>,
pub player_id: __sdk::__query_builder::Col<PlayerClock, u32>,
pub renewable: __sdk::__query_builder::Col<PlayerClock, u16>,
pub total: __sdk::__query_builder::Col<PlayerClock, u16>,
}
impl __sdk::__query_builder::HasCols for PlayerClock {
type Cols = PlayerClockCols;
fn cols(table_name: &'static str) -> Self::Cols {
PlayerClockCols {
id: __sdk::__query_builder::Col::new(table_name, "id"),
player_id: __sdk::__query_builder::Col::new(table_name, "player_id"),
renewable: __sdk::__query_builder::Col::new(table_name, "renewable"),
total: __sdk::__query_builder::Col::new(table_name, "total"),
}
}
}
/// Indexed column accessor struct for the table `PlayerClock`.
///
/// Provides typed access to indexed columns for query building.
pub struct PlayerClockIxCols {
pub id: __sdk::__query_builder::IxCol<PlayerClock, u32>,
pub player_id: __sdk::__query_builder::IxCol<PlayerClock, u32>,
}
impl __sdk::__query_builder::HasIxCols for PlayerClock {
type IxCols = PlayerClockIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
PlayerClockIxCols {
id: __sdk::__query_builder::IxCol::new(table_name, "id"),
player_id: __sdk::__query_builder::IxCol::new(table_name, "player_id"),
}
}
}

View file

@ -1,191 +0,0 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use super::db_tile_type::DbTile;
use super::player_hand_type::PlayerHand;
use super::turn_state_type::TurnState;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// 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<PlayerHand>,
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::<PlayerHand>("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<Item = PlayerHand> + '_ {
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<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<PlayerHand>("player_hand");
_table.add_unique_constraint::<u32>("id", |row| &row.id);
_table.add_unique_constraint::<u32>("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<PlayerHand>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<PlayerHand>", "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<PlayerHand, u32>,
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::<u32>("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<PlayerHand> {
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<PlayerHand, u32>,
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::<u32>("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<PlayerHand> {
self.imp.find(col_val)
}
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `PlayerHand`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait player_handQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `PlayerHand`.
fn player_hand(&self) -> __sdk::__query_builder::Table<PlayerHand>;
}
impl player_handQueryTableAccess for __sdk::QueryTableAccessor {
fn player_hand(&self) -> __sdk::__query_builder::Table<PlayerHand> {
__sdk::__query_builder::Table::new("player_hand")
}
}

View file

@ -1,67 +0,0 @@
// 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::db_tile_type::DbTile;
use super::turn_state_type::TurnState;
#[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<DbTile>,
pub hand: Vec<DbTile>,
pub working_tile: Option<DbTile>,
}
impl __sdk::InModule for PlayerHand {
type Module = super::RemoteModule;
}
/// Column accessor struct for the table `PlayerHand`.
///
/// Provides typed access to columns for query building.
pub struct PlayerHandCols {
pub id: __sdk::__query_builder::Col<PlayerHand, u32>,
pub player_id: __sdk::__query_builder::Col<PlayerHand, u32>,
pub turn_state: __sdk::__query_builder::Col<PlayerHand, TurnState>,
pub pond: __sdk::__query_builder::Col<PlayerHand, Vec<DbTile>>,
pub hand: __sdk::__query_builder::Col<PlayerHand, Vec<DbTile>>,
pub working_tile: __sdk::__query_builder::Col<PlayerHand, Option<DbTile>>,
}
impl __sdk::__query_builder::HasCols for PlayerHand {
type Cols = PlayerHandCols;
fn cols(table_name: &'static str) -> Self::Cols {
PlayerHandCols {
id: __sdk::__query_builder::Col::new(table_name, "id"),
player_id: __sdk::__query_builder::Col::new(table_name, "player_id"),
turn_state: __sdk::__query_builder::Col::new(table_name, "turn_state"),
pond: __sdk::__query_builder::Col::new(table_name, "pond"),
hand: __sdk::__query_builder::Col::new(table_name, "hand"),
working_tile: __sdk::__query_builder::Col::new(table_name, "working_tile"),
}
}
}
/// Indexed column accessor struct for the table `PlayerHand`.
///
/// Provides typed access to indexed columns for query building.
pub struct PlayerHandIxCols {
pub id: __sdk::__query_builder::IxCol<PlayerHand, u32>,
pub player_id: __sdk::__query_builder::IxCol<PlayerHand, u32>,
}
impl __sdk::__query_builder::HasIxCols for PlayerHand {
type IxCols = PlayerHandIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
PlayerHandIxCols {
id: __sdk::__query_builder::IxCol::new(table_name, "id"),
player_id: __sdk::__query_builder::IxCol::new(table_name, "player_id"),
}
}
}

View file

@ -2,6 +2,7 @@
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)] #![allow(unused, clippy::all)]
use super::db_tile_type::DbTile;
use super::player_type::Player; use super::player_type::Player;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
@ -81,8 +82,8 @@ impl<'ctx> __sdk::Table for PlayerTableHandle<'ctx> {
#[doc(hidden)] #[doc(hidden)]
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) { pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<Player>("player"); let _table = client_cache.get_or_make_table::<Player>("player");
_table.add_unique_constraint::<u32>("id", |row| &row.id);
_table.add_unique_constraint::<__sdk::Identity>("identity", |row| &row.identity); _table.add_unique_constraint::<__sdk::Identity>("identity", |row| &row.identity);
_table.add_unique_constraint::<u32>("id", |row| &row.id);
} }
pub struct PlayerUpdateCallbackId(__sdk::CallbackId); pub struct PlayerUpdateCallbackId(__sdk::CallbackId);
@ -112,36 +113,6 @@ pub(super) fn parse_table_update(
}) })
} }
/// 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<Player, u32>,
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::<u32>("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<Player> {
self.imp.find(col_val)
}
}
/// Access to the `identity` unique index on the table `player`, /// Access to the `identity` unique index on the table `player`,
/// which allows point queries on the field of the same name /// which allows point queries on the field of the same name
/// via the [`PlayerIdentityUnique::find`] method. /// via the [`PlayerIdentityUnique::find`] method.
@ -174,18 +145,32 @@ impl<'ctx> PlayerIdentityUnique<'ctx> {
} }
} }
#[allow(non_camel_case_types)] /// Access to the `id` unique index on the table `player`,
/// Extension trait for query builder access to the table `Player`. /// which allows point queries on the field of the same name
/// via the [`PlayerIdUnique::find`] method.
/// ///
/// Implemented for [`__sdk::QueryTableAccessor`]. /// Users are encouraged not to explicitly reference this type,
pub trait playerQueryTableAccess { /// but to directly chain method calls,
#[allow(non_snake_case)] /// like `ctx.db.player().id().find(...)`.
/// Get a query builder for the table `Player`. pub struct PlayerIdUnique<'ctx> {
fn player(&self) -> __sdk::__query_builder::Table<Player>; imp: __sdk::UniqueConstraintHandle<Player, u32>,
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
} }
impl playerQueryTableAccess for __sdk::QueryTableAccessor { impl<'ctx> PlayerTableHandle<'ctx> {
fn player(&self) -> __sdk::__query_builder::Table<Player> { /// Get a handle on the `id` unique index on the table `player`.
__sdk::__query_builder::Table::new("player") pub fn id(&self) -> PlayerIdUnique<'ctx> {
PlayerIdUnique {
imp: self.imp.get_unique_constraint::<u32>("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<Player> {
self.imp.find(col_val)
} }
} }

View file

@ -4,63 +4,22 @@
#![allow(unused, clippy::all)] #![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::db_tile_type::DbTile;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)] #[sats(crate = __lib)]
pub struct Player { pub struct Player {
pub id: u32,
pub identity: __sdk::Identity, pub identity: __sdk::Identity,
pub id: u32,
pub name: Option<String>, pub name: Option<String>,
pub lobby_id: u32, pub lobby_id: u32,
pub ready: bool, pub ready: bool,
pub sort: bool, pub sort: bool,
pub hand: Vec<DbTile>,
pub pond: Vec<DbTile>,
pub drawn_tile: Option<DbTile>,
} }
impl __sdk::InModule for Player { impl __sdk::InModule for Player {
type Module = super::RemoteModule; type Module = super::RemoteModule;
} }
/// Column accessor struct for the table `Player`.
///
/// Provides typed access to columns for query building.
pub struct PlayerCols {
pub id: __sdk::__query_builder::Col<Player, u32>,
pub identity: __sdk::__query_builder::Col<Player, __sdk::Identity>,
pub name: __sdk::__query_builder::Col<Player, Option<String>>,
pub lobby_id: __sdk::__query_builder::Col<Player, u32>,
pub ready: __sdk::__query_builder::Col<Player, bool>,
pub sort: __sdk::__query_builder::Col<Player, bool>,
}
impl __sdk::__query_builder::HasCols for Player {
type Cols = PlayerCols;
fn cols(table_name: &'static str) -> Self::Cols {
PlayerCols {
id: __sdk::__query_builder::Col::new(table_name, "id"),
identity: __sdk::__query_builder::Col::new(table_name, "identity"),
name: __sdk::__query_builder::Col::new(table_name, "name"),
lobby_id: __sdk::__query_builder::Col::new(table_name, "lobby_id"),
ready: __sdk::__query_builder::Col::new(table_name, "ready"),
sort: __sdk::__query_builder::Col::new(table_name, "sort"),
}
}
}
/// Indexed column accessor struct for the table `Player`.
///
/// Provides typed access to indexed columns for query building.
pub struct PlayerIxCols {
pub id: __sdk::__query_builder::IxCol<Player, u32>,
pub identity: __sdk::__query_builder::IxCol<Player, __sdk::Identity>,
pub lobby_id: __sdk::__query_builder::IxCol<Player, u32>,
}
impl __sdk::__query_builder::HasIxCols for Player {
type IxCols = PlayerIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
PlayerIxCols {
id: __sdk::__query_builder::IxCol::new(table_name, "id"),
identity: __sdk::__query_builder::IxCol::new(table_name, "identity"),
lobby_id: __sdk::__query_builder::IxCol::new(table_name, "lobby_id"),
}
}
}

View file

@ -0,0 +1,105 @@
// 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 ShuffleDealArgs {
pub lobby_id: u32,
}
impl From<ShuffleDealArgs> for super::Reducer {
fn from(args: ShuffleDealArgs) -> Self {
Self::ShuffleDeal {
lobby_id: args.lobby_id,
}
}
}
impl __sdk::InModule for ShuffleDealArgs {
type Module = super::RemoteModule;
}
pub struct ShuffleDealCallbackId(__sdk::CallbackId);
#[allow(non_camel_case_types)]
/// Extension trait for access to the reducer `shuffle_deal`.
///
/// Implemented for [`super::RemoteReducers`].
pub trait shuffle_deal {
/// Request that the remote module invoke the reducer `shuffle_deal` 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_shuffle_deal`] callbacks.
fn shuffle_deal(&self, lobby_id: u32) -> __sdk::Result<()>;
/// Register a callback to run whenever we are notified of an invocation of the reducer `shuffle_deal`.
///
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
/// to determine the reducer's status.
///
/// The returned [`ShuffleDealCallbackId`] can be passed to [`Self::remove_on_shuffle_deal`]
/// to cancel the callback.
fn on_shuffle_deal(
&self,
callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static,
) -> ShuffleDealCallbackId;
/// Cancel a callback previously registered by [`Self::on_shuffle_deal`],
/// causing it not to run in the future.
fn remove_on_shuffle_deal(&self, callback: ShuffleDealCallbackId);
}
impl shuffle_deal for super::RemoteReducers {
fn shuffle_deal(&self, lobby_id: u32) -> __sdk::Result<()> {
self.imp
.call_reducer("shuffle_deal", ShuffleDealArgs { lobby_id })
}
fn on_shuffle_deal(
&self,
mut callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static,
) -> ShuffleDealCallbackId {
ShuffleDealCallbackId(self.imp.on_reducer(
"shuffle_deal",
Box::new(move |ctx: &super::ReducerEventContext| {
#[allow(irrefutable_let_patterns)]
let super::ReducerEventContext {
event:
__sdk::ReducerEvent {
reducer: super::Reducer::ShuffleDeal { lobby_id },
..
},
..
} = ctx
else {
unreachable!()
};
callback(ctx, lobby_id)
}),
))
}
fn remove_on_shuffle_deal(&self, callback: ShuffleDealCallbackId) {
self.imp.remove_on_reducer("shuffle_deal", callback.0)
}
}
#[allow(non_camel_case_types)]
#[doc(hidden)]
/// Extension trait for setting the call-flags for the reducer `shuffle_deal`.
///
/// Implemented for [`super::SetReducerFlags`].
///
/// This type is currently unstable and may be removed without a major version bump.
pub trait set_flags_for_shuffle_deal {
/// Set the call-reducer flags for the reducer `shuffle_deal` to `flags`.
///
/// This type is currently unstable and may be removed without a major version bump.
fn shuffle_deal(&self, flags: __ws::CallReducerFlags);
}
impl set_flags_for_shuffle_deal for super::SetReducerFlags {
fn shuffle_deal(&self, flags: __ws::CallReducerFlags) {
self.imp.set_call_reducer_flags("shuffle_deal", flags);
}
}

View file

@ -0,0 +1,100 @@
// 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 SkipCallArgs {}
impl From<SkipCallArgs> for super::Reducer {
fn from(args: SkipCallArgs) -> Self {
Self::SkipCall
}
}
impl __sdk::InModule for SkipCallArgs {
type Module = super::RemoteModule;
}
pub struct SkipCallCallbackId(__sdk::CallbackId);
#[allow(non_camel_case_types)]
/// Extension trait for access to the reducer `skip_call`.
///
/// Implemented for [`super::RemoteReducers`].
pub trait skip_call {
/// Request that the remote module invoke the reducer `skip_call` 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_skip_call`] callbacks.
fn skip_call(&self) -> __sdk::Result<()>;
/// Register a callback to run whenever we are notified of an invocation of the reducer `skip_call`.
///
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
/// to determine the reducer's status.
///
/// The returned [`SkipCallCallbackId`] can be passed to [`Self::remove_on_skip_call`]
/// to cancel the callback.
fn on_skip_call(
&self,
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> SkipCallCallbackId;
/// Cancel a callback previously registered by [`Self::on_skip_call`],
/// causing it not to run in the future.
fn remove_on_skip_call(&self, callback: SkipCallCallbackId);
}
impl skip_call for super::RemoteReducers {
fn skip_call(&self) -> __sdk::Result<()> {
self.imp.call_reducer("skip_call", SkipCallArgs {})
}
fn on_skip_call(
&self,
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> SkipCallCallbackId {
SkipCallCallbackId(self.imp.on_reducer(
"skip_call",
Box::new(move |ctx: &super::ReducerEventContext| {
#[allow(irrefutable_let_patterns)]
let super::ReducerEventContext {
event:
__sdk::ReducerEvent {
reducer: super::Reducer::SkipCall {},
..
},
..
} = ctx
else {
unreachable!()
};
callback(ctx)
}),
))
}
fn remove_on_skip_call(&self, callback: SkipCallCallbackId) {
self.imp.remove_on_reducer("skip_call", callback.0)
}
}
#[allow(non_camel_case_types)]
#[doc(hidden)]
/// Extension trait for setting the call-flags for the reducer `skip_call`.
///
/// Implemented for [`super::SetReducerFlags`].
///
/// This type is currently unstable and may be removed without a major version bump.
pub trait set_flags_for_skip_call {
/// Set the call-reducer flags for the reducer `skip_call` to `flags`.
///
/// This type is currently unstable and may be removed without a major version bump.
fn skip_call(&self, flags: __ws::CallReducerFlags);
}
impl set_flags_for_skip_call for super::SetReducerFlags {
fn skip_call(&self, flags: __ws::CallReducerFlags) {
self.imp.set_call_reducer_flags("skip_call", flags);
}
}

View file

@ -6,63 +6,63 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)] #[sats(crate = __lib)]
pub(super) struct DisconnectArgs {} pub(super) struct StartGameArgs {}
impl From<DisconnectArgs> for super::Reducer { impl From<StartGameArgs> for super::Reducer {
fn from(args: DisconnectArgs) -> Self { fn from(args: StartGameArgs) -> Self {
Self::Disconnect Self::StartGame
} }
} }
impl __sdk::InModule for DisconnectArgs { impl __sdk::InModule for StartGameArgs {
type Module = super::RemoteModule; type Module = super::RemoteModule;
} }
pub struct DisconnectCallbackId(__sdk::CallbackId); pub struct StartGameCallbackId(__sdk::CallbackId);
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
/// Extension trait for access to the reducer `disconnect`. /// Extension trait for access to the reducer `start_game`.
/// ///
/// Implemented for [`super::RemoteReducers`]. /// Implemented for [`super::RemoteReducers`].
pub trait disconnect { pub trait start_game {
/// Request that the remote module invoke the reducer `disconnect` to run as soon as possible. /// Request that the remote module invoke the reducer `start_game` to run as soon as possible.
/// ///
/// This method returns immediately, and errors only if we are unable to send the request. /// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future, /// The reducer will run asynchronously in the future,
/// and its status can be observed by listening for [`Self::on_disconnect`] callbacks. /// and its status can be observed by listening for [`Self::on_start_game`] callbacks.
fn disconnect(&self) -> __sdk::Result<()>; fn start_game(&self) -> __sdk::Result<()>;
/// Register a callback to run whenever we are notified of an invocation of the reducer `disconnect`. /// Register a callback to run whenever we are notified of an invocation of the reducer `start_game`.
/// ///
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
/// to determine the reducer's status. /// to determine the reducer's status.
/// ///
/// The returned [`DisconnectCallbackId`] can be passed to [`Self::remove_on_disconnect`] /// The returned [`StartGameCallbackId`] can be passed to [`Self::remove_on_start_game`]
/// to cancel the callback. /// to cancel the callback.
fn on_disconnect( fn on_start_game(
&self, &self,
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> DisconnectCallbackId; ) -> StartGameCallbackId;
/// Cancel a callback previously registered by [`Self::on_disconnect`], /// Cancel a callback previously registered by [`Self::on_start_game`],
/// causing it not to run in the future. /// causing it not to run in the future.
fn remove_on_disconnect(&self, callback: DisconnectCallbackId); fn remove_on_start_game(&self, callback: StartGameCallbackId);
} }
impl disconnect for super::RemoteReducers { impl start_game for super::RemoteReducers {
fn disconnect(&self) -> __sdk::Result<()> { fn start_game(&self) -> __sdk::Result<()> {
self.imp.call_reducer("disconnect", DisconnectArgs {}) self.imp.call_reducer("start_game", StartGameArgs {})
} }
fn on_disconnect( fn on_start_game(
&self, &self,
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> DisconnectCallbackId { ) -> StartGameCallbackId {
DisconnectCallbackId(self.imp.on_reducer( StartGameCallbackId(self.imp.on_reducer(
"disconnect", "start_game",
Box::new(move |ctx: &super::ReducerEventContext| { Box::new(move |ctx: &super::ReducerEventContext| {
#[allow(irrefutable_let_patterns)] #[allow(irrefutable_let_patterns)]
let super::ReducerEventContext { let super::ReducerEventContext {
event: event:
__sdk::ReducerEvent { __sdk::ReducerEvent {
reducer: super::Reducer::Disconnect {}, reducer: super::Reducer::StartGame {},
.. ..
}, },
.. ..
@ -74,27 +74,27 @@ impl disconnect for super::RemoteReducers {
}), }),
)) ))
} }
fn remove_on_disconnect(&self, callback: DisconnectCallbackId) { fn remove_on_start_game(&self, callback: StartGameCallbackId) {
self.imp.remove_on_reducer("disconnect", callback.0) self.imp.remove_on_reducer("start_game", callback.0)
} }
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[doc(hidden)] #[doc(hidden)]
/// Extension trait for setting the call-flags for the reducer `disconnect`. /// Extension trait for setting the call-flags for the reducer `start_game`.
/// ///
/// Implemented for [`super::SetReducerFlags`]. /// Implemented for [`super::SetReducerFlags`].
/// ///
/// This type is currently unstable and may be removed without a major version bump. /// This type is currently unstable and may be removed without a major version bump.
pub trait set_flags_for_disconnect { pub trait set_flags_for_start_game {
/// Set the call-reducer flags for the reducer `disconnect` to `flags`. /// Set the call-reducer flags for the reducer `start_game` to `flags`.
/// ///
/// This type is currently unstable and may be removed without a major version bump. /// This type is currently unstable and may be removed without a major version bump.
fn disconnect(&self, flags: __ws::CallReducerFlags); fn start_game(&self, flags: __ws::CallReducerFlags);
} }
impl set_flags_for_disconnect for super::SetReducerFlags { impl set_flags_for_start_game for super::SetReducerFlags {
fn disconnect(&self, flags: __ws::CallReducerFlags) { fn start_game(&self, flags: __ws::CallReducerFlags) {
self.imp.set_call_reducer_flags("disconnect", flags); self.imp.set_call_reducer_flags("start_game", flags);
} }
} }

View file

@ -141,19 +141,3 @@ impl<'ctx> TileIdUnique<'ctx> {
self.imp.find(col_val) self.imp.find(col_val)
} }
} }
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `DbTile`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait tileQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `DbTile`.
fn tile(&self) -> __sdk::__query_builder::Table<DbTile>;
}
impl tileQueryTableAccess for __sdk::QueryTableAccessor {
fn tile(&self) -> __sdk::__query_builder::Table<DbTile> {
__sdk::__query_builder::Table::new("tile")
}
}

View file

@ -1,113 +0,0 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use super::db_tile_type::DbTile;
use super::player_hand_type::PlayerHand;
use super::turn_state_type::TurnState;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// Table handle for the table `view_hand`.
///
/// Obtain a handle from the [`ViewHandTableAccess::view_hand`] method on [`super::RemoteTables`],
/// like `ctx.db.view_hand()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.view_hand().on_insert(...)`.
pub struct ViewHandTableHandle<'ctx> {
imp: __sdk::TableHandle<PlayerHand>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the table `view_hand`.
///
/// Implemented for [`super::RemoteTables`].
pub trait ViewHandTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`ViewHandTableHandle`], which mediates access to the table `view_hand`.
fn view_hand(&self) -> ViewHandTableHandle<'_>;
}
impl ViewHandTableAccess for super::RemoteTables {
fn view_hand(&self) -> ViewHandTableHandle<'_> {
ViewHandTableHandle {
imp: self.imp.get_table::<PlayerHand>("view_hand"),
ctx: std::marker::PhantomData,
}
}
}
pub struct ViewHandInsertCallbackId(__sdk::CallbackId);
pub struct ViewHandDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::Table for ViewHandTableHandle<'ctx> {
type Row = PlayerHand;
type EventContext = super::EventContext;
fn count(&self) -> u64 {
self.imp.count()
}
fn iter(&self) -> impl Iterator<Item = PlayerHand> + '_ {
self.imp.iter()
}
type InsertCallbackId = ViewHandInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> ViewHandInsertCallbackId {
ViewHandInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: ViewHandInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
type DeleteCallbackId = ViewHandDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> ViewHandDeleteCallbackId {
ViewHandDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: ViewHandDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
#[doc(hidden)]
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<PlayerHand>("view_hand");
}
#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::TableUpdate<__ws::BsatnFormat>,
) -> __sdk::Result<__sdk::TableUpdate<PlayerHand>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<PlayerHand>", "TableUpdate")
.with_cause(e)
.into()
})
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `PlayerHand`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait view_handQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `PlayerHand`.
fn view_hand(&self) -> __sdk::__query_builder::Table<PlayerHand>;
}
impl view_handQueryTableAccess for __sdk::QueryTableAccessor {
fn view_hand(&self) -> __sdk::__query_builder::Table<PlayerHand> {
__sdk::__query_builder::Table::new("view_hand")
}
}

View file

@ -141,19 +141,3 @@ impl<'ctx> WallLobbyIdUnique<'ctx> {
self.imp.find(col_val) self.imp.find(col_val)
} }
} }
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `DbWall`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait wallQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `DbWall`.
fn wall(&self) -> __sdk::__query_builder::Table<DbWall>;
}
impl wallQueryTableAccess for __sdk::QueryTableAccessor {
fn wall(&self) -> __sdk::__query_builder::Table<DbWall> {
__sdk::__query_builder::Table::new("wall")
}
}

View file

@ -1,6 +1,4 @@
pub mod db; pub mod db;
pub use conversions::*;
pub use db::*; pub use db::*;
mod conversions { mod conversions {

View file

@ -1,9 +1,15 @@
use log::debug; use log::debug;
use spacetimedb::{ReducerContext, Table, reducer}; use spacetimedb::{ReducerContext, Table, reducer};
use jong_types::TurnState;
use crate::tables::*; use crate::tables::*;
mod reducers; mod reducers {
mod deal;
mod hand;
mod lobby;
}
mod tables; mod tables;
#[reducer] #[reducer]
@ -26,40 +32,27 @@ pub fn clear_all(ctx: &ReducerContext) {
} }
#[reducer(client_connected)] #[reducer(client_connected)]
pub fn connect(ctx: &ReducerContext) -> Result<(), String> { pub fn login_or_add_player(ctx: &ReducerContext) {
let player = if let Some(player) = ctx.db.logged_out_player().identity().find(ctx.sender) { let identity = ctx.sender;
let player = ctx.db.player().insert(player);
ctx.db.logged_out_player().identity().delete(ctx.sender); // TODO remove player on disconnect
player 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);
} else { } else {
ctx.db.player().try_insert(Player { let player = ctx.db.player().identity().find(identity).unwrap();
identity: ctx.sender, debug!("player {:?} has reconnected", player)
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)] // #[reducer(init)]
@ -72,6 +65,11 @@ pub fn disconnect(ctx: &ReducerContext) -> Result<(), String> {
// // Called everytime a new client connects // // Called everytime a new client connects
// } // }
// #[reducer(client_disconnected)]
// pub fn identity_disconnected(_ctx: &ReducerContext) {
// // Called everytime a client disconnects
// }
// #[reducer] // #[reducer]
// pub fn add(ctx: &ReducerContext, name: String) { // pub fn add(ctx: &ReducerContext, name: String) {
// ctx.db.player().insert(Player { name }); // ctx.db.player().insert(Player { name });

View file

@ -1,119 +0,0 @@
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);
ctx.db.lobby().id().update(lobby);
} 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;
}
}

View file

@ -1,13 +1,18 @@
use log::debug; use log::debug;
use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer}; use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer};
use super::hand::deal_hands;
use crate::tables::*; use crate::tables::*;
#[reducer]
pub fn shuffle_deal(ctx: &ReducerContext, lobby_id: u32) { pub fn shuffle_deal(ctx: &ReducerContext, lobby_id: u32) {
debug!("lobby_id: {lobby_id}"); debug!("lobby_id: {lobby_id}");
let mut lobby = ctx.db.lobby().id().find(lobby_id).unwrap(); let mut lobby = ctx.db.lobby().id().find(lobby_id).unwrap();
if lobby.game_state == jong_types::states::GameState::Deal { if lobby.game_state == jong_types::states::GameState::Setup {
lobby.game_state = jong_types::states::GameState::Deal;
lobby = ctx.db.lobby().id().update(lobby);
let tiles = new_shuffled_wall(ctx); let tiles = new_shuffled_wall(ctx);
ctx.db.wall().insert(DbWall { ctx.db.wall().insert(DbWall {
@ -19,6 +24,7 @@ pub fn shuffle_deal(ctx: &ReducerContext, lobby_id: u32) {
deal_hands(ctx, lobby_id); deal_hands(ctx, lobby_id);
lobby.game_state = jong_types::states::GameState::Play; lobby.game_state = jong_types::states::GameState::Play;
lobby.turn_state = jong_types::states::TurnState::Tsumo;
ctx.db.lobby().id().update(lobby); ctx.db.lobby().id().update(lobby);
} }
} }
@ -33,32 +39,3 @@ pub fn new_shuffled_wall(ctx: &ReducerContext) -> Vec<DbTile> {
wall 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);
}
}

View file

@ -1,27 +1,66 @@
use log::{debug, trace}; use log::{debug, trace};
use spacetimedb::{ReducerContext, reducer}; use spacetimedb::{ReducerContext, reducer};
use crate::tables::{player::player, *};
use jong_types::states::TurnState; use jong_types::states::TurnState;
use crate::tables::*; 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);
}
// TODO make sure this can't be called or just error here? // TODO make sure this can't be called or just error here?
#[reducer] #[reducer]
pub fn discard_tile(ctx: &ReducerContext, tile_id: u32) -> Result<(), String> { pub fn discard_tile(ctx: &ReducerContext, tile_id: u32) -> Result<(), String> {
let player = ctx.db.player().identity().find(ctx.sender).unwrap(); let mut player = ctx.db.player().identity().find(ctx.sender).unwrap();
let mut hand = ctx.db.player_hand().player_id().find(player.id).unwrap(); let mut lobby = ctx.db.lobby().id().find(player.lobby_id).unwrap();
let dealt_tile = if let Some(dealt) = ctx.db.tile().id().find(tile_id) { let dealt_tile = if let Some(dealt) = ctx.db.tile().id().find(tile_id) {
if let Some(drawn) = hand.working_tile { if let Some(drawn) = player.drawn_tile {
if drawn.id == dealt.id { if drawn.id == dealt.id {
// dealt from drawn tile // dealt from drawn tile
dealt dealt
} else if let Some((i, _)) = hand.hand.iter().enumerate().find(|(_, t)| t.id == tile_id) } else if let Some((i, _)) = player
.hand
.iter()
.enumerate()
.find(|(_, t)| t.id == tile_id)
{ {
// dealt from hand // dealt from hand
let dealt = hand.hand.remove(i); let dealt = player.hand.remove(i);
hand.hand.push(drawn); player.hand.push(drawn);
hand.hand.sort_by_key(|t| t.tile); player.hand.sort_by_key(|t| t.tile);
dealt dealt
} else { } else {
@ -43,53 +82,54 @@ pub fn discard_tile(ctx: &ReducerContext, tile_id: u32) -> Result<(), String> {
)); ));
}; };
hand.pond.push(dealt_tile); player.pond.push(dealt_tile);
hand.working_tile = None; player.drawn_tile = None;
hand.turn_state = TurnState::None; lobby.turn_state = TurnState::RonChiiPonKan;
ctx.db.player_hand().id().update(hand); let player = ctx.db.player().id().update(player);
ctx.db.lobby().id().update(lobby);
debug!("player {} discarded tile {:?}", player.id, dealt_tile.tile); debug!("player {} discarded tile {:?}", player.id, dealt_tile.tile);
Ok(()) Ok(())
} }
// #[reducer] #[reducer]
// pub fn skip_call(ctx: &ReducerContext) { pub fn skip_call(ctx: &ReducerContext) {
// trace!("skip_call"); trace!("skip_call");
// let player = ctx.db.player().identity().find(ctx.sender).unwrap(); let player = ctx.db.player().identity().find(ctx.sender).unwrap();
// let mut lobby = ctx.db.lobby().id().find(player.lobby_id).unwrap(); let mut lobby = ctx.db.lobby().id().find(player.lobby_id).unwrap();
// lobby.turn_state = TurnState::Tsumo; lobby.turn_state = TurnState::Tsumo;
// lobby.current_idx += 1; lobby.current_idx += 1;
// if lobby.current_idx >= 3 { if lobby.current_idx >= 3 {
// lobby.current_idx = 0; lobby.current_idx = 0;
// } }
// // FIXME where better can this go // FIXME where better can this go
// bot_moves(ctx, &mut lobby); bot_moves(ctx, &mut lobby);
// ctx.db.player().id().update(player); ctx.db.player().id().update(player);
// ctx.db.lobby().id().update(lobby); ctx.db.lobby().id().update(lobby);
// } }
// fn bot_moves(ctx: &ReducerContext, lobby: &mut Lobby) { fn bot_moves(ctx: &ReducerContext, lobby: &mut Lobby) {
// let mut wall = ctx.db.wall().lobby_id().find(lobby.id).unwrap(); 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) { 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(); let mut bot = ctx.db.bot().id().find(id).unwrap();
// bot.pond.push(wall.tiles.pop().unwrap()); bot.pond.push(wall.tiles.pop().unwrap());
// ctx.db.bot().id().update(bot); ctx.db.bot().id().update(bot);
// lobby.turn_state = TurnState::RonChiiPonKan; lobby.turn_state = TurnState::RonChiiPonKan;
// } else { } else {
// lobby.turn_state = TurnState::Tsumo; lobby.turn_state = TurnState::Tsumo;
// } }
// lobby.current_idx += 1; lobby.current_idx += 1;
// if lobby.current_idx >= 3 { if lobby.current_idx >= 3 {
// lobby.current_idx = 0; lobby.current_idx = 0;
// } }
// } }
// #[view(name = view_player_hand, public)] // #[view(name = view_player_hand, public)]
// pub fn view_player_hand(ctx: &ViewContext) -> Option<Hand> { // pub fn view_player_hand(ctx: &ViewContext) -> Option<Hand> {

View file

@ -1,5 +1,3 @@
use std::time::Duration;
use log::info; use log::info;
use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer}; use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer};
@ -7,18 +5,18 @@ use crate::tables::*;
#[reducer] #[reducer]
pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<(), String> { pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<(), String> {
let mut player = ctx let ok_or = ctx
.db .db
.player() .player()
.identity() .identity()
.find(ctx.sender) .find(ctx.sender)
.ok_or(format!("cannot find player {}", ctx.sender))?; .ok_or(format!("cannot find player {}", ctx.sender))?;
let mut player = ok_or;
if lobby_id == 0 { if lobby_id == 0 {
// TODO check first if player is already in a lobby
let lobby = ctx.db.lobby().insert(Lobby { let lobby = ctx.db.lobby().insert(Lobby {
id: 0, id: 0,
host_player_id: player.id,
players: vec![PlayerOrBot::Player { id: player.id }], players: vec![PlayerOrBot::Player { id: player.id }],
game_state: jong_types::states::GameState::Lobby, game_state: jong_types::states::GameState::Lobby,
dealer_idx: 0, dealer_idx: 0,
@ -51,8 +49,7 @@ pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> {
lobby_id, lobby_id,
hand: vec![], hand: vec![],
pond: vec![], pond: vec![],
working_tile: None, drawn_tile: None,
turn_state: jong_types::TurnState::None,
}); });
lobby.players.push(PlayerOrBot::Bot { id: bot.id }); lobby.players.push(PlayerOrBot::Bot { id: bot.id });
ctx.db.lobby().id().update(lobby); ctx.db.lobby().id().update(lobby);
@ -64,33 +61,29 @@ pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> {
} }
#[reducer] #[reducer]
pub fn set_ready(ctx: &ReducerContext, ready: bool) -> Result<(), String> { pub fn set_ready(ctx: &ReducerContext, ready: bool) {
let mut player = ctx.db.player().identity().find(ctx.sender).unwrap(); let mut player = ctx.db.player().identity().find(ctx.sender).unwrap();
player.ready = ready; player.ready = ready;
player = ctx.db.player().identity().update(player);
if let Some(mut lobby) = ctx.db.lobby().id().find(player.lobby_id) 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)
&& lobby.players.len() == 4 && lobby.players.len() == 4
&& ctx.db.player().lobby_id().filter(lobby.id).all(|p| p.ready) && 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(),
})
{ {
lobby.game_state = jong_types::states::GameState::Setup; lobby.game_state = jong_types::states::GameState::Setup;
lobby.players.shuffle(&mut ctx.rng()); lobby.players.shuffle(&mut ctx.rng());
let lobby = ctx.db.lobby().id().update(lobby); lobby.dealer_idx += 1;
if lobby.dealer_idx > 3 {
// TODO should we schedule this outside so that we can clear out stale lobbies? lobby.dealer_idx = 0;
ctx.db.game_timer().insert(GameTimer { }
id: 0, ctx.db.lobby().id().update(lobby);
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(())
} }

View file

@ -1,12 +1,10 @@
use spacetimedb::{SpacetimeType, ViewContext, table, view}; use spacetimedb::{SpacetimeType, table};
use jong_types::{ use jong_types::{
states::{GameState, TurnState}, states::{GameState, TurnState},
tiles::Tile, tiles::Tile,
}; };
use crate::reducers::advance_game;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[table(name = lobby, public)] #[table(name = lobby, public)]
pub struct Lobby { pub struct Lobby {
@ -14,6 +12,8 @@ pub struct Lobby {
#[auto_inc] #[auto_inc]
pub id: u32, pub id: u32,
#[unique]
pub host_player_id: u32,
pub players: Vec<PlayerOrBot>, pub players: Vec<PlayerOrBot>,
pub dealer_idx: u8, pub dealer_idx: u8,
pub current_idx: u8, pub current_idx: u8,
@ -45,57 +45,44 @@ pub enum PlayerOrBot {
Bot { id: u32 }, Bot { id: u32 },
} }
#[table(name = advance_state_timer)]
pub struct AdvanceStateTimer {
#[primary_key]
#[auto_inc]
scheduled_id: u64,
scheduled_at: spacetimedb::ScheduleAt,
lobby_id: u32,
}
// FIXME this shant be public, use views
#[table(name = player, public)] #[table(name = player, public)]
#[table(name = logged_out_player)]
#[derive(Debug)] #[derive(Debug)]
pub struct Player { pub struct Player {
#[primary_key]
pub identity: spacetimedb::Identity,
#[unique] #[unique]
#[auto_inc] #[auto_inc]
pub id: u32, pub id: u32,
#[primary_key]
pub identity: spacetimedb::Identity,
pub name: Option<String>, pub name: Option<String>,
#[index(btree)] #[index(btree)]
pub lobby_id: u32, pub lobby_id: u32,
pub ready: bool, 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 turn_state: TurnState,
pub pond: Vec<DbTile>, pub sort: bool,
pub hand: Vec<DbTile>,
/// drawn or callable tile pub hand: Vec<DbTile>,
pub working_tile: Option<DbTile>, pub pond: Vec<DbTile>,
pub drawn_tile: Option<DbTile>,
} }
#[table(name = bot, public)] #[table(name = bot)]
pub struct Bot { pub struct Bot {
#[primary_key] #[primary_key]
#[auto_inc] #[auto_inc]
@ -104,31 +91,8 @@ pub struct Bot {
#[index(btree)] #[index(btree)]
pub lobby_id: u32, pub lobby_id: u32,
pub turn_state: TurnState,
pub hand: Vec<DbTile>, pub hand: Vec<DbTile>,
pub pond: Vec<DbTile>, pub pond: Vec<DbTile>,
pub working_tile: Option<DbTile>, pub drawn_tile: Option<DbTile>,
}
#[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,
}
#[view(name = view_hand, public)]
fn view_hand(ctx: &ViewContext) -> Option<PlayerHand> {
ctx.db
.player()
.identity()
.find(ctx.sender)
.and_then(|p| ctx.db.player_hand().player_id().find(p.id))
} }

View file

@ -3,11 +3,8 @@ use bevy_spacetimedb::{
ReadInsertUpdateMessage, ReadStdbConnectedMessage, ReadStdbDisconnectedMessage, StdbPlugin, ReadInsertUpdateMessage, ReadStdbConnectedMessage, ReadStdbDisconnectedMessage, StdbPlugin,
}; };
use jong_db::{ use jong_db::{self, DbConnection, LobbyTableAccess, PlayerTableAccess, RemoteTables};
self, DbConnection, LobbyTableAccess, PlayerHand, PlayerTableAccess, RemoteTables, use jong_db::{add_bot, draw_tile, set_ready, shuffle_deal, skip_call, start_game};
ViewHandTableAccess as _,
};
use jong_db::{add_bot, set_ready};
use jong_types::*; use jong_types::*;
pub mod player; pub mod player;
@ -22,10 +19,11 @@ impl Plugin for Riichi {
.with_uri("http://localhost:3000") .with_uri("http://localhost:3000")
.with_module_name("jong-line") .with_module_name("jong-line")
.with_run_fn(DbConnection::run_threaded) .with_run_fn(DbConnection::run_threaded)
// TODO why don't I need to call add_reducer?
// TODO do these need to be subscription & vice-versa?
.add_table(RemoteTables::player) .add_table(RemoteTables::player)
.add_table(RemoteTables::lobby) .add_table(RemoteTables::lobby)
// TODO check bevy_spacetimedb PR status
.add_view_with_pk(RemoteTables::view_hand, |p| p.id)
// semicolon stopper // semicolon stopper
; ;
@ -89,59 +87,92 @@ fn subscriptions(stdb: SpacetimeDB) {
.on_applied(|_| trace!("made all subs!")) .on_applied(|_| trace!("made all subs!"))
.on_error(|_, err| error!("sub failed: {err}")) .on_error(|_, err| error!("sub failed: {err}"))
.subscribe([ .subscribe([
// TODO change these to sub/unsub based on being in lobby and some such // TODO until views work
format!( format!(
"SELECT * FROM player p WHERE p.identity = '{}'", "SELECT * FROM player p WHERE p.identity = '{}'",
stdb.identity() stdb.identity()
), ),
"SELECT l.* FROM lobby l JOIN player p ON l.id = p.lobby_id".to_string(), "SELECT l.* FROM lobby l JOIN player p ON l.host_player_id = p.id".to_string(),
"SELECT c.* FROM player_clock c JOIN player p ON c.player_id = p.id".to_string(),
"SELECT * FROM view_hand".to_string(),
"SELECT b.* FROM bot b JOIN lobby l ON l.id = b.lobby_id".to_string(),
]); ]);
// .subscribe_to_all_tables(); // .subscribe_to_all_tables();
} }
fn on_view_hand_insert_update(
stdb: SpacetimeDB,
mut messages: ReadInsertUpdateMessage<jong_db::PlayerHand>,
mut commands: Commands,
mut hand: Option<Single<&mut Children, With<Hand>>>,
tiles: Query<&Tile>,
mut next_turnstate: ResMut<NextState<jong_types::states::TurnState>>,
) {
for msg in messages.read() {
if hand.is_none() {
let hand_tiles: Vec<_> = msg
.new
.hand
.iter()
.map(|dbt| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
.collect();
commands.spawn(Hand).add_children(&hand_tiles);
}
// match msg.new.turn_state {
// jong_db::TurnState::None => todo!(),
// jong_db::TurnState::Tsumo => todo!(),
// jong_db::TurnState::Menzen => todo!(),
// jong_db::TurnState::RiichiKan => todo!(),
// jong_db::TurnState::RonChiiPonKan => todo!(),
// jong_db::TurnState::End => todo!(),
// }
next_turnstate.set(msg.new.turn_state.into());
}
}
fn on_player_insert_update( fn on_player_insert_update(
stdb: SpacetimeDB,
mut messages: ReadInsertUpdateMessage<jong_db::Player>, mut messages: ReadInsertUpdateMessage<jong_db::Player>,
mut commands: Commands, mut commands: Commands,
pond: Option<Single<Entity, With<Pond>>>,
hand: Option<Single<Entity, With<Hand>>>,
tiles: Query<(Entity, &TileId)>,
) { ) {
for msg in messages.read() {} let hand = if hand.is_none() {
let hand = commands.spawn(Hand).id();
commands.spawn(Pond);
hand
} else {
*hand.unwrap()
};
let pond = if pond.is_none() {
let pond = commands.spawn(Pond).id();
commands.spawn(Pond);
pond
} else {
*pond.unwrap()
};
for msg in messages.read() {
match msg.new.turn_state {
jong_db::TurnState::None => {}
jong_db::TurnState::Tsumo => {
stdb.reducers().draw_tile().unwrap();
}
jong_db::TurnState::Menzen => todo!(),
jong_db::TurnState::RiichiKan => todo!(),
jong_db::TurnState::RonChiiPonKan => {
stdb.reducers().skip_call().unwrap();
}
jong_db::TurnState::End => todo!(),
}
let hand_tiles: Vec<_> = msg
.new
.hand
.iter()
.map(|dbt| {
tiles
.iter()
.find_map(|(e, t)| if *t == TileId(dbt.id) { Some(e) } else { None })
.or_else(|| Some(commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id()))
.unwrap()
})
.collect();
let pond_tiles: Vec<_> = msg
.new
.pond
.iter()
.map(|dbt| {
tiles
.iter()
.find_map(|(e, t)| if *t == TileId(dbt.id) { Some(e) } else { None })
.expect(&format!(
"dealt tiles should still be around, couldn't find {:?}. Tiles: {:?}",
dbt,
tiles.iter().map(|(_, t)| t).collect::<Vec<_>>()
))
})
.collect();
debug!("hand_tiles: {hand_tiles:?}");
commands.entity(hand).replace_children(&hand_tiles);
commands.entity(pond).replace_children(&pond_tiles);
// drawn tile is always a new tile to us until wall isn't fake
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));
}
}
} }
fn on_lobby_insert_update( fn on_lobby_insert_update(
@ -150,9 +181,10 @@ fn on_lobby_insert_update(
commands: Commands, commands: Commands,
mut next_gamestate: ResMut<NextState<jong_types::states::GameState>>, mut next_gamestate: ResMut<NextState<jong_types::states::GameState>>,
mut next_turnstate: ResMut<NextState<jong_types::states::TurnState>>,
) { ) {
for msg in messages.read() { for msg in messages.read() {
trace!("on_lobby_insert_update msg:\n{:#?}", msg.new); // trace!("on_lobby_insert_update msg:\n{:#?}", msg.new);
let player = stdb let player = stdb
.db() .db()
@ -173,10 +205,12 @@ fn on_lobby_insert_update(
stdb.reducers().add_bot(player.lobby_id).unwrap(); stdb.reducers().add_bot(player.lobby_id).unwrap();
} }
stdb.reducers().set_ready(true).unwrap(); stdb.reducers().set_ready(true).unwrap();
stdb.reducers().start_game().unwrap();
} }
} }
jong_db::GameState::Setup => { jong_db::GameState::Setup => {
trace!("game entered setup"); trace!("game entered setup");
stdb.reducers().shuffle_deal(player.lobby_id).unwrap();
} }
jong_db::GameState::Deal => { jong_db::GameState::Deal => {
trace!("game entered deal"); trace!("game entered deal");

View file

@ -97,8 +97,9 @@ impl Plugin for TuiPlugin {
fn discard_tile( fn discard_tile(
stdb: SpacetimeDB, stdb: SpacetimeDB,
mut commands: Commands,
mut selected: MessageReader<ConfirmSelect>, mut selected: MessageReader<ConfirmSelect>,
mut commands: Commands,
drawn: Single<(Entity, &TileId), With<Drawn>>, drawn: Single<(Entity, &TileId), With<Drawn>>,
tiles: Query<&TileId>, tiles: Query<&TileId>,
) { ) {

View file

@ -3,6 +3,7 @@ use bevy_ratatui::crossterm::event::KeyCode;
use bevy_ratatui::event::KeyMessage; use bevy_ratatui::event::KeyMessage;
use jong_db::PlayerTableAccess; use jong_db::PlayerTableAccess;
use jong_db::join_or_create_lobby; use jong_db::join_or_create_lobby;
use jong_db::start_game;
use tui_logger::TuiWidgetEvent; use tui_logger::TuiWidgetEvent;
use jong::SpacetimeDB; use jong::SpacetimeDB;

View file

@ -8,6 +8,8 @@ default:
just --list just --list
run-tui: run-tui:
just spacetime_restart_dev
sleep 3sec
cargo run -- run-tui cargo run -- run-tui
update: update:
@ -25,8 +27,3 @@ spacetime_generate-bindings:
spacetime_restart_dev: spacetime_restart_dev:
mprocs -s localhost:4050 --ctl $"({c: restart-proc, name: spacetimedb_dev} | to yaml)" mprocs -s localhost:4050 --ctl $"({c: restart-proc, name: spacetimedb_dev} | to yaml)"
rrt:
just spacetime_restart_dev
sleep 3sec
just run-tui