Compare commits
No commits in common. "3457e0d024d6ab32569fc123093c8f365784aefb" and "7ffef5522b88d9d179e8b96ed91af8da7416c7db" have entirely different histories.
3457e0d024
...
7ffef5522b
38 changed files with 1305 additions and 1160 deletions
|
|
@ -1,2 +1,2 @@
|
||||||
jong-db/src/db
|
jong-db
|
||||||
bevy_spacetimedb
|
bevy_spacetimedb
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@
|
||||||
];
|
];
|
||||||
env.LD_LIBRARY_PATH = lib.makeLibraryPath packages;
|
env.LD_LIBRARY_PATH = lib.makeLibraryPath packages;
|
||||||
env.RUST_LOG = "jong=trace";
|
env.RUST_LOG = "jong=trace";
|
||||||
env.RUST_BACKTRACE = "full";
|
|
||||||
|
|
||||||
# https://devenv.sh/languages/
|
# https://devenv.sh/languages/
|
||||||
languages.rust = {
|
languages.rust = {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#![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::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`.
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,18 @@
|
||||||
#![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;
|
||||||
|
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 config_id: u32,
|
pub turn_state: TurnState,
|
||||||
|
pub hand: Vec<DbTile>,
|
||||||
|
pub pond: Vec<DbTile>,
|
||||||
|
pub working_tile: Option<DbTile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for Bot {
|
impl __sdk::InModule for Bot {
|
||||||
|
|
@ -22,7 +28,10 @@ impl __sdk::InModule for Bot {
|
||||||
pub struct BotCols {
|
pub struct BotCols {
|
||||||
pub id: __sdk::__query_builder::Col<Bot, u32>,
|
pub id: __sdk::__query_builder::Col<Bot, u32>,
|
||||||
pub lobby_id: __sdk::__query_builder::Col<Bot, u32>,
|
pub lobby_id: __sdk::__query_builder::Col<Bot, u32>,
|
||||||
pub config_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 {
|
impl __sdk::__query_builder::HasCols for Bot {
|
||||||
|
|
@ -31,7 +40,10 @@ impl __sdk::__query_builder::HasCols for Bot {
|
||||||
BotCols {
|
BotCols {
|
||||||
id: __sdk::__query_builder::Col::new(table_name, "id"),
|
id: __sdk::__query_builder::Col::new(table_name, "id"),
|
||||||
lobby_id: __sdk::__query_builder::Col::new(table_name, "lobby_id"),
|
lobby_id: __sdk::__query_builder::Col::new(table_name, "lobby_id"),
|
||||||
config_id: __sdk::__query_builder::Col::new(table_name, "config_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"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
62
jong-db/src/db/clear_all_reducer.rs
Normal file
62
jong-db/src/db/clear_all_reducer.rs
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
// 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 ClearAllArgs {}
|
||||||
|
|
||||||
|
impl From<ClearAllArgs> for super::Reducer {
|
||||||
|
fn from(args: ClearAllArgs) -> Self {
|
||||||
|
Self::ClearAll
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for ClearAllArgs {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the reducer `clear_all`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteReducers`].
|
||||||
|
pub trait clear_all {
|
||||||
|
/// Request that the remote module invoke the reducer `clear_all` 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 this method provides no way to listen for its completion status.
|
||||||
|
/// /// Use [`clear_all:clear_all_then`] to run a callback after the reducer completes.
|
||||||
|
fn clear_all(&self) -> __sdk::Result<()> {
|
||||||
|
self.clear_all_then(|_, _| {})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Request that the remote module invoke the reducer `clear_all` to run as soon as possible,
|
||||||
|
/// registering `callback` to run when we are notified that the reducer completed.
|
||||||
|
///
|
||||||
|
/// 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 with the `callback`.
|
||||||
|
fn clear_all_then(
|
||||||
|
&self,
|
||||||
|
|
||||||
|
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
||||||
|
+ Send
|
||||||
|
+ 'static,
|
||||||
|
) -> __sdk::Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl clear_all for super::RemoteReducers {
|
||||||
|
fn clear_all_then(
|
||||||
|
&self,
|
||||||
|
|
||||||
|
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
|
||||||
|
+ Send
|
||||||
|
+ 'static,
|
||||||
|
) -> __sdk::Result<()> {
|
||||||
|
self.imp
|
||||||
|
.invoke_reducer_with_callback(ClearAllArgs {}, callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,47 +8,47 @@ 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 Wall {
|
pub struct DbWall {
|
||||||
pub lobby_id: u32,
|
pub lobby_id: u32,
|
||||||
pub tiles: Vec<DbTile>,
|
pub tiles: Vec<DbTile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for Wall {
|
impl __sdk::InModule for DbWall {
|
||||||
type Module = super::RemoteModule;
|
type Module = super::RemoteModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Column accessor struct for the table `Wall`.
|
/// Column accessor struct for the table `DbWall`.
|
||||||
///
|
///
|
||||||
/// Provides typed access to columns for query building.
|
/// Provides typed access to columns for query building.
|
||||||
pub struct WallCols {
|
pub struct DbWallCols {
|
||||||
pub lobby_id: __sdk::__query_builder::Col<Wall, u32>,
|
pub lobby_id: __sdk::__query_builder::Col<DbWall, u32>,
|
||||||
pub tiles: __sdk::__query_builder::Col<Wall, Vec<DbTile>>,
|
pub tiles: __sdk::__query_builder::Col<DbWall, Vec<DbTile>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for Wall {
|
impl __sdk::__query_builder::HasCols for DbWall {
|
||||||
type Cols = WallCols;
|
type Cols = DbWallCols;
|
||||||
fn cols(table_name: &'static str) -> Self::Cols {
|
fn cols(table_name: &'static str) -> Self::Cols {
|
||||||
WallCols {
|
DbWallCols {
|
||||||
lobby_id: __sdk::__query_builder::Col::new(table_name, "lobby_id"),
|
lobby_id: __sdk::__query_builder::Col::new(table_name, "lobby_id"),
|
||||||
tiles: __sdk::__query_builder::Col::new(table_name, "tiles"),
|
tiles: __sdk::__query_builder::Col::new(table_name, "tiles"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indexed column accessor struct for the table `Wall`.
|
/// Indexed column accessor struct for the table `DbWall`.
|
||||||
///
|
///
|
||||||
/// Provides typed access to indexed columns for query building.
|
/// Provides typed access to indexed columns for query building.
|
||||||
pub struct WallIxCols {
|
pub struct DbWallIxCols {
|
||||||
pub lobby_id: __sdk::__query_builder::IxCol<Wall, u32>,
|
pub lobby_id: __sdk::__query_builder::IxCol<DbWall, u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasIxCols for Wall {
|
impl __sdk::__query_builder::HasIxCols for DbWall {
|
||||||
type IxCols = WallIxCols;
|
type IxCols = DbWallIxCols;
|
||||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||||
WallIxCols {
|
DbWallIxCols {
|
||||||
lobby_id: __sdk::__query_builder::IxCol::new(table_name, "lobby_id"),
|
lobby_id: __sdk::__query_builder::IxCol::new(table_name, "lobby_id"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::__query_builder::CanBeLookupTable for Wall {}
|
impl __sdk::__query_builder::CanBeLookupTable for DbWall {}
|
||||||
190
jong-db/src/db/game_timer_table.rs
Normal file
190
jong-db/src/db/game_timer_table.rs
Normal file
|
|
@ -0,0 +1,190 @@
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub(super) fn parse_table_update(
|
||||||
|
raw_updates: __ws::v2::TableUpdate,
|
||||||
|
) -> __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()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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")
|
||||||
|
}
|
||||||
|
}
|
||||||
57
jong-db/src/db/game_timer_type.rs
Normal file
57
jong-db/src/db/game_timer_type.rs
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
// 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"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::__query_builder::CanBeLookupTable for GameTimer {}
|
||||||
|
|
@ -4,14 +4,13 @@
|
||||||
#![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;
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
|
|
||||||
#[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 HandView {
|
pub struct HandView {
|
||||||
pub player_id: u32,
|
pub player: PlayerOrBot,
|
||||||
pub hand_length: u8,
|
pub hand_length: u8,
|
||||||
pub pond: Vec<DbTile>,
|
|
||||||
pub drawn: bool,
|
pub drawn: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -23,9 +22,8 @@ impl __sdk::InModule for HandView {
|
||||||
///
|
///
|
||||||
/// Provides typed access to columns for query building.
|
/// Provides typed access to columns for query building.
|
||||||
pub struct HandViewCols {
|
pub struct HandViewCols {
|
||||||
pub player_id: __sdk::__query_builder::Col<HandView, u32>,
|
pub player: __sdk::__query_builder::Col<HandView, PlayerOrBot>,
|
||||||
pub hand_length: __sdk::__query_builder::Col<HandView, u8>,
|
pub hand_length: __sdk::__query_builder::Col<HandView, u8>,
|
||||||
pub pond: __sdk::__query_builder::Col<HandView, Vec<DbTile>>,
|
|
||||||
pub drawn: __sdk::__query_builder::Col<HandView, bool>,
|
pub drawn: __sdk::__query_builder::Col<HandView, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -33,9 +31,8 @@ impl __sdk::__query_builder::HasCols for HandView {
|
||||||
type Cols = HandViewCols;
|
type Cols = HandViewCols;
|
||||||
fn cols(table_name: &'static str) -> Self::Cols {
|
fn cols(table_name: &'static str) -> Self::Cols {
|
||||||
HandViewCols {
|
HandViewCols {
|
||||||
player_id: __sdk::__query_builder::Col::new(table_name, "player_id"),
|
player: __sdk::__query_builder::Col::new(table_name, "player"),
|
||||||
hand_length: __sdk::__query_builder::Col::new(table_name, "hand_length"),
|
hand_length: __sdk::__query_builder::Col::new(table_name, "hand_length"),
|
||||||
pond: __sdk::__query_builder::Col::new(table_name, "pond"),
|
|
||||||
drawn: __sdk::__query_builder::Col::new(table_name, "drawn"),
|
drawn: __sdk::__query_builder::Col::new(table_name, "drawn"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#![allow(unused, clippy::all)]
|
#![allow(unused, clippy::all)]
|
||||||
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 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`.
|
||||||
|
|
|
||||||
|
|
@ -1,57 +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 LobbyTimer {
|
|
||||||
pub lobby_id: u32,
|
|
||||||
pub scheduled_id: u64,
|
|
||||||
pub scheduled_at: __sdk::ScheduleAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::InModule for LobbyTimer {
|
|
||||||
type Module = super::RemoteModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Column accessor struct for the table `LobbyTimer`.
|
|
||||||
///
|
|
||||||
/// Provides typed access to columns for query building.
|
|
||||||
pub struct LobbyTimerCols {
|
|
||||||
pub lobby_id: __sdk::__query_builder::Col<LobbyTimer, u32>,
|
|
||||||
pub scheduled_id: __sdk::__query_builder::Col<LobbyTimer, u64>,
|
|
||||||
pub scheduled_at: __sdk::__query_builder::Col<LobbyTimer, __sdk::ScheduleAt>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for LobbyTimer {
|
|
||||||
type Cols = LobbyTimerCols;
|
|
||||||
fn cols(table_name: &'static str) -> Self::Cols {
|
|
||||||
LobbyTimerCols {
|
|
||||||
lobby_id: __sdk::__query_builder::Col::new(table_name, "lobby_id"),
|
|
||||||
scheduled_id: __sdk::__query_builder::Col::new(table_name, "scheduled_id"),
|
|
||||||
scheduled_at: __sdk::__query_builder::Col::new(table_name, "scheduled_at"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Indexed column accessor struct for the table `LobbyTimer`.
|
|
||||||
///
|
|
||||||
/// Provides typed access to indexed columns for query building.
|
|
||||||
pub struct LobbyTimerIxCols {
|
|
||||||
pub lobby_id: __sdk::__query_builder::IxCol<LobbyTimer, u32>,
|
|
||||||
pub scheduled_id: __sdk::__query_builder::IxCol<LobbyTimer, u64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasIxCols for LobbyTimer {
|
|
||||||
type IxCols = LobbyTimerIxCols;
|
|
||||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
|
||||||
LobbyTimerIxCols {
|
|
||||||
lobby_id: __sdk::__query_builder::IxCol::new(table_name, "lobby_id"),
|
|
||||||
scheduled_id: __sdk::__query_builder::IxCol::new(table_name, "scheduled_id"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::__query_builder::CanBeLookupTable for LobbyTimer {}
|
|
||||||
|
|
@ -5,12 +5,13 @@
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
use super::game_state_type::GameState;
|
use super::game_state_type::GameState;
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
|
|
||||||
#[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 players: Vec<u32>,
|
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,
|
||||||
|
|
@ -25,7 +26,7 @@ impl __sdk::InModule for Lobby {
|
||||||
/// Provides typed access to columns for query building.
|
/// Provides typed access to columns for query building.
|
||||||
pub struct LobbyCols {
|
pub struct LobbyCols {
|
||||||
pub id: __sdk::__query_builder::Col<Lobby, u32>,
|
pub id: __sdk::__query_builder::Col<Lobby, u32>,
|
||||||
pub players: __sdk::__query_builder::Col<Lobby, Vec<u32>>,
|
pub players: __sdk::__query_builder::Col<Lobby, Vec<PlayerOrBot>>,
|
||||||
pub dealer_idx: __sdk::__query_builder::Col<Lobby, u8>,
|
pub dealer_idx: __sdk::__query_builder::Col<Lobby, u8>,
|
||||||
pub current_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>,
|
pub game_state: __sdk::__query_builder::Col<Lobby, GameState>,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// 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 2.0.2 (commit bc4fcec6f33f607fb46f61ae66c479eecf5a6e74).
|
// This was generated using spacetimedb cli version 2.0.1 (commit a4d29daec8ed35ce4913a335b7210b9ae3933d00).
|
||||||
|
|
||||||
#![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};
|
||||||
|
|
@ -10,60 +10,62 @@ pub mod add_bot_reducer;
|
||||||
pub mod advance_game_reducer;
|
pub mod advance_game_reducer;
|
||||||
pub mod bot_table;
|
pub mod bot_table;
|
||||||
pub mod bot_type;
|
pub mod bot_type;
|
||||||
|
pub mod clear_all_reducer;
|
||||||
pub mod db_tile_type;
|
pub mod db_tile_type;
|
||||||
|
pub mod db_wall_type;
|
||||||
pub mod discard_tile_reducer;
|
pub mod discard_tile_reducer;
|
||||||
pub mod dragon_type;
|
pub mod dragon_type;
|
||||||
pub mod game_state_type;
|
pub mod game_state_type;
|
||||||
|
pub mod game_timer_table;
|
||||||
|
pub mod game_timer_type;
|
||||||
pub mod hand_view_type;
|
pub mod hand_view_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_timer_type;
|
|
||||||
pub mod lobby_type;
|
pub mod lobby_type;
|
||||||
pub mod player_clock_table;
|
pub mod player_clock_table;
|
||||||
pub mod player_clock_type;
|
pub mod player_clock_type;
|
||||||
pub mod player_config_table;
|
|
||||||
pub mod player_config_type;
|
|
||||||
pub mod player_hand_type;
|
pub mod player_hand_type;
|
||||||
|
pub mod player_or_bot_type;
|
||||||
|
pub mod player_table;
|
||||||
|
pub mod player_type;
|
||||||
pub mod rank_type;
|
pub mod rank_type;
|
||||||
pub mod set_ready_reducer;
|
pub mod set_ready_reducer;
|
||||||
pub mod suit_type;
|
pub mod suit_type;
|
||||||
pub mod tile_type;
|
pub mod tile_type;
|
||||||
pub mod turn_state_type;
|
pub mod turn_state_type;
|
||||||
pub mod user_table;
|
|
||||||
pub mod user_type;
|
|
||||||
pub mod view_closed_hands_table;
|
pub mod view_closed_hands_table;
|
||||||
pub mod view_hand_table;
|
pub mod view_hand_table;
|
||||||
pub mod wall_type;
|
|
||||||
pub mod wind_type;
|
pub mod wind_type;
|
||||||
|
|
||||||
pub use add_bot_reducer::add_bot;
|
pub use add_bot_reducer::add_bot;
|
||||||
pub use advance_game_reducer::advance_game;
|
pub use advance_game_reducer::advance_game;
|
||||||
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;
|
||||||
pub use db_tile_type::DbTile;
|
pub use db_tile_type::DbTile;
|
||||||
|
pub use db_wall_type::DbWall;
|
||||||
pub use discard_tile_reducer::discard_tile;
|
pub use discard_tile_reducer::discard_tile;
|
||||||
pub use dragon_type::Dragon;
|
pub use dragon_type::Dragon;
|
||||||
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 hand_view_type::HandView;
|
pub use hand_view_type::HandView;
|
||||||
pub use join_or_create_lobby_reducer::join_or_create_lobby;
|
pub use join_or_create_lobby_reducer::join_or_create_lobby;
|
||||||
pub use lobby_table::*;
|
pub use lobby_table::*;
|
||||||
pub use lobby_timer_type::LobbyTimer;
|
|
||||||
pub use lobby_type::Lobby;
|
pub use lobby_type::Lobby;
|
||||||
pub use player_clock_table::*;
|
pub use player_clock_table::*;
|
||||||
pub use player_clock_type::PlayerClock;
|
pub use player_clock_type::PlayerClock;
|
||||||
pub use player_config_table::*;
|
|
||||||
pub use player_config_type::PlayerConfig;
|
|
||||||
pub use player_hand_type::PlayerHand;
|
pub use player_hand_type::PlayerHand;
|
||||||
|
pub use player_or_bot_type::PlayerOrBot;
|
||||||
|
pub use player_table::*;
|
||||||
|
pub use player_type::Player;
|
||||||
pub use rank_type::Rank;
|
pub use rank_type::Rank;
|
||||||
pub use set_ready_reducer::set_ready;
|
pub use set_ready_reducer::set_ready;
|
||||||
pub use suit_type::Suit;
|
pub use suit_type::Suit;
|
||||||
pub use tile_type::Tile;
|
pub use tile_type::Tile;
|
||||||
pub use turn_state_type::TurnState;
|
pub use turn_state_type::TurnState;
|
||||||
pub use user_table::*;
|
|
||||||
pub use user_type::User;
|
|
||||||
pub use view_closed_hands_table::*;
|
pub use view_closed_hands_table::*;
|
||||||
pub use view_hand_table::*;
|
pub use view_hand_table::*;
|
||||||
pub use wall_type::Wall;
|
|
||||||
pub use wind_type::Wind;
|
pub use wind_type::Wind;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
|
@ -76,6 +78,7 @@ pub use wind_type::Wind;
|
||||||
pub enum Reducer {
|
pub enum Reducer {
|
||||||
AddBot { lobby_id: u32 },
|
AddBot { lobby_id: u32 },
|
||||||
AdvanceGame,
|
AdvanceGame,
|
||||||
|
ClearAll,
|
||||||
DiscardTile { tile_id: u32 },
|
DiscardTile { tile_id: u32 },
|
||||||
JoinOrCreateLobby { lobby_id: u32 },
|
JoinOrCreateLobby { lobby_id: u32 },
|
||||||
SetReady { ready: bool },
|
SetReady { ready: bool },
|
||||||
|
|
@ -90,6 +93,7 @@ impl __sdk::Reducer for Reducer {
|
||||||
match self {
|
match self {
|
||||||
Reducer::AddBot { .. } => "add_bot",
|
Reducer::AddBot { .. } => "add_bot",
|
||||||
Reducer::AdvanceGame => "advance_game",
|
Reducer::AdvanceGame => "advance_game",
|
||||||
|
Reducer::ClearAll => "clear_all",
|
||||||
Reducer::DiscardTile { .. } => "discard_tile",
|
Reducer::DiscardTile { .. } => "discard_tile",
|
||||||
Reducer::JoinOrCreateLobby { .. } => "join_or_create_lobby",
|
Reducer::JoinOrCreateLobby { .. } => "join_or_create_lobby",
|
||||||
Reducer::SetReady { .. } => "set_ready",
|
Reducer::SetReady { .. } => "set_ready",
|
||||||
|
|
@ -105,6 +109,7 @@ impl __sdk::Reducer for Reducer {
|
||||||
Reducer::AdvanceGame => {
|
Reducer::AdvanceGame => {
|
||||||
__sats::bsatn::to_vec(&advance_game_reducer::AdvanceGameArgs {})
|
__sats::bsatn::to_vec(&advance_game_reducer::AdvanceGameArgs {})
|
||||||
}
|
}
|
||||||
|
Reducer::ClearAll => __sats::bsatn::to_vec(&clear_all_reducer::ClearAllArgs {}),
|
||||||
Reducer::DiscardTile { tile_id } => {
|
Reducer::DiscardTile { tile_id } => {
|
||||||
__sats::bsatn::to_vec(&discard_tile_reducer::DiscardTileArgs {
|
__sats::bsatn::to_vec(&discard_tile_reducer::DiscardTileArgs {
|
||||||
tile_id: tile_id.clone(),
|
tile_id: tile_id.clone(),
|
||||||
|
|
@ -130,10 +135,10 @@ impl __sdk::Reducer for Reducer {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct DbUpdate {
|
pub struct DbUpdate {
|
||||||
bot: __sdk::TableUpdate<Bot>,
|
bot: __sdk::TableUpdate<Bot>,
|
||||||
|
game_timer: __sdk::TableUpdate<GameTimer>,
|
||||||
lobby: __sdk::TableUpdate<Lobby>,
|
lobby: __sdk::TableUpdate<Lobby>,
|
||||||
|
player: __sdk::TableUpdate<Player>,
|
||||||
player_clock: __sdk::TableUpdate<PlayerClock>,
|
player_clock: __sdk::TableUpdate<PlayerClock>,
|
||||||
player_config: __sdk::TableUpdate<PlayerConfig>,
|
|
||||||
user: __sdk::TableUpdate<User>,
|
|
||||||
view_closed_hands: __sdk::TableUpdate<HandView>,
|
view_closed_hands: __sdk::TableUpdate<HandView>,
|
||||||
view_hand: __sdk::TableUpdate<PlayerHand>,
|
view_hand: __sdk::TableUpdate<PlayerHand>,
|
||||||
}
|
}
|
||||||
|
|
@ -147,18 +152,18 @@ impl TryFrom<__ws::v2::TransactionUpdate> for DbUpdate {
|
||||||
"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)?),
|
||||||
|
"player" => db_update
|
||||||
|
.player
|
||||||
|
.append(player_table::parse_table_update(table_update)?),
|
||||||
"player_clock" => db_update
|
"player_clock" => db_update
|
||||||
.player_clock
|
.player_clock
|
||||||
.append(player_clock_table::parse_table_update(table_update)?),
|
.append(player_clock_table::parse_table_update(table_update)?),
|
||||||
"player_config" => db_update
|
|
||||||
.player_config
|
|
||||||
.append(player_config_table::parse_table_update(table_update)?),
|
|
||||||
"user" => db_update
|
|
||||||
.user
|
|
||||||
.append(user_table::parse_table_update(table_update)?),
|
|
||||||
"view_closed_hands" => db_update
|
"view_closed_hands" => db_update
|
||||||
.view_closed_hands
|
.view_closed_hands
|
||||||
.append(view_closed_hands_table::parse_table_update(table_update)?),
|
.append(view_closed_hands_table::parse_table_update(table_update)?),
|
||||||
|
|
@ -194,18 +199,18 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||||
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.player = cache
|
||||||
|
.apply_diff_to_table::<Player>("player", &self.player)
|
||||||
|
.with_updates_by_pk(|row| &row.identity);
|
||||||
diff.player_clock = cache
|
diff.player_clock = cache
|
||||||
.apply_diff_to_table::<PlayerClock>("player_clock", &self.player_clock)
|
.apply_diff_to_table::<PlayerClock>("player_clock", &self.player_clock)
|
||||||
.with_updates_by_pk(|row| &row.player_id);
|
|
||||||
diff.player_config = cache
|
|
||||||
.apply_diff_to_table::<PlayerConfig>("player_config", &self.player_config)
|
|
||||||
.with_updates_by_pk(|row| &row.id);
|
.with_updates_by_pk(|row| &row.id);
|
||||||
diff.user = cache
|
|
||||||
.apply_diff_to_table::<User>("user", &self.user)
|
|
||||||
.with_updates_by_pk(|row| &row.identity);
|
|
||||||
diff.view_closed_hands =
|
diff.view_closed_hands =
|
||||||
cache.apply_diff_to_table::<HandView>("view_closed_hands", &self.view_closed_hands);
|
cache.apply_diff_to_table::<HandView>("view_closed_hands", &self.view_closed_hands);
|
||||||
diff.view_hand = cache.apply_diff_to_table::<PlayerHand>("view_hand", &self.view_hand);
|
diff.view_hand = cache.apply_diff_to_table::<PlayerHand>("view_hand", &self.view_hand);
|
||||||
|
|
@ -219,18 +224,18 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||||
"bot" => db_update
|
"bot" => db_update
|
||||||
.bot
|
.bot
|
||||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||||
|
"game_timer" => db_update
|
||||||
|
.game_timer
|
||||||
|
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||||
"lobby" => db_update
|
"lobby" => db_update
|
||||||
.lobby
|
.lobby
|
||||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||||
|
"player" => db_update
|
||||||
|
.player
|
||||||
|
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||||
"player_clock" => db_update
|
"player_clock" => db_update
|
||||||
.player_clock
|
.player_clock
|
||||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||||
"player_config" => db_update
|
|
||||||
.player_config
|
|
||||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
|
||||||
"user" => db_update
|
|
||||||
.user
|
|
||||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
|
||||||
"view_closed_hands" => db_update
|
"view_closed_hands" => db_update
|
||||||
.view_closed_hands
|
.view_closed_hands
|
||||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||||
|
|
@ -253,18 +258,18 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||||
"bot" => db_update
|
"bot" => db_update
|
||||||
.bot
|
.bot
|
||||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||||
|
"game_timer" => db_update
|
||||||
|
.game_timer
|
||||||
|
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||||
"lobby" => db_update
|
"lobby" => db_update
|
||||||
.lobby
|
.lobby
|
||||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||||
|
"player" => db_update
|
||||||
|
.player
|
||||||
|
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||||
"player_clock" => db_update
|
"player_clock" => db_update
|
||||||
.player_clock
|
.player_clock
|
||||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||||
"player_config" => db_update
|
|
||||||
.player_config
|
|
||||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
|
||||||
"user" => db_update
|
|
||||||
.user
|
|
||||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
|
||||||
"view_closed_hands" => db_update
|
"view_closed_hands" => db_update
|
||||||
.view_closed_hands
|
.view_closed_hands
|
||||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||||
|
|
@ -287,10 +292,10 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct AppliedDiff<'r> {
|
pub struct AppliedDiff<'r> {
|
||||||
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>,
|
||||||
|
player: __sdk::TableAppliedDiff<'r, Player>,
|
||||||
player_clock: __sdk::TableAppliedDiff<'r, PlayerClock>,
|
player_clock: __sdk::TableAppliedDiff<'r, PlayerClock>,
|
||||||
player_config: __sdk::TableAppliedDiff<'r, PlayerConfig>,
|
|
||||||
user: __sdk::TableAppliedDiff<'r, User>,
|
|
||||||
view_closed_hands: __sdk::TableAppliedDiff<'r, HandView>,
|
view_closed_hands: __sdk::TableAppliedDiff<'r, HandView>,
|
||||||
view_hand: __sdk::TableAppliedDiff<'r, PlayerHand>,
|
view_hand: __sdk::TableAppliedDiff<'r, PlayerHand>,
|
||||||
__unused: std::marker::PhantomData<&'r ()>,
|
__unused: std::marker::PhantomData<&'r ()>,
|
||||||
|
|
@ -307,18 +312,14 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
|
||||||
callbacks: &mut __sdk::DbCallbacks<RemoteModule>,
|
callbacks: &mut __sdk::DbCallbacks<RemoteModule>,
|
||||||
) {
|
) {
|
||||||
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>("player", &self.player, event);
|
||||||
callbacks.invoke_table_row_callbacks::<PlayerClock>(
|
callbacks.invoke_table_row_callbacks::<PlayerClock>(
|
||||||
"player_clock",
|
"player_clock",
|
||||||
&self.player_clock,
|
&self.player_clock,
|
||||||
event,
|
event,
|
||||||
);
|
);
|
||||||
callbacks.invoke_table_row_callbacks::<PlayerConfig>(
|
|
||||||
"player_config",
|
|
||||||
&self.player_config,
|
|
||||||
event,
|
|
||||||
);
|
|
||||||
callbacks.invoke_table_row_callbacks::<User>("user", &self.user, event);
|
|
||||||
callbacks.invoke_table_row_callbacks::<HandView>(
|
callbacks.invoke_table_row_callbacks::<HandView>(
|
||||||
"view_closed_hands",
|
"view_closed_hands",
|
||||||
&self.view_closed_hands,
|
&self.view_closed_hands,
|
||||||
|
|
@ -970,19 +971,19 @@ impl __sdk::SpacetimeModule for RemoteModule {
|
||||||
|
|
||||||
fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
|
fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
|
||||||
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);
|
||||||
|
player_table::register_table(client_cache);
|
||||||
player_clock_table::register_table(client_cache);
|
player_clock_table::register_table(client_cache);
|
||||||
player_config_table::register_table(client_cache);
|
|
||||||
user_table::register_table(client_cache);
|
|
||||||
view_closed_hands_table::register_table(client_cache);
|
view_closed_hands_table::register_table(client_cache);
|
||||||
view_hand_table::register_table(client_cache);
|
view_hand_table::register_table(client_cache);
|
||||||
}
|
}
|
||||||
const ALL_TABLE_NAMES: &'static [&'static str] = &[
|
const ALL_TABLE_NAMES: &'static [&'static str] = &[
|
||||||
"bot",
|
"bot",
|
||||||
|
"game_timer",
|
||||||
"lobby",
|
"lobby",
|
||||||
|
"player",
|
||||||
"player_clock",
|
"player_clock",
|
||||||
"player_config",
|
|
||||||
"user",
|
|
||||||
"view_closed_hands",
|
"view_closed_hands",
|
||||||
"view_hand",
|
"view_hand",
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,36 @@ impl<'ctx> __sdk::TableWithPrimaryKey for PlayerClockTableHandle<'ctx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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`,
|
/// Access to the `player_id` unique index on the table `player_clock`,
|
||||||
/// which allows point queries on the field of the same name
|
/// which allows point queries on the field of the same name
|
||||||
/// via the [`PlayerClockPlayerIdUnique::find`] method.
|
/// via the [`PlayerClockPlayerIdUnique::find`] method.
|
||||||
|
|
@ -128,6 +158,7 @@ impl<'ctx> PlayerClockPlayerIdUnique<'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::<PlayerClock>("player_clock");
|
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);
|
_table.add_unique_constraint::<u32>("player_id", |row| &row.player_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ 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 struct PlayerClock {
|
pub struct PlayerClock {
|
||||||
|
pub id: u32,
|
||||||
pub player_id: u32,
|
pub player_id: u32,
|
||||||
pub renewable: u16,
|
pub renewable: u16,
|
||||||
pub total: u16,
|
pub total: u16,
|
||||||
|
|
@ -20,6 +21,7 @@ impl __sdk::InModule for PlayerClock {
|
||||||
///
|
///
|
||||||
/// Provides typed access to columns for query building.
|
/// Provides typed access to columns for query building.
|
||||||
pub struct PlayerClockCols {
|
pub struct PlayerClockCols {
|
||||||
|
pub id: __sdk::__query_builder::Col<PlayerClock, u32>,
|
||||||
pub player_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 renewable: __sdk::__query_builder::Col<PlayerClock, u16>,
|
||||||
pub total: __sdk::__query_builder::Col<PlayerClock, u16>,
|
pub total: __sdk::__query_builder::Col<PlayerClock, u16>,
|
||||||
|
|
@ -29,6 +31,7 @@ impl __sdk::__query_builder::HasCols for PlayerClock {
|
||||||
type Cols = PlayerClockCols;
|
type Cols = PlayerClockCols;
|
||||||
fn cols(table_name: &'static str) -> Self::Cols {
|
fn cols(table_name: &'static str) -> Self::Cols {
|
||||||
PlayerClockCols {
|
PlayerClockCols {
|
||||||
|
id: __sdk::__query_builder::Col::new(table_name, "id"),
|
||||||
player_id: __sdk::__query_builder::Col::new(table_name, "player_id"),
|
player_id: __sdk::__query_builder::Col::new(table_name, "player_id"),
|
||||||
renewable: __sdk::__query_builder::Col::new(table_name, "renewable"),
|
renewable: __sdk::__query_builder::Col::new(table_name, "renewable"),
|
||||||
total: __sdk::__query_builder::Col::new(table_name, "total"),
|
total: __sdk::__query_builder::Col::new(table_name, "total"),
|
||||||
|
|
@ -40,6 +43,7 @@ impl __sdk::__query_builder::HasCols for PlayerClock {
|
||||||
///
|
///
|
||||||
/// Provides typed access to indexed columns for query building.
|
/// Provides typed access to indexed columns for query building.
|
||||||
pub struct PlayerClockIxCols {
|
pub struct PlayerClockIxCols {
|
||||||
|
pub id: __sdk::__query_builder::IxCol<PlayerClock, u32>,
|
||||||
pub player_id: __sdk::__query_builder::IxCol<PlayerClock, u32>,
|
pub player_id: __sdk::__query_builder::IxCol<PlayerClock, u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,6 +51,7 @@ impl __sdk::__query_builder::HasIxCols for PlayerClock {
|
||||||
type IxCols = PlayerClockIxCols;
|
type IxCols = PlayerClockIxCols;
|
||||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||||
PlayerClockIxCols {
|
PlayerClockIxCols {
|
||||||
|
id: __sdk::__query_builder::IxCol::new(table_name, "id"),
|
||||||
player_id: __sdk::__query_builder::IxCol::new(table_name, "player_id"),
|
player_id: __sdk::__query_builder::IxCol::new(table_name, "player_id"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,159 +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_config_type::PlayerConfig;
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
/// Table handle for the table `player_config`.
|
|
||||||
///
|
|
||||||
/// Obtain a handle from the [`PlayerConfigTableAccess::player_config`] method on [`super::RemoteTables`],
|
|
||||||
/// like `ctx.db.player_config()`.
|
|
||||||
///
|
|
||||||
/// Users are encouraged not to explicitly reference this type,
|
|
||||||
/// but to directly chain method calls,
|
|
||||||
/// like `ctx.db.player_config().on_insert(...)`.
|
|
||||||
pub struct PlayerConfigTableHandle<'ctx> {
|
|
||||||
imp: __sdk::TableHandle<PlayerConfig>,
|
|
||||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the table `player_config`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteTables`].
|
|
||||||
pub trait PlayerConfigTableAccess {
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
/// Obtain a [`PlayerConfigTableHandle`], which mediates access to the table `player_config`.
|
|
||||||
fn player_config(&self) -> PlayerConfigTableHandle<'_>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PlayerConfigTableAccess for super::RemoteTables {
|
|
||||||
fn player_config(&self) -> PlayerConfigTableHandle<'_> {
|
|
||||||
PlayerConfigTableHandle {
|
|
||||||
imp: self.imp.get_table::<PlayerConfig>("player_config"),
|
|
||||||
ctx: std::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct PlayerConfigInsertCallbackId(__sdk::CallbackId);
|
|
||||||
pub struct PlayerConfigDeleteCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
impl<'ctx> __sdk::Table for PlayerConfigTableHandle<'ctx> {
|
|
||||||
type Row = PlayerConfig;
|
|
||||||
type EventContext = super::EventContext;
|
|
||||||
|
|
||||||
fn count(&self) -> u64 {
|
|
||||||
self.imp.count()
|
|
||||||
}
|
|
||||||
fn iter(&self) -> impl Iterator<Item = PlayerConfig> + '_ {
|
|
||||||
self.imp.iter()
|
|
||||||
}
|
|
||||||
|
|
||||||
type InsertCallbackId = PlayerConfigInsertCallbackId;
|
|
||||||
|
|
||||||
fn on_insert(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> PlayerConfigInsertCallbackId {
|
|
||||||
PlayerConfigInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_insert(&self, callback: PlayerConfigInsertCallbackId) {
|
|
||||||
self.imp.remove_on_insert(callback.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteCallbackId = PlayerConfigDeleteCallbackId;
|
|
||||||
|
|
||||||
fn on_delete(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> PlayerConfigDeleteCallbackId {
|
|
||||||
PlayerConfigDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_delete(&self, callback: PlayerConfigDeleteCallbackId) {
|
|
||||||
self.imp.remove_on_delete(callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct PlayerConfigUpdateCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
impl<'ctx> __sdk::TableWithPrimaryKey for PlayerConfigTableHandle<'ctx> {
|
|
||||||
type UpdateCallbackId = PlayerConfigUpdateCallbackId;
|
|
||||||
|
|
||||||
fn on_update(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
|
||||||
) -> PlayerConfigUpdateCallbackId {
|
|
||||||
PlayerConfigUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_update(&self, callback: PlayerConfigUpdateCallbackId) {
|
|
||||||
self.imp.remove_on_update(callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Access to the `id` unique index on the table `player_config`,
|
|
||||||
/// which allows point queries on the field of the same name
|
|
||||||
/// via the [`PlayerConfigIdUnique::find`] method.
|
|
||||||
///
|
|
||||||
/// Users are encouraged not to explicitly reference this type,
|
|
||||||
/// but to directly chain method calls,
|
|
||||||
/// like `ctx.db.player_config().id().find(...)`.
|
|
||||||
pub struct PlayerConfigIdUnique<'ctx> {
|
|
||||||
imp: __sdk::UniqueConstraintHandle<PlayerConfig, u32>,
|
|
||||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ctx> PlayerConfigTableHandle<'ctx> {
|
|
||||||
/// Get a handle on the `id` unique index on the table `player_config`.
|
|
||||||
pub fn id(&self) -> PlayerConfigIdUnique<'ctx> {
|
|
||||||
PlayerConfigIdUnique {
|
|
||||||
imp: self.imp.get_unique_constraint::<u32>("id"),
|
|
||||||
phantom: std::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ctx> PlayerConfigIdUnique<'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<PlayerConfig> {
|
|
||||||
self.imp.find(col_val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
|
||||||
let _table = client_cache.get_or_make_table::<PlayerConfig>("player_config");
|
|
||||||
_table.add_unique_constraint::<u32>("id", |row| &row.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub(super) fn parse_table_update(
|
|
||||||
raw_updates: __ws::v2::TableUpdate,
|
|
||||||
) -> __sdk::Result<__sdk::TableUpdate<PlayerConfig>> {
|
|
||||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
|
||||||
__sdk::InternalError::failed_parse("TableUpdate<PlayerConfig>", "TableUpdate")
|
|
||||||
.with_cause(e)
|
|
||||||
.into()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for query builder access to the table `PlayerConfig`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
|
||||||
pub trait player_configQueryTableAccess {
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
/// Get a query builder for the table `PlayerConfig`.
|
|
||||||
fn player_config(&self) -> __sdk::__query_builder::Table<PlayerConfig>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl player_configQueryTableAccess for __sdk::QueryTableAccessor {
|
|
||||||
fn player_config(&self) -> __sdk::__query_builder::Table<PlayerConfig> {
|
|
||||||
__sdk::__query_builder::Table::new("player_config")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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 PlayerConfig {
|
|
||||||
pub id: u32,
|
|
||||||
pub name: String,
|
|
||||||
pub ready: bool,
|
|
||||||
pub sort: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::InModule for PlayerConfig {
|
|
||||||
type Module = super::RemoteModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Column accessor struct for the table `PlayerConfig`.
|
|
||||||
///
|
|
||||||
/// Provides typed access to columns for query building.
|
|
||||||
pub struct PlayerConfigCols {
|
|
||||||
pub id: __sdk::__query_builder::Col<PlayerConfig, u32>,
|
|
||||||
pub name: __sdk::__query_builder::Col<PlayerConfig, String>,
|
|
||||||
pub ready: __sdk::__query_builder::Col<PlayerConfig, bool>,
|
|
||||||
pub sort: __sdk::__query_builder::Col<PlayerConfig, bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for PlayerConfig {
|
|
||||||
type Cols = PlayerConfigCols;
|
|
||||||
fn cols(table_name: &'static str) -> Self::Cols {
|
|
||||||
PlayerConfigCols {
|
|
||||||
id: __sdk::__query_builder::Col::new(table_name, "id"),
|
|
||||||
name: __sdk::__query_builder::Col::new(table_name, "name"),
|
|
||||||
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 `PlayerConfig`.
|
|
||||||
///
|
|
||||||
/// Provides typed access to indexed columns for query building.
|
|
||||||
pub struct PlayerConfigIxCols {
|
|
||||||
pub id: __sdk::__query_builder::IxCol<PlayerConfig, u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasIxCols for PlayerConfig {
|
|
||||||
type IxCols = PlayerConfigIxCols;
|
|
||||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
|
||||||
PlayerConfigIxCols {
|
|
||||||
id: __sdk::__query_builder::IxCol::new(table_name, "id"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::__query_builder::CanBeLookupTable for PlayerConfig {}
|
|
||||||
|
|
@ -10,10 +10,11 @@ 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 PlayerHand {
|
pub struct PlayerHand {
|
||||||
|
pub id: u32,
|
||||||
pub player_id: u32,
|
pub player_id: u32,
|
||||||
pub turn_state: TurnState,
|
pub turn_state: TurnState,
|
||||||
pub hand: Vec<DbTile>,
|
|
||||||
pub pond: Vec<DbTile>,
|
pub pond: Vec<DbTile>,
|
||||||
|
pub hand: Vec<DbTile>,
|
||||||
pub working_tile: Option<DbTile>,
|
pub working_tile: Option<DbTile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -25,10 +26,11 @@ impl __sdk::InModule for PlayerHand {
|
||||||
///
|
///
|
||||||
/// Provides typed access to columns for query building.
|
/// Provides typed access to columns for query building.
|
||||||
pub struct PlayerHandCols {
|
pub struct PlayerHandCols {
|
||||||
|
pub id: __sdk::__query_builder::Col<PlayerHand, u32>,
|
||||||
pub player_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 turn_state: __sdk::__query_builder::Col<PlayerHand, TurnState>,
|
||||||
pub hand: __sdk::__query_builder::Col<PlayerHand, Vec<DbTile>>,
|
|
||||||
pub pond: __sdk::__query_builder::Col<PlayerHand, Vec<DbTile>>,
|
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>>,
|
pub working_tile: __sdk::__query_builder::Col<PlayerHand, Option<DbTile>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,10 +38,11 @@ impl __sdk::__query_builder::HasCols for PlayerHand {
|
||||||
type Cols = PlayerHandCols;
|
type Cols = PlayerHandCols;
|
||||||
fn cols(table_name: &'static str) -> Self::Cols {
|
fn cols(table_name: &'static str) -> Self::Cols {
|
||||||
PlayerHandCols {
|
PlayerHandCols {
|
||||||
|
id: __sdk::__query_builder::Col::new(table_name, "id"),
|
||||||
player_id: __sdk::__query_builder::Col::new(table_name, "player_id"),
|
player_id: __sdk::__query_builder::Col::new(table_name, "player_id"),
|
||||||
turn_state: __sdk::__query_builder::Col::new(table_name, "turn_state"),
|
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"),
|
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"),
|
working_tile: __sdk::__query_builder::Col::new(table_name, "working_tile"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -49,6 +52,7 @@ impl __sdk::__query_builder::HasCols for PlayerHand {
|
||||||
///
|
///
|
||||||
/// Provides typed access to indexed columns for query building.
|
/// Provides typed access to indexed columns for query building.
|
||||||
pub struct PlayerHandIxCols {
|
pub struct PlayerHandIxCols {
|
||||||
|
pub id: __sdk::__query_builder::IxCol<PlayerHand, u32>,
|
||||||
pub player_id: __sdk::__query_builder::IxCol<PlayerHand, u32>,
|
pub player_id: __sdk::__query_builder::IxCol<PlayerHand, u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,6 +60,7 @@ impl __sdk::__query_builder::HasIxCols for PlayerHand {
|
||||||
type IxCols = PlayerHandIxCols;
|
type IxCols = PlayerHandIxCols;
|
||||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||||
PlayerHandIxCols {
|
PlayerHandIxCols {
|
||||||
|
id: __sdk::__query_builder::IxCol::new(table_name, "id"),
|
||||||
player_id: __sdk::__query_builder::IxCol::new(table_name, "player_id"),
|
player_id: __sdk::__query_builder::IxCol::new(table_name, "player_id"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
jong-db/src/db/player_or_bot_type.rs
Normal file
17
jong-db/src/db/player_or_bot_type.rs
Normal 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 enum PlayerOrBot {
|
||||||
|
Player(u32),
|
||||||
|
|
||||||
|
Bot(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for PlayerOrBot {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
192
jong-db/src/db/player_table.rs
Normal file
192
jong-db/src/db/player_table.rs
Normal file
|
|
@ -0,0 +1,192 @@
|
||||||
|
// 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 `player`.
|
||||||
|
///
|
||||||
|
/// Obtain a handle from the [`PlayerTableAccess::player`] method on [`super::RemoteTables`],
|
||||||
|
/// like `ctx.db.player()`.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.player().on_insert(...)`.
|
||||||
|
pub struct PlayerTableHandle<'ctx> {
|
||||||
|
imp: __sdk::TableHandle<Player>,
|
||||||
|
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the table `player`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteTables`].
|
||||||
|
pub trait PlayerTableAccess {
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
/// Obtain a [`PlayerTableHandle`], which mediates access to the table `player`.
|
||||||
|
fn player(&self) -> PlayerTableHandle<'_>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PlayerTableAccess for super::RemoteTables {
|
||||||
|
fn player(&self) -> PlayerTableHandle<'_> {
|
||||||
|
PlayerTableHandle {
|
||||||
|
imp: self.imp.get_table::<Player>("player"),
|
||||||
|
ctx: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PlayerInsertCallbackId(__sdk::CallbackId);
|
||||||
|
pub struct PlayerDeleteCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::Table for PlayerTableHandle<'ctx> {
|
||||||
|
type Row = Player;
|
||||||
|
type EventContext = super::EventContext;
|
||||||
|
|
||||||
|
fn count(&self) -> u64 {
|
||||||
|
self.imp.count()
|
||||||
|
}
|
||||||
|
fn iter(&self) -> impl Iterator<Item = Player> + '_ {
|
||||||
|
self.imp.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
type InsertCallbackId = PlayerInsertCallbackId;
|
||||||
|
|
||||||
|
fn on_insert(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||||
|
) -> PlayerInsertCallbackId {
|
||||||
|
PlayerInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_insert(&self, callback: PlayerInsertCallbackId) {
|
||||||
|
self.imp.remove_on_insert(callback.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteCallbackId = PlayerDeleteCallbackId;
|
||||||
|
|
||||||
|
fn on_delete(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||||
|
) -> PlayerDeleteCallbackId {
|
||||||
|
PlayerDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_delete(&self, callback: PlayerDeleteCallbackId) {
|
||||||
|
self.imp.remove_on_delete(callback.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PlayerUpdateCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::TableWithPrimaryKey for PlayerTableHandle<'ctx> {
|
||||||
|
type UpdateCallbackId = PlayerUpdateCallbackId;
|
||||||
|
|
||||||
|
fn on_update(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||||
|
) -> PlayerUpdateCallbackId {
|
||||||
|
PlayerUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_update(&self, callback: PlayerUpdateCallbackId) {
|
||||||
|
self.imp.remove_on_update(callback.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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`,
|
||||||
|
/// which allows point queries on the field of the same name
|
||||||
|
/// via the [`PlayerIdentityUnique::find`] method.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.player().identity().find(...)`.
|
||||||
|
pub struct PlayerIdentityUnique<'ctx> {
|
||||||
|
imp: __sdk::UniqueConstraintHandle<Player, __sdk::Identity>,
|
||||||
|
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> PlayerTableHandle<'ctx> {
|
||||||
|
/// Get a handle on the `identity` unique index on the table `player`.
|
||||||
|
pub fn identity(&self) -> PlayerIdentityUnique<'ctx> {
|
||||||
|
PlayerIdentityUnique {
|
||||||
|
imp: self
|
||||||
|
.imp
|
||||||
|
.get_unique_constraint::<__sdk::Identity>("identity"),
|
||||||
|
phantom: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> PlayerIdentityUnique<'ctx> {
|
||||||
|
/// Find the subscribed row whose `identity` column value is equal to `col_val`,
|
||||||
|
/// if such a row is present in the client cache.
|
||||||
|
pub fn find(&self, col_val: &__sdk::Identity) -> Option<Player> {
|
||||||
|
self.imp.find(col_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub(super) fn parse_table_update(
|
||||||
|
raw_updates: __ws::v2::TableUpdate,
|
||||||
|
) -> __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()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for query builder access to the table `Player`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||||
|
pub trait playerQueryTableAccess {
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
/// Get a query builder for the table `Player`.
|
||||||
|
fn player(&self) -> __sdk::__query_builder::Table<Player>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl playerQueryTableAccess for __sdk::QueryTableAccessor {
|
||||||
|
fn player(&self) -> __sdk::__query_builder::Table<Player> {
|
||||||
|
__sdk::__query_builder::Table::new("player")
|
||||||
|
}
|
||||||
|
}
|
||||||
68
jong-db/src/db/player_type.rs
Normal file
68
jong-db/src/db/player_type.rs
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
// 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 Player {
|
||||||
|
pub id: u32,
|
||||||
|
pub identity: __sdk::Identity,
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub lobby_id: u32,
|
||||||
|
pub ready: bool,
|
||||||
|
pub sort: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for Player {
|
||||||
|
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"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::__query_builder::CanBeLookupTable for Player {}
|
||||||
|
|
@ -1,192 +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::user_type::User;
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
/// Table handle for the table `user`.
|
|
||||||
///
|
|
||||||
/// Obtain a handle from the [`UserTableAccess::user`] method on [`super::RemoteTables`],
|
|
||||||
/// like `ctx.db.user()`.
|
|
||||||
///
|
|
||||||
/// Users are encouraged not to explicitly reference this type,
|
|
||||||
/// but to directly chain method calls,
|
|
||||||
/// like `ctx.db.user().on_insert(...)`.
|
|
||||||
pub struct UserTableHandle<'ctx> {
|
|
||||||
imp: __sdk::TableHandle<User>,
|
|
||||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the table `user`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteTables`].
|
|
||||||
pub trait UserTableAccess {
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
/// Obtain a [`UserTableHandle`], which mediates access to the table `user`.
|
|
||||||
fn user(&self) -> UserTableHandle<'_>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UserTableAccess for super::RemoteTables {
|
|
||||||
fn user(&self) -> UserTableHandle<'_> {
|
|
||||||
UserTableHandle {
|
|
||||||
imp: self.imp.get_table::<User>("user"),
|
|
||||||
ctx: std::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct UserInsertCallbackId(__sdk::CallbackId);
|
|
||||||
pub struct UserDeleteCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
impl<'ctx> __sdk::Table for UserTableHandle<'ctx> {
|
|
||||||
type Row = User;
|
|
||||||
type EventContext = super::EventContext;
|
|
||||||
|
|
||||||
fn count(&self) -> u64 {
|
|
||||||
self.imp.count()
|
|
||||||
}
|
|
||||||
fn iter(&self) -> impl Iterator<Item = User> + '_ {
|
|
||||||
self.imp.iter()
|
|
||||||
}
|
|
||||||
|
|
||||||
type InsertCallbackId = UserInsertCallbackId;
|
|
||||||
|
|
||||||
fn on_insert(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> UserInsertCallbackId {
|
|
||||||
UserInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_insert(&self, callback: UserInsertCallbackId) {
|
|
||||||
self.imp.remove_on_insert(callback.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteCallbackId = UserDeleteCallbackId;
|
|
||||||
|
|
||||||
fn on_delete(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> UserDeleteCallbackId {
|
|
||||||
UserDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_delete(&self, callback: UserDeleteCallbackId) {
|
|
||||||
self.imp.remove_on_delete(callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct UserUpdateCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
impl<'ctx> __sdk::TableWithPrimaryKey for UserTableHandle<'ctx> {
|
|
||||||
type UpdateCallbackId = UserUpdateCallbackId;
|
|
||||||
|
|
||||||
fn on_update(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
|
||||||
) -> UserUpdateCallbackId {
|
|
||||||
UserUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_update(&self, callback: UserUpdateCallbackId) {
|
|
||||||
self.imp.remove_on_update(callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Access to the `identity` unique index on the table `user`,
|
|
||||||
/// which allows point queries on the field of the same name
|
|
||||||
/// via the [`UserIdentityUnique::find`] method.
|
|
||||||
///
|
|
||||||
/// Users are encouraged not to explicitly reference this type,
|
|
||||||
/// but to directly chain method calls,
|
|
||||||
/// like `ctx.db.user().identity().find(...)`.
|
|
||||||
pub struct UserIdentityUnique<'ctx> {
|
|
||||||
imp: __sdk::UniqueConstraintHandle<User, __sdk::Identity>,
|
|
||||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ctx> UserTableHandle<'ctx> {
|
|
||||||
/// Get a handle on the `identity` unique index on the table `user`.
|
|
||||||
pub fn identity(&self) -> UserIdentityUnique<'ctx> {
|
|
||||||
UserIdentityUnique {
|
|
||||||
imp: self
|
|
||||||
.imp
|
|
||||||
.get_unique_constraint::<__sdk::Identity>("identity"),
|
|
||||||
phantom: std::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ctx> UserIdentityUnique<'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<User> {
|
|
||||||
self.imp.find(col_val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Access to the `config_id` unique index on the table `user`,
|
|
||||||
/// which allows point queries on the field of the same name
|
|
||||||
/// via the [`UserConfigIdUnique::find`] method.
|
|
||||||
///
|
|
||||||
/// Users are encouraged not to explicitly reference this type,
|
|
||||||
/// but to directly chain method calls,
|
|
||||||
/// like `ctx.db.user().config_id().find(...)`.
|
|
||||||
pub struct UserConfigIdUnique<'ctx> {
|
|
||||||
imp: __sdk::UniqueConstraintHandle<User, u32>,
|
|
||||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ctx> UserTableHandle<'ctx> {
|
|
||||||
/// Get a handle on the `config_id` unique index on the table `user`.
|
|
||||||
pub fn config_id(&self) -> UserConfigIdUnique<'ctx> {
|
|
||||||
UserConfigIdUnique {
|
|
||||||
imp: self.imp.get_unique_constraint::<u32>("config_id"),
|
|
||||||
phantom: std::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ctx> UserConfigIdUnique<'ctx> {
|
|
||||||
/// Find the subscribed row whose `config_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<User> {
|
|
||||||
self.imp.find(col_val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
|
||||||
let _table = client_cache.get_or_make_table::<User>("user");
|
|
||||||
_table.add_unique_constraint::<__sdk::Identity>("identity", |row| &row.identity);
|
|
||||||
_table.add_unique_constraint::<u32>("config_id", |row| &row.config_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub(super) fn parse_table_update(
|
|
||||||
raw_updates: __ws::v2::TableUpdate,
|
|
||||||
) -> __sdk::Result<__sdk::TableUpdate<User>> {
|
|
||||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
|
||||||
__sdk::InternalError::failed_parse("TableUpdate<User>", "TableUpdate")
|
|
||||||
.with_cause(e)
|
|
||||||
.into()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for query builder access to the table `User`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
|
||||||
pub trait userQueryTableAccess {
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
/// Get a query builder for the table `User`.
|
|
||||||
fn user(&self) -> __sdk::__query_builder::Table<User>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl userQueryTableAccess for __sdk::QueryTableAccessor {
|
|
||||||
fn user(&self) -> __sdk::__query_builder::Table<User> {
|
|
||||||
__sdk::__query_builder::Table::new("user")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,62 +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 User {
|
|
||||||
pub identity: __sdk::Identity,
|
|
||||||
pub name: String,
|
|
||||||
pub lobby_id: u32,
|
|
||||||
pub config_id: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::InModule for User {
|
|
||||||
type Module = super::RemoteModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Column accessor struct for the table `User`.
|
|
||||||
///
|
|
||||||
/// Provides typed access to columns for query building.
|
|
||||||
pub struct UserCols {
|
|
||||||
pub identity: __sdk::__query_builder::Col<User, __sdk::Identity>,
|
|
||||||
pub name: __sdk::__query_builder::Col<User, String>,
|
|
||||||
pub lobby_id: __sdk::__query_builder::Col<User, u32>,
|
|
||||||
pub config_id: __sdk::__query_builder::Col<User, u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasCols for User {
|
|
||||||
type Cols = UserCols;
|
|
||||||
fn cols(table_name: &'static str) -> Self::Cols {
|
|
||||||
UserCols {
|
|
||||||
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"),
|
|
||||||
config_id: __sdk::__query_builder::Col::new(table_name, "config_id"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Indexed column accessor struct for the table `User`.
|
|
||||||
///
|
|
||||||
/// Provides typed access to indexed columns for query building.
|
|
||||||
pub struct UserIxCols {
|
|
||||||
pub config_id: __sdk::__query_builder::IxCol<User, u32>,
|
|
||||||
pub identity: __sdk::__query_builder::IxCol<User, __sdk::Identity>,
|
|
||||||
pub lobby_id: __sdk::__query_builder::IxCol<User, u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::__query_builder::HasIxCols for User {
|
|
||||||
type IxCols = UserIxCols;
|
|
||||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
|
||||||
UserIxCols {
|
|
||||||
config_id: __sdk::__query_builder::IxCol::new(table_name, "config_id"),
|
|
||||||
identity: __sdk::__query_builder::IxCol::new(table_name, "identity"),
|
|
||||||
lobby_id: __sdk::__query_builder::IxCol::new(table_name, "lobby_id"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::__query_builder::CanBeLookupTable for User {}
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
// 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::hand_view_type::HandView;
|
use super::hand_view_type::HandView;
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
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 `view_closed_hands`.
|
/// Table handle for the table `view_closed_hands`.
|
||||||
|
|
|
||||||
|
|
@ -55,4 +55,13 @@ mod conversions {
|
||||||
Self::from_repr(value as usize).unwrap()
|
Self::from_repr(value as usize).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<&crate::db::PlayerOrBot> for jong_types::PlayerOrBot {
|
||||||
|
fn from(value: &crate::db::PlayerOrBot) -> Self {
|
||||||
|
match value {
|
||||||
|
crate::PlayerOrBot::Player(id) => Self::Player { id: *id },
|
||||||
|
crate::PlayerOrBot::Bot(id) => Self::Bot { id: *id },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,46 +3,68 @@
|
||||||
use log::{debug, trace};
|
use log::{debug, trace};
|
||||||
use spacetimedb::{ReducerContext, Table, reducer};
|
use spacetimedb::{ReducerContext, Table, reducer};
|
||||||
|
|
||||||
|
use crate::tables::*;
|
||||||
|
|
||||||
mod reducers;
|
mod reducers;
|
||||||
mod tables;
|
mod tables;
|
||||||
use crate::tables::*;
|
|
||||||
|
#[reducer]
|
||||||
|
pub fn clear_all(ctx: &ReducerContext) {
|
||||||
|
for row in ctx.db.player().iter() {
|
||||||
|
ctx.db.player().delete(row);
|
||||||
|
}
|
||||||
|
for row in ctx.db.lobby().iter() {
|
||||||
|
ctx.db.lobby().delete(row);
|
||||||
|
}
|
||||||
|
for row in ctx.db.bot().iter() {
|
||||||
|
ctx.db.bot().delete(row);
|
||||||
|
}
|
||||||
|
for row in ctx.db.wall().iter() {
|
||||||
|
ctx.db.wall().delete(row);
|
||||||
|
}
|
||||||
|
for row in ctx.db.tile().iter() {
|
||||||
|
ctx.db.tile().delete(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[reducer(client_connected)]
|
#[reducer(client_connected)]
|
||||||
pub fn connect(ctx: &ReducerContext) -> Result<(), String> {
|
pub fn connect(ctx: &ReducerContext) -> Result<(), String> {
|
||||||
let player = if let Some(player) = ctx.db.logged_out_user().identity().find(ctx.sender()) {
|
let player = if let Some(player) = ctx.db.logged_out_player().identity().find(ctx.sender()) {
|
||||||
let player = ctx.db.user().insert(player);
|
let player = ctx.db.player().insert(player);
|
||||||
ctx.db.logged_out_user().identity().delete(ctx.sender());
|
ctx.db.logged_out_player().identity().delete(ctx.sender());
|
||||||
player
|
player
|
||||||
} else {
|
} else {
|
||||||
debug!("inserting new user with identity {:?}", ctx.sender());
|
debug!("inserting new player with identity {:?}", ctx.sender());
|
||||||
ctx.db.user().try_insert(User {
|
ctx.db.player().try_insert(Player {
|
||||||
identity: ctx.sender(),
|
identity: ctx.sender(),
|
||||||
name: String::new(),
|
id: 0,
|
||||||
config_id: 0,
|
name: None,
|
||||||
lobby_id: 0,
|
lobby_id: 0,
|
||||||
|
ready: false,
|
||||||
|
sort: true,
|
||||||
})?
|
})?
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("user connected: {:?}", player);
|
debug!("player connected: {:?}", player);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[reducer(client_disconnected)]
|
#[reducer(client_disconnected)]
|
||||||
pub fn disconnect(ctx: &ReducerContext) -> Result<(), String> {
|
pub fn disconnect(ctx: &ReducerContext) -> Result<(), String> {
|
||||||
let user = ctx
|
let player = ctx
|
||||||
.db
|
.db
|
||||||
.user()
|
.player()
|
||||||
.identity()
|
.identity()
|
||||||
.find(ctx.sender())
|
.find(ctx.sender())
|
||||||
.ok_or_else(|| format!("can't find player {} to disconnect", ctx.sender()))?;
|
.ok_or_else(|| format!("can't find player {} to disconnect", ctx.sender()))?;
|
||||||
|
|
||||||
let user = ctx.db.logged_out_user().insert(user);
|
let player = ctx.db.logged_out_player().insert(player);
|
||||||
if !ctx.db.user().identity().delete(ctx.sender()) {
|
if !ctx.db.player().identity().delete(ctx.sender()) {
|
||||||
Err(format!("can't delete user: {user:?}"))?
|
Err("can't delete row")?
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("user disconnected: {:?}", user);
|
debug!("player disconnected: {:?}", player);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,11 @@ use spacetimedb::{
|
||||||
ReducerContext, ScheduleAt::Interval, Table as _, rand::seq::SliceRandom, reducer,
|
ReducerContext, ScheduleAt::Interval, Table as _, rand::seq::SliceRandom, reducer,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::tables::{
|
||||||
reducers::hand::{discard_tile, discard_tile_private},
|
DbTile, DbWall, GameTimer, Lobby, PlayerClock, PlayerHand, bot, game_timer, lobby as _, player,
|
||||||
tables::{
|
player_clock, player_hand, tile as _, wall,
|
||||||
DbTile, Lobby, LobbyTimer, PlayerClock, PlayerHand, Wall, bot, game_timer, lobby as _,
|
|
||||||
player_clock, player_config, player_hand, tile, user, wall,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use jong_types::{GameState, TurnState};
|
use jong_types::{GameState, PlayerOrBot, TurnState};
|
||||||
|
|
||||||
mod hand;
|
mod hand;
|
||||||
mod lobby;
|
mod lobby;
|
||||||
|
|
@ -25,7 +22,7 @@ pub fn advance_game(ctx: &ReducerContext) -> Result<(), String> {
|
||||||
.lobby_id()
|
.lobby_id()
|
||||||
.find(
|
.find(
|
||||||
ctx.db
|
ctx.db
|
||||||
.user()
|
.player()
|
||||||
.identity()
|
.identity()
|
||||||
.find(ctx.sender())
|
.find(ctx.sender())
|
||||||
.ok_or("player not in lobby")?
|
.ok_or("player not in lobby")?
|
||||||
|
|
@ -46,7 +43,8 @@ fn shuffle_wall(ctx: &ReducerContext, lobby: &mut Lobby) {
|
||||||
wall.shuffle(&mut rng);
|
wall.shuffle(&mut rng);
|
||||||
wall
|
wall
|
||||||
};
|
};
|
||||||
ctx.db.wall().insert(Wall {
|
ctx.db.wall().insert(DbWall {
|
||||||
|
// id: 0,
|
||||||
lobby_id: lobby.id,
|
lobby_id: lobby.id,
|
||||||
tiles,
|
tiles,
|
||||||
});
|
});
|
||||||
|
|
@ -55,17 +53,33 @@ fn shuffle_wall(ctx: &ReducerContext, lobby: &mut Lobby) {
|
||||||
|
|
||||||
fn deal_hands(ctx: &ReducerContext, lobby: &mut Lobby) -> Result<(), String> {
|
fn deal_hands(ctx: &ReducerContext, lobby: &mut Lobby) -> Result<(), String> {
|
||||||
let mut wall = ctx.db.wall().lobby_id().find(lobby.id).unwrap();
|
let mut wall = ctx.db.wall().lobby_id().find(lobby.id).unwrap();
|
||||||
for player in &lobby.players {
|
for pob in &lobby.players {
|
||||||
let mut tiles = wall.tiles.split_off(wall.tiles.len() - 13);
|
let mut tiles = wall.tiles.split_off(wall.tiles.len() - 13);
|
||||||
wall = ctx.db.wall().lobby_id().update(wall);
|
wall = ctx.db.wall().lobby_id().update(wall);
|
||||||
tiles.sort_by_key(|t| t.tile);
|
tiles.sort_by_key(|t| t.tile);
|
||||||
|
match pob {
|
||||||
|
PlayerOrBot::Player { id } if let Some(p) = ctx.db.player().id().find(id) => {
|
||||||
ctx.db.player_hand().insert(PlayerHand {
|
ctx.db.player_hand().insert(PlayerHand {
|
||||||
player_id: *player,
|
id: 0,
|
||||||
turn_state: TurnState::None,
|
player_id: p.id,
|
||||||
hand: tiles,
|
turn_state: jong_types::TurnState::None,
|
||||||
pond: vec![],
|
pond: vec![],
|
||||||
|
hand: tiles,
|
||||||
working_tile: None,
|
working_tile: None,
|
||||||
});
|
});
|
||||||
|
ctx.db.player_clock().insert(PlayerClock {
|
||||||
|
id: 0,
|
||||||
|
player_id: p.id,
|
||||||
|
renewable: 5,
|
||||||
|
total: 30,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
PlayerOrBot::Bot { id } if let Some(mut b) = ctx.db.bot().id().find(id) => {
|
||||||
|
b.hand = tiles;
|
||||||
|
ctx.db.bot().id().update(b);
|
||||||
|
}
|
||||||
|
_ => Err("couldn't find player or bot".to_string())?,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lobby.game_state = jong_types::states::GameState::Play;
|
lobby.game_state = jong_types::states::GameState::Play;
|
||||||
|
|
||||||
|
|
@ -73,10 +87,7 @@ fn deal_hands(ctx: &ReducerContext, lobby: &mut Lobby) -> Result<(), String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[reducer]
|
#[reducer]
|
||||||
pub fn advance_game_private(
|
pub fn advance_game_private(ctx: &ReducerContext, mut game_timer: GameTimer) -> Result<(), String> {
|
||||||
ctx: &ReducerContext,
|
|
||||||
mut game_timer: LobbyTimer,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
// checks every second (or more? when users make moves) on whether to advance the game's various states
|
// 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?
|
// TODO this, or allow player/debug to call this?
|
||||||
|
|
||||||
|
|
@ -88,21 +99,6 @@ pub fn advance_game_private(
|
||||||
// TODO keep a count to clear stale lobbies
|
// TODO keep a count to clear stale lobbies
|
||||||
// trace!("shuffle wall");
|
// trace!("shuffle wall");
|
||||||
shuffle_wall(ctx, &mut lobby);
|
shuffle_wall(ctx, &mut lobby);
|
||||||
|
|
||||||
lobby.players.shuffle(&mut ctx.rng());
|
|
||||||
|
|
||||||
for player_id in lobby
|
|
||||||
.players
|
|
||||||
.iter()
|
|
||||||
.filter(|id| ctx.db.user().config_id().find(*id).is_some())
|
|
||||||
{
|
|
||||||
ctx.db.player_clock().insert(PlayerClock {
|
|
||||||
player_id: *player_id,
|
|
||||||
renewable: 5,
|
|
||||||
total: 20,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.db.lobby().id().update(lobby);
|
ctx.db.lobby().id().update(lobby);
|
||||||
advance_game_private(ctx, game_timer)?;
|
advance_game_private(ctx, game_timer)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
@ -118,38 +114,32 @@ pub fn advance_game_private(
|
||||||
GameState::Play => {
|
GameState::Play => {
|
||||||
// trace!("in play");
|
// trace!("in play");
|
||||||
let curr_player = lobby.players.get(lobby.current_idx as usize).unwrap();
|
let curr_player = lobby.players.get(lobby.current_idx as usize).unwrap();
|
||||||
let mut hand = ctx.db.player_hand().player_id().find(curr_player).unwrap();
|
match curr_player {
|
||||||
|
PlayerOrBot::Player { id: player_id } => {
|
||||||
|
// trace!("current player is {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 {
|
match hand.turn_state {
|
||||||
TurnState::None => {
|
TurnState::None => {
|
||||||
// trace!("draw a tile");
|
trace!("draw a tile");
|
||||||
if let Some(mut wall) = ctx.db.wall().lobby_id().find(lobby.id)
|
if let Some(mut wall) = ctx.db.wall().lobby_id().find(lobby.id)
|
||||||
&& let Some(tile) = wall.tiles.pop()
|
&& let Some(tile) = wall.tiles.pop()
|
||||||
{
|
{
|
||||||
hand.working_tile = Some(tile);
|
hand.working_tile = Some(tile);
|
||||||
hand.turn_state = TurnState::Tsumo;
|
hand.turn_state = TurnState::Tsumo;
|
||||||
ctx.db.wall().lobby_id().update(wall);
|
ctx.db.wall().lobby_id().update(wall);
|
||||||
ctx.db.player_hand().player_id().update(hand);
|
ctx.db.player_hand().id().update(hand);
|
||||||
} else {
|
} else {
|
||||||
// TODO out of tiles
|
// TODO out of tiles
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TurnState::Tsumo => {
|
TurnState::Tsumo => {
|
||||||
// only real players have clocks?
|
// trace!("wait for discard");
|
||||||
if let Some(mut clock) = ctx.db.player_clock().player_id().find(curr_player)
|
if clock.tick() {
|
||||||
&& clock.tick()
|
ctx.db.player_clock().id().update(clock);
|
||||||
{
|
|
||||||
ctx.db.player_clock().player_id().update(clock);
|
|
||||||
} else {
|
} else {
|
||||||
// TODO bot / auto discard
|
// TODO auto-discard
|
||||||
discard_tile_private(
|
|
||||||
ctx,
|
|
||||||
lobby.id,
|
|
||||||
ctx.db.player_config().id().find(curr_player).unwrap(),
|
|
||||||
hand.working_tile.unwrap().id,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TurnState::Menzen => {}
|
TurnState::Menzen => {}
|
||||||
|
|
@ -158,12 +148,28 @@ pub fn advance_game_private(
|
||||||
TurnState::End => {}
|
TurnState::End => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PlayerOrBot::Bot { id: bot_id } => {
|
||||||
|
debug!("current bot is {bot_id}");
|
||||||
|
let bot = ctx.db.bot().id().find(bot_id).unwrap();
|
||||||
|
match bot.turn_state {
|
||||||
|
// TurnState::None => todo!(),
|
||||||
|
// TurnState::Tsumo => todo!(),
|
||||||
|
// TurnState::Menzen => todo!(),
|
||||||
|
// TurnState::RiichiKan => todo!(),
|
||||||
|
// TurnState::RonChiiPonKan => todo!(),
|
||||||
|
// TurnState::End => todo!(),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
lobby.next_player();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
GameState::Exit => {
|
GameState::Exit => {
|
||||||
// ctx.db.game_timer().id().delete(game_timer.id);
|
ctx.db.game_timer().id().delete(game_timer.id);
|
||||||
// ctx.db.lobby().id().delete(lobby.id);
|
ctx.db.lobby().id().delete(lobby.id);
|
||||||
// TODO reset all player lobbies, delete bots, etc?
|
// 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?
|
// is there a way to do this automatically, or rely on elsewhere's checks clearing the state?
|
||||||
todo!("lobby exit cleanup")
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO handle stale lobbies
|
// TODO handle stale lobbies
|
||||||
|
|
@ -174,10 +180,10 @@ pub fn advance_game_private(
|
||||||
// ctx.db.game_timer().id().update(game_timer);
|
// ctx.db.game_timer().id().update(game_timer);
|
||||||
ctx.db.lobby().id().update(lobby);
|
ctx.db.lobby().id().update(lobby);
|
||||||
} else {
|
} else {
|
||||||
// ctx.db.game_timer().id().delete(game_timer.id);
|
ctx.db.game_timer().id().delete(game_timer.id);
|
||||||
Err(format!(
|
Err(format!(
|
||||||
"ran schedule {} for empty lobby {}",
|
"ran schedule {} for empty lobby {}",
|
||||||
game_timer.scheduled_id, game_timer.lobby_id
|
game_timer.id, game_timer.lobby_id
|
||||||
))?;
|
))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,61 +8,57 @@ use crate::tables::*;
|
||||||
// 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.user().identity().find(ctx.sender()).unwrap();
|
let player = ctx.db.player().identity().find(ctx.sender()).unwrap();
|
||||||
let config = ctx.db.player_config().id().find(player.config_id).unwrap();
|
let mut hand = ctx.db.player_hand().player_id().find(player.id).unwrap();
|
||||||
|
|
||||||
discard_tile_private(ctx, player.lobby_id, config, tile_id)?;
|
// TODO we can probably remove a buncha these errors
|
||||||
|
let dealt_tile = if let Some(dealt) = ctx.db.tile().id().find(tile_id) {
|
||||||
Ok(())
|
if let Some(drawn) = hand.working_tile {
|
||||||
}
|
if drawn.id == dealt.id {
|
||||||
|
|
||||||
pub(crate) fn discard_tile_private(
|
|
||||||
ctx: &ReducerContext,
|
|
||||||
lobby_id: u32,
|
|
||||||
player_config: PlayerConfig,
|
|
||||||
tile_id: u32,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
let mut hand = ctx
|
|
||||||
.db
|
|
||||||
.player_hand()
|
|
||||||
.player_id()
|
|
||||||
.find(player_config.id)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let dealt = ctx.db.tile().id().find(tile_id).unwrap();
|
|
||||||
let drawn = hand.working_tile.unwrap();
|
|
||||||
|
|
||||||
let dealt_tile = if dealt.id == drawn.id {
|
|
||||||
// dealt from drawn tile
|
// dealt from drawn tile
|
||||||
dealt
|
dealt
|
||||||
} else if let Some((i, _)) = hand.hand.iter().enumerate().find(|(_, t)| dealt.id == t.id) {
|
} else if let Some((i, _)) = hand.hand.iter().enumerate().find(|(_, t)| t.id == tile_id)
|
||||||
|
{
|
||||||
// dealt from hand
|
// dealt from hand
|
||||||
let dealt = hand.hand.remove(i);
|
let dealt = hand.hand.remove(i);
|
||||||
hand.hand.push(drawn);
|
hand.hand.push(drawn);
|
||||||
if player_config.sort {
|
|
||||||
hand.hand.sort_by_key(|t| t.tile);
|
hand.hand.sort_by_key(|t| t.tile);
|
||||||
}
|
|
||||||
|
|
||||||
dealt
|
dealt
|
||||||
} else {
|
} else {
|
||||||
// ERROR
|
return Err(format!(
|
||||||
Err("dealt tile is missing")?
|
"player {} attempted to deal tile {} not in hand or drawn",
|
||||||
|
player.id, tile_id
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(format!(
|
||||||
|
"player {} attempted to deal tile {} without having drawn",
|
||||||
|
player.id, tile_id
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(format!(
|
||||||
|
"player {} attempted to deal nonexistant tile {}",
|
||||||
|
player.id, tile_id
|
||||||
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
hand.pond.push(dealt_tile);
|
hand.pond.push(dealt_tile);
|
||||||
hand.working_tile = None;
|
hand.working_tile = None;
|
||||||
hand.turn_state = TurnState::None;
|
hand.turn_state = TurnState::None;
|
||||||
ctx.db.player_hand().player_id().update(hand);
|
ctx.db.player_hand().id().update(hand);
|
||||||
|
|
||||||
if let Some(mut clock) = ctx.db.player_clock().player_id().find(player_config.id) {
|
let mut clock = ctx.db.player_clock().player_id().find(player.id).unwrap();
|
||||||
clock.renew();
|
clock.renew();
|
||||||
ctx.db.player_clock().player_id().update(clock);
|
ctx.db.player_clock().id().update(clock);
|
||||||
}
|
|
||||||
|
|
||||||
let mut lobby = ctx.db.lobby().id().find(lobby_id).unwrap();
|
let mut lobby = ctx.db.lobby().id().find(player.lobby_id).unwrap();
|
||||||
lobby.next_player();
|
lobby.next_player();
|
||||||
ctx.db.lobby().id().update(lobby);
|
ctx.db.lobby().id().update(lobby);
|
||||||
|
|
||||||
|
debug!("player {} discarded tile {:?}", player.id, dealt_tile.tile);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,96 +1,48 @@
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use log::{debug, info, warn};
|
use log::info;
|
||||||
use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer};
|
use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer};
|
||||||
|
|
||||||
|
use jong_types::PlayerOrBot;
|
||||||
|
|
||||||
use crate::{reducers::advance_game_private, tables::*};
|
use crate::{reducers::advance_game_private, 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 user = ctx
|
let mut player = ctx
|
||||||
.db
|
.db
|
||||||
.user()
|
.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()))?;
|
||||||
|
|
||||||
if lobby_id == 0 && user.lobby_id == 0 {
|
if lobby_id == 0 && player.lobby_id == 0 {
|
||||||
let player = ctx.db.player_config().insert(PlayerConfig {
|
// TODO check first if player is already in a lobby
|
||||||
id: 0,
|
|
||||||
name: String::new(),
|
|
||||||
ready: false,
|
|
||||||
sort: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
let lobby = ctx.db.lobby().insert(Lobby {
|
let lobby = ctx.db.lobby().insert(Lobby {
|
||||||
id: 0,
|
id: 0,
|
||||||
players: vec![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,
|
||||||
current_idx: 0,
|
current_idx: 0,
|
||||||
});
|
});
|
||||||
lobby_id = lobby.id;
|
|
||||||
info!("created lobby: {}", lobby.id);
|
info!("created lobby: {}", lobby.id);
|
||||||
|
|
||||||
user.config_id = player.id;
|
lobby_id = lobby.id;
|
||||||
user.lobby_id = lobby.id;
|
player.lobby_id = lobby_id;
|
||||||
} else {
|
} else {
|
||||||
let lobby = ctx
|
let lobby = ctx
|
||||||
.db
|
.db
|
||||||
.lobby()
|
.lobby()
|
||||||
.id()
|
.id()
|
||||||
.find(user.lobby_id)
|
.find(player.lobby_id)
|
||||||
.ok_or(format!("can't find lobby {}", user.lobby_id))?;
|
.ok_or(format!("can't find lobby {}", player.lobby_id))?;
|
||||||
lobby_id = lobby.id;
|
lobby_id = lobby.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
let user = ctx.db.user().identity().update(user);
|
let player = ctx.db.player().identity().update(player);
|
||||||
info!("user {} joined lobby {}", user.name, lobby_id);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[reducer]
|
|
||||||
pub fn set_ready(ctx: &ReducerContext, ready: bool) -> Result<(), String> {
|
|
||||||
let mut user = ctx.db.user().identity().find(ctx.sender()).unwrap();
|
|
||||||
let mut player = ctx.db.player_config().id().find(user.config_id).unwrap();
|
|
||||||
|
|
||||||
player.ready = ready;
|
|
||||||
let player = ctx.db.player_config().id().update(player);
|
|
||||||
|
|
||||||
if player.ready {
|
|
||||||
debug!("player readied");
|
|
||||||
} else {
|
|
||||||
debug!("player unreadied");
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(mut lobby) = ctx.db.lobby().id().find(user.lobby_id)
|
|
||||||
&& lobby.players.len() == 4
|
|
||||||
&& lobby.players.iter().all(|id| {
|
|
||||||
ctx.db
|
|
||||||
.player_config()
|
|
||||||
.id()
|
|
||||||
.find(id)
|
|
||||||
.is_some_and(|p| p.ready)
|
|
||||||
})
|
|
||||||
&& ctx.db.game_timer().lobby_id().find(user.lobby_id).is_none()
|
|
||||||
{
|
|
||||||
lobby.game_state = jong_types::states::GameState::Setup;
|
|
||||||
let lobby = ctx.db.lobby().id().update(lobby);
|
|
||||||
|
|
||||||
// TODO should we schedule this outside so that we can clear out stale lobbies?
|
|
||||||
let game_timer = ctx.db.game_timer().insert(LobbyTimer {
|
|
||||||
lobby_id: lobby.id,
|
|
||||||
scheduled_id: 0,
|
|
||||||
scheduled_at: spacetimedb::ScheduleAt::Interval(Duration::from_secs(1).into()),
|
|
||||||
});
|
|
||||||
|
|
||||||
advance_game_private(ctx, game_timer)?;
|
|
||||||
} else {
|
|
||||||
// TODO if lobby doesn't exist, reset player state?
|
|
||||||
// FIXME return error here
|
|
||||||
}
|
|
||||||
|
|
||||||
|
info!("player {} joined lobby {}", player.id, lobby_id);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -99,26 +51,57 @@ pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> {
|
||||||
if lobby_id == 0 {
|
if lobby_id == 0 {
|
||||||
Err("cannot add a bot without a lobby".into())
|
Err("cannot add a bot without a lobby".into())
|
||||||
} else if let Some(mut lobby) = ctx.db.lobby().id().find(lobby_id)
|
} else if let Some(mut lobby) = ctx.db.lobby().id().find(lobby_id)
|
||||||
&& (ctx.db.user().lobby_id().filter(lobby_id).count()
|
&& (ctx.db.player().lobby_id().filter(lobby_id).count()
|
||||||
+ ctx.db.bot().lobby_id().filter(lobby_id).count()
|
+ ctx.db.bot().lobby_id().filter(lobby_id).count()
|
||||||
< 4)
|
< 4)
|
||||||
{
|
{
|
||||||
let player = ctx.db.player_config().insert(PlayerConfig {
|
|
||||||
id: 0,
|
|
||||||
name: String::new(),
|
|
||||||
ready: true,
|
|
||||||
sort: false,
|
|
||||||
});
|
|
||||||
let bot = ctx.db.bot().insert(Bot {
|
let bot = ctx.db.bot().insert(Bot {
|
||||||
id: 0,
|
id: 0,
|
||||||
lobby_id,
|
lobby_id,
|
||||||
config_id: player.id,
|
hand: vec![],
|
||||||
|
pond: vec![],
|
||||||
|
working_tile: None,
|
||||||
|
turn_state: jong_types::TurnState::None,
|
||||||
});
|
});
|
||||||
lobby.players.push(player.id);
|
lobby.players.push(PlayerOrBot::Bot { id: bot.id });
|
||||||
ctx.db.lobby().id().update(lobby);
|
ctx.db.lobby().id().update(lobby);
|
||||||
info!("added bot {} to lobby {}", bot.id, lobby_id);
|
info!("added bot {} to lobby {}", bot.id, lobby_id);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(format!("lobby {lobby_id} doesn't exist or is full"))
|
Err("lobby doesn't exist".into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[reducer]
|
||||||
|
pub fn set_ready(ctx: &ReducerContext, ready: bool) -> Result<(), String> {
|
||||||
|
let mut player = ctx.db.player().identity().find(ctx.sender()).unwrap();
|
||||||
|
player.ready = ready;
|
||||||
|
player = ctx.db.player().identity().update(player);
|
||||||
|
|
||||||
|
if let Some(mut lobby) = ctx.db.lobby().id().find(player.lobby_id)
|
||||||
|
&& lobby.players.len() == 4
|
||||||
|
&& ctx.db.player().lobby_id().filter(lobby.id).all(|p| p.ready)
|
||||||
|
{
|
||||||
|
lobby.game_state = jong_types::states::GameState::Setup;
|
||||||
|
lobby.players.shuffle(&mut ctx.rng());
|
||||||
|
let lobby = ctx.db.lobby().id().update(lobby);
|
||||||
|
|
||||||
|
// TODO should we schedule this outside so that we can clear out stale lobbies?
|
||||||
|
let game_timer = ctx.db.game_timer().insert(GameTimer {
|
||||||
|
id: 0,
|
||||||
|
lobby_id: lobby.id,
|
||||||
|
scheduled_at: spacetimedb::ScheduleAt::Interval(Duration::from_secs(1).into()),
|
||||||
|
});
|
||||||
|
|
||||||
|
advance_game_private(ctx, game_timer)?;
|
||||||
|
} 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(())
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,13 @@
|
||||||
use spacetimedb::{Identity, SpacetimeType, ViewContext, table, view};
|
use spacetimedb::{SpacetimeType, ViewContext, table, view};
|
||||||
|
|
||||||
use jong_types::{
|
use jong_types::{
|
||||||
|
PlayerOrBot,
|
||||||
states::{GameState, TurnState},
|
states::{GameState, TurnState},
|
||||||
tiles::Tile,
|
tiles::Tile,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::reducers::advance_game_private;
|
use crate::reducers::advance_game_private;
|
||||||
|
|
||||||
#[table(accessor = user, public)]
|
|
||||||
#[table(accessor = logged_out_user)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct User {
|
|
||||||
#[primary_key]
|
|
||||||
pub identity: Identity,
|
|
||||||
|
|
||||||
pub name: String,
|
|
||||||
|
|
||||||
#[index(btree)]
|
|
||||||
pub lobby_id: u32,
|
|
||||||
#[unique]
|
|
||||||
pub config_id: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[table(accessor = lobby, public)]
|
#[table(accessor = lobby, public)]
|
||||||
pub struct Lobby {
|
pub struct Lobby {
|
||||||
|
|
@ -29,7 +15,7 @@ pub struct Lobby {
|
||||||
#[auto_inc]
|
#[auto_inc]
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
|
|
||||||
pub players: Vec<u32>,
|
pub players: Vec<PlayerOrBot>,
|
||||||
pub dealer_idx: u8,
|
pub dealer_idx: u8,
|
||||||
pub current_idx: u8,
|
pub current_idx: u8,
|
||||||
|
|
||||||
|
|
@ -37,16 +23,8 @@ pub struct Lobby {
|
||||||
// pub open_hands: bool,
|
// pub open_hands: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[table(accessor = lobby_state, public)]
|
|
||||||
// pub struct LobbyState {
|
|
||||||
// #[unique]
|
|
||||||
// lobby_id: u32,
|
|
||||||
|
|
||||||
// current_idx: u8,
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[table(accessor = wall)]
|
#[table(accessor = wall)]
|
||||||
pub struct Wall {
|
pub struct DbWall {
|
||||||
#[primary_key]
|
#[primary_key]
|
||||||
pub lobby_id: u32,
|
pub lobby_id: u32,
|
||||||
|
|
||||||
|
|
@ -63,34 +41,32 @@ pub struct DbTile {
|
||||||
pub tile: Tile,
|
pub tile: Tile,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[table(accessor = bot, public)]
|
#[table(accessor = player, public)]
|
||||||
pub struct Bot {
|
#[table(accessor = logged_out_player)]
|
||||||
#[primary_key]
|
#[derive(Debug)]
|
||||||
|
pub struct Player {
|
||||||
|
#[unique]
|
||||||
#[auto_inc]
|
#[auto_inc]
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
|
|
||||||
|
#[primary_key]
|
||||||
|
pub identity: spacetimedb::Identity,
|
||||||
|
|
||||||
|
pub name: Option<String>,
|
||||||
|
|
||||||
#[index(btree)]
|
#[index(btree)]
|
||||||
pub lobby_id: u32,
|
pub lobby_id: u32,
|
||||||
|
|
||||||
pub config_id: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[table(accessor = player_config, public)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct PlayerConfig {
|
|
||||||
#[primary_key]
|
|
||||||
#[auto_inc]
|
|
||||||
pub id: u32,
|
|
||||||
|
|
||||||
// TODO randomly generate this from contributor names for bots
|
|
||||||
pub name: String,
|
|
||||||
pub ready: bool,
|
pub ready: bool,
|
||||||
|
|
||||||
pub sort: bool,
|
pub sort: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[table(accessor = player_clock, public)]
|
#[table(accessor = player_clock, public)]
|
||||||
pub struct PlayerClock {
|
pub struct PlayerClock {
|
||||||
#[primary_key]
|
#[primary_key]
|
||||||
|
pub id: u32,
|
||||||
|
|
||||||
|
#[unique]
|
||||||
pub player_id: u32,
|
pub player_id: u32,
|
||||||
|
|
||||||
pub renewable: u16,
|
pub renewable: u16,
|
||||||
|
|
@ -100,65 +76,99 @@ pub struct PlayerClock {
|
||||||
#[table(accessor = player_hand)]
|
#[table(accessor = player_hand)]
|
||||||
pub struct PlayerHand {
|
pub struct PlayerHand {
|
||||||
#[primary_key]
|
#[primary_key]
|
||||||
|
#[auto_inc]
|
||||||
|
pub id: u32,
|
||||||
|
|
||||||
|
#[unique]
|
||||||
pub player_id: u32,
|
pub player_id: u32,
|
||||||
|
|
||||||
pub turn_state: TurnState,
|
pub turn_state: TurnState,
|
||||||
|
|
||||||
|
pub pond: Vec<DbTile>,
|
||||||
|
pub hand: Vec<DbTile>,
|
||||||
|
|
||||||
|
/// drawn or callable tile
|
||||||
|
pub working_tile: Option<DbTile>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[table(accessor = bot, public)]
|
||||||
|
pub struct Bot {
|
||||||
|
#[primary_key]
|
||||||
|
#[auto_inc]
|
||||||
|
pub id: u32,
|
||||||
|
|
||||||
|
#[index(btree)]
|
||||||
|
pub lobby_id: u32,
|
||||||
|
|
||||||
|
pub turn_state: TurnState,
|
||||||
|
|
||||||
pub hand: Vec<DbTile>,
|
pub hand: Vec<DbTile>,
|
||||||
pub pond: Vec<DbTile>,
|
pub pond: Vec<DbTile>,
|
||||||
|
|
||||||
/// drawn or callable tile
|
|
||||||
pub working_tile: Option<DbTile>,
|
pub working_tile: Option<DbTile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[table(accessor = game_timer, scheduled(advance_game_private))]
|
#[table(accessor = game_timer, scheduled(advance_game_private), public)]
|
||||||
pub struct LobbyTimer {
|
pub struct GameTimer {
|
||||||
|
#[primary_key]
|
||||||
|
#[auto_inc]
|
||||||
|
pub id: u64,
|
||||||
|
|
||||||
#[unique]
|
#[unique]
|
||||||
pub lobby_id: u32,
|
pub lobby_id: u32,
|
||||||
|
|
||||||
#[primary_key]
|
|
||||||
#[auto_inc]
|
|
||||||
pub scheduled_id: u64,
|
|
||||||
pub scheduled_at: spacetimedb::ScheduleAt,
|
pub scheduled_at: spacetimedb::ScheduleAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[view(accessor = view_hand, public)]
|
#[view(accessor = view_hand, public)]
|
||||||
fn view_hand(ctx: &ViewContext) -> Option<PlayerHand> {
|
fn view_hand(ctx: &ViewContext) -> Option<PlayerHand> {
|
||||||
ctx.db
|
ctx.db
|
||||||
.user()
|
.player()
|
||||||
.identity()
|
.identity()
|
||||||
.find(ctx.sender())
|
.find(ctx.sender())
|
||||||
.and_then(|p| ctx.db.player_hand().player_id().find(p.config_id))
|
.and_then(|p| ctx.db.player_hand().player_id().find(p.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(SpacetimeType, Clone)]
|
#[derive(SpacetimeType, Clone, Copy)]
|
||||||
pub struct HandView {
|
pub struct HandView {
|
||||||
pub player_id: u32,
|
pub player: PlayerOrBot,
|
||||||
pub hand_length: u8,
|
pub hand_length: u8,
|
||||||
// pub melds: u8,
|
// pub melds: u8,
|
||||||
pub pond: Vec<DbTile>,
|
|
||||||
pub drawn: bool,
|
pub drawn: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[view(accessor = view_closed_hands, public)]
|
#[view(accessor = view_closed_hands, public)]
|
||||||
fn view_closed_hands(ctx: &ViewContext) -> Vec<HandView> {
|
fn view_closed_hands(ctx: &ViewContext) -> Vec<HandView> {
|
||||||
if let Some(this_player) = ctx.db.user().identity().find(ctx.sender())
|
if let Some(this_player) = ctx.db.player().identity().find(ctx.sender())
|
||||||
&& let Some(lobby) = ctx.db.lobby().id().find(this_player.lobby_id)
|
&& let Some(lobby) = ctx.db.lobby().id().find(this_player.lobby_id)
|
||||||
{
|
{
|
||||||
lobby
|
lobby
|
||||||
.players
|
.players
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|id| {
|
.filter_map(|&player| match player {
|
||||||
ctx.db
|
PlayerOrBot::Player { id } => {
|
||||||
.player_hand()
|
if let Some(player_hand) = ctx.db.player_hand().player_id().find(id) {
|
||||||
.player_id()
|
Some(HandView {
|
||||||
.find(id)
|
player,
|
||||||
.map(|hand| HandView {
|
hand_length: player_hand.hand.len() as u8,
|
||||||
player_id: hand.player_id,
|
drawn: player_hand.turn_state == TurnState::Tsumo
|
||||||
hand_length: hand.hand.len() as u8,
|
&& player_hand.working_tile.is_some(),
|
||||||
pond: hand.pond,
|
|
||||||
drawn: hand.turn_state == TurnState::Tsumo && hand.working_tile.is_some(),
|
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlayerOrBot::Bot { id } => {
|
||||||
|
if let Some(bot) = ctx.db.bot().id().find(id) {
|
||||||
|
Some(HandView {
|
||||||
|
player,
|
||||||
|
hand_length: bot.hand.len() as u8,
|
||||||
|
drawn: bot.turn_state == TurnState::Tsumo && bot.working_tile.is_some(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -17,3 +17,9 @@ pub mod tiles;
|
||||||
pub use states::*;
|
pub use states::*;
|
||||||
pub use tiles::*;
|
pub use tiles::*;
|
||||||
|
|
||||||
|
#[derive(Debug, ..Copy, ..Eq, Hash)]
|
||||||
|
#[derive(SpacetimeType)]
|
||||||
|
pub enum PlayerOrBot {
|
||||||
|
Player { id: u32 },
|
||||||
|
Bot { id: u32 },
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,11 @@
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::render::render_resource::AsBindGroupShaderType;
|
|
||||||
use bevy_spacetimedb::{ReadInsertMessage, ReadInsertUpdateMessage, ReadUpdateMessage, StdbPlugin};
|
use bevy_spacetimedb::{ReadInsertMessage, ReadInsertUpdateMessage, ReadUpdateMessage, StdbPlugin};
|
||||||
|
|
||||||
use jong_db::{
|
use jong_db::{
|
||||||
self, PlayerClockTableAccess, PlayerConfigTableAccess, UserTableAccess, add_bot, advance_game,
|
self, GameTimerTableAccess, PlayerClockTableAccess, add_bot, advance_game, set_ready,
|
||||||
join_or_create_lobby, lobbyQueryTableAccess, player_configQueryTableAccess, set_ready,
|
|
||||||
userQueryTableAccess,
|
|
||||||
};
|
};
|
||||||
use jong_db::{
|
use jong_db::{
|
||||||
BotTableAccess, DbConnection, LobbyTableAccess, PlayerHand, RemoteTables,
|
BotTableAccess, DbConnection, LobbyTableAccess, PlayerHand, PlayerTableAccess, RemoteTables,
|
||||||
ViewClosedHandsTableAccess, ViewHandTableAccess,
|
ViewClosedHandsTableAccess, ViewHandTableAccess,
|
||||||
};
|
};
|
||||||
use jong_types::*;
|
use jong_types::*;
|
||||||
|
|
@ -28,14 +23,15 @@ 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)
|
||||||
.add_table(RemoteTables::user)
|
|
||||||
.add_table(RemoteTables::lobby)
|
.add_table(RemoteTables::lobby)
|
||||||
|
.add_table(RemoteTables::player)
|
||||||
.add_table(RemoteTables::bot)
|
.add_table(RemoteTables::bot)
|
||||||
.add_table(RemoteTables::player_config)
|
|
||||||
.add_table(RemoteTables::player_clock)
|
.add_table(RemoteTables::player_clock)
|
||||||
// TODO check bevy_spacetimedb PR status
|
// TODO check bevy_spacetimedb PR status
|
||||||
.add_view_with_pk(RemoteTables::view_hand, |p| p.player_id)
|
.add_view_with_pk(RemoteTables::view_hand, |p| p.id)
|
||||||
.add_view_with_pk(RemoteTables::view_closed_hands, |p| p.player_id);
|
.add_view_with_pk(RemoteTables::view_closed_hands, |p| {
|
||||||
|
PlayerOrBot::from(&p.player)
|
||||||
|
});
|
||||||
let plugins =
|
let plugins =
|
||||||
if let Some(token) = creds_store().load().expect("i/o error loading credentials") {
|
if let Some(token) = creds_store().load().expect("i/o error loading credentials") {
|
||||||
// FIXME patch plugin so this takes Option?
|
// FIXME patch plugin so this takes Option?
|
||||||
|
|
@ -47,31 +43,37 @@ impl Plugin for Riichi {
|
||||||
app.add_plugins(plugins)
|
app.add_plugins(plugins)
|
||||||
.init_state::<jong_types::states::GameState>()
|
.init_state::<jong_types::states::GameState>()
|
||||||
.add_sub_state::<jong_types::states::TurnState>()
|
.add_sub_state::<jong_types::states::TurnState>()
|
||||||
.init_resource::<Lobby>()
|
.add_message::<SyncPlayer>()
|
||||||
|
.add_message::<SyncOpenHand>()
|
||||||
.add_systems(Startup, subscriptions)
|
.add_systems(Startup, subscriptions)
|
||||||
.add_systems(Update, (connection::on_connect, connection::on_disconnect))
|
.add_systems(Update, (connection::on_connect, connection::on_disconnect))
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
(
|
(
|
||||||
on_user_insert_update,
|
(on_player_insert_update, on_lobby_insert_update),
|
||||||
on_lobby_insert_update,
|
(sync_player),
|
||||||
on_bot_insert_update,
|
|
||||||
on_player_config_insert_update,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
(on_view_hand_insert, on_view_hand_update)
|
((on_view_hand_insert, on_view_hand_update), (sync_open_hand))
|
||||||
.run_if(in_state(GameState::Play).or(in_state(GameState::Deal))),
|
.run_if(in_state(GameState::Play).or(in_state(GameState::Deal))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subscriptions(stdb: SpacetimeDB, mut commands: Commands) {
|
/// on subscribe we need to check:
|
||||||
while stdb.try_identity().is_none() {
|
/// if we're in a game already
|
||||||
bevy::platform::thread::sleep(Duration::from_secs(1));
|
/// spawn (restore) all current game state
|
||||||
}
|
/// spawn all players and hands
|
||||||
|
/// else
|
||||||
|
/// spawn self player
|
||||||
|
/// then
|
||||||
|
/// wait for lobbies
|
||||||
|
/// spawn other players
|
||||||
|
/// spawn all hands and ponds
|
||||||
|
|
||||||
|
fn subscriptions(stdb: SpacetimeDB, mut commands: Commands) {
|
||||||
let (tx, rx) = std::sync::mpsc::channel();
|
let (tx, rx) = std::sync::mpsc::channel();
|
||||||
stdb.subscription_builder()
|
stdb.subscription_builder()
|
||||||
.on_applied(move |_| {
|
.on_applied(move |_| {
|
||||||
|
|
@ -81,172 +83,108 @@ fn subscriptions(stdb: SpacetimeDB, mut commands: Commands) {
|
||||||
.on_error(|_, err| {
|
.on_error(|_, err| {
|
||||||
error!("subs failed: {err}");
|
error!("subs failed: {err}");
|
||||||
})
|
})
|
||||||
.add_query(|q| q.from.user().r#where(|u| u.identity.eq(stdb.identity())))
|
.subscribe([
|
||||||
.subscribe();
|
// TODO change these to sub/unsub based on being in lobby and some such
|
||||||
// TODO more sub/unsub based on being in lobby and some such, current done in tui::keybaord
|
format!(
|
||||||
|
"SELECT p.* FROM player p WHERE p.identity = '{}'",
|
||||||
|
stdb.identity()
|
||||||
|
),
|
||||||
|
// TODO add filter for lobby id for all of these later
|
||||||
|
"SELECT l.* FROM lobby l JOIN player p ON l.id = p.lobby_id".to_string(),
|
||||||
|
"SELECT p.* FROM player p JOIN lobby l ON p.lobby_id = l.id".to_string(),
|
||||||
|
"SELECT c.* FROM player_clock c JOIN player p ON c.player_id = p.id".to_string(),
|
||||||
|
"SELECT b.* FROM bot b JOIN lobby l ON l.id = b.lobby_id".to_string(),
|
||||||
|
"SELECT * FROM view_hand".to_string(),
|
||||||
|
"SELECT * FROM view_closed_hands".to_string(),
|
||||||
|
]);
|
||||||
|
|
||||||
while let Ok(()) = rx.recv() {
|
while let Ok(()) = rx.recv() {
|
||||||
// todo!()
|
// todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_user_insert_update() {}
|
#[derive(Message)]
|
||||||
|
struct SyncPlayer(u32);
|
||||||
|
|
||||||
#[derive(Resource, Default)]
|
#[derive(Message)]
|
||||||
pub struct Lobby {
|
struct SyncOpenHand(u32);
|
||||||
pub players: Vec<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_lobby_insert_update(
|
#[derive(Message)]
|
||||||
|
struct SyncClosedHand(PlayerOrBot);
|
||||||
|
|
||||||
|
#[derive(Message)]
|
||||||
|
struct SyncPlayerClock(u32);
|
||||||
|
|
||||||
|
fn sync_player(
|
||||||
stdb: SpacetimeDB,
|
stdb: SpacetimeDB,
|
||||||
mut messages: ReadInsertUpdateMessage<jong_db::Lobby>,
|
|
||||||
|
|
||||||
mut commands: Commands,
|
|
||||||
|
|
||||||
mut lobby: ResMut<Lobby>,
|
|
||||||
players: Query<(Entity, &Player)>,
|
|
||||||
|
|
||||||
mut next_gamestate: ResMut<NextState<jong_types::states::GameState>>,
|
|
||||||
) {
|
|
||||||
for msg in messages.read() {
|
|
||||||
// trace!("on_lobby_insert_update msg:\n{:#?}", msg.new);
|
|
||||||
|
|
||||||
let player = stdb.db().user().identity().find(&stdb.identity()).unwrap();
|
|
||||||
let player_config = stdb
|
|
||||||
.db()
|
|
||||||
.player_config()
|
|
||||||
.id()
|
|
||||||
.find(&player.config_id)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
match msg.new.game_state {
|
|
||||||
jong_db::GameState::None => {
|
|
||||||
// trace!("game entered none");
|
|
||||||
}
|
|
||||||
jong_db::GameState::Lobby => {
|
|
||||||
// trace!("game entered lobby");
|
|
||||||
if !player_config.ready {
|
|
||||||
for _ in 0..3 {
|
|
||||||
stdb.reducers().add_bot(player.lobby_id).unwrap();
|
|
||||||
}
|
|
||||||
stdb.reducers().set_ready(true).unwrap();
|
|
||||||
// stdb.reducers().advance_game().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jong_db::GameState::Setup => {
|
|
||||||
// trace!("game entered setup");
|
|
||||||
}
|
|
||||||
jong_db::GameState::Deal => {
|
|
||||||
// trace!("game entered deal");
|
|
||||||
}
|
|
||||||
jong_db::GameState::Play => {
|
|
||||||
// trace!("game entered play");
|
|
||||||
}
|
|
||||||
jong_db::GameState::Exit => {
|
|
||||||
// trace!("game enetered exit");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lobby.players = msg.new.players.clone();
|
|
||||||
next_gamestate.set(msg.new.game_state.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_bot_insert_update(stdb: SpacetimeDB, mut messages: ReadInsertUpdateMessage<jong_db::Bot>) {
|
|
||||||
for msg in messages.read() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_player_config_insert_update(
|
|
||||||
stdb: SpacetimeDB,
|
|
||||||
mut messages: ReadInsertUpdateMessage<jong_db::PlayerConfig>,
|
|
||||||
|
|
||||||
|
mut messages: MessageReader<SyncPlayer>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
|
|
||||||
players: Query<(Entity, &Player)>,
|
players: Query<(Entity, &Player)>,
|
||||||
) {
|
) {
|
||||||
for msg in messages.read() {
|
for SyncPlayer(id) in messages.read() {
|
||||||
trace!("on_player_insert_update");
|
trace!("sync_player");
|
||||||
let player = &msg.new;
|
let Some(player) = stdb.db().player().id().find(id) else {
|
||||||
|
todo!()
|
||||||
|
};
|
||||||
|
|
||||||
let player_ent = players
|
let player_ent = players
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|(e, p)| (p.id == player.id).then_some(e))
|
.find_map(|(e, p)| (p.id == PlayerOrBot::Player { id: player.id }).then_some(e))
|
||||||
.unwrap_or_else(|| commands.spawn(Player { id: player.id }).id());
|
.unwrap_or_else(|| {
|
||||||
|
commands
|
||||||
|
.spawn(Player {
|
||||||
|
id: PlayerOrBot::Player { id: player.id },
|
||||||
|
})
|
||||||
|
.id()
|
||||||
|
});
|
||||||
|
|
||||||
if player.id
|
if player.identity == stdb.identity() {
|
||||||
== stdb
|
|
||||||
.db()
|
|
||||||
.user()
|
|
||||||
.identity()
|
|
||||||
.find(&stdb.identity())
|
|
||||||
.unwrap()
|
|
||||||
.config_id
|
|
||||||
{
|
|
||||||
commands.entity(player_ent).insert(MainPlayer);
|
commands.entity(player_ent).insert(MainPlayer);
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_view_hand_insert(
|
|
||||||
mut messages: ReadInsertMessage<jong_db::PlayerHand>,
|
|
||||||
mut commands: Commands,
|
|
||||||
tiles: Query<(Entity, &TileId)>,
|
|
||||||
hands: Query<(Entity, &Hand)>,
|
|
||||||
ponds: Query<(Entity, &Pond)>,
|
|
||||||
mut next_turnstate: ResMut<NextState<TurnState>>,
|
|
||||||
) {
|
|
||||||
for msg in messages.read() {
|
|
||||||
trace!("on_view_hand_insert");
|
|
||||||
sync_open_hand(
|
|
||||||
&mut commands,
|
|
||||||
tiles,
|
|
||||||
hands,
|
|
||||||
ponds,
|
|
||||||
&mut next_turnstate,
|
|
||||||
&msg.row,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_view_hand_update(
|
|
||||||
mut messages: ReadUpdateMessage<jong_db::PlayerHand>,
|
|
||||||
mut commands: Commands,
|
|
||||||
tiles: Query<(Entity, &TileId)>,
|
|
||||||
hands: Query<(Entity, &Hand)>,
|
|
||||||
ponds: Query<(Entity, &Pond)>,
|
|
||||||
mut next_turnstate: ResMut<NextState<TurnState>>,
|
|
||||||
) {
|
|
||||||
for msg in messages.read() {
|
|
||||||
trace!("on_view_hand_update");
|
|
||||||
sync_open_hand(
|
|
||||||
&mut commands,
|
|
||||||
tiles,
|
|
||||||
hands,
|
|
||||||
ponds,
|
|
||||||
&mut next_turnstate,
|
|
||||||
&msg.new,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sync_open_hand(
|
fn sync_open_hand(
|
||||||
commands: &mut Commands,
|
stdb: SpacetimeDB,
|
||||||
|
|
||||||
|
mut messages: MessageReader<SyncOpenHand>,
|
||||||
|
mut commands: Commands,
|
||||||
|
|
||||||
tiles: Query<(Entity, &TileId)>,
|
tiles: Query<(Entity, &TileId)>,
|
||||||
hands: Query<(Entity, &Hand)>,
|
hands: Query<(Entity, &Hand)>,
|
||||||
ponds: Query<(Entity, &Pond)>,
|
ponds: Query<(Entity, &Pond)>,
|
||||||
next_turnstate: &mut ResMut<NextState<TurnState>>,
|
|
||||||
player_hand: &PlayerHand,
|
mut next_turnstate: ResMut<NextState<TurnState>>,
|
||||||
) {
|
) {
|
||||||
let player_id = player_hand.player_id;
|
for SyncOpenHand(id) in messages.read() {
|
||||||
|
trace!("sync_open_hand");
|
||||||
|
let Some(player_hand) = stdb.db().view_hand().iter().find(|hand| hand.id == *id) else {
|
||||||
|
todo!()
|
||||||
|
};
|
||||||
|
|
||||||
let hand_ent = hands
|
let hand_ent = hands
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|(e, h)| (h.player_id == player_id).then_some(e))
|
.find_map(|(e, h)| (h.owner == PlayerOrBot::Player { id: *id }).then_some(e))
|
||||||
.unwrap_or_else(|| commands.spawn(Hand { player_id }).id());
|
.unwrap_or_else(|| {
|
||||||
|
commands
|
||||||
|
.spawn(Hand {
|
||||||
|
owner: PlayerOrBot::Player { id: *id },
|
||||||
|
})
|
||||||
|
.id()
|
||||||
|
});
|
||||||
let pond_ent = ponds
|
let pond_ent = ponds
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|(e, p)| (p.player_id == player_id).then_some(e))
|
.find_map(|(e, h)| (h.owner == PlayerOrBot::Player { id: *id }).then_some(e))
|
||||||
.unwrap_or_else(|| commands.spawn(Pond { player_id }).id());
|
.unwrap_or_else(|| {
|
||||||
|
commands
|
||||||
|
.spawn(Pond {
|
||||||
|
owner: PlayerOrBot::Player { id: *id },
|
||||||
|
})
|
||||||
|
.id()
|
||||||
|
});
|
||||||
|
|
||||||
// hand and pond both still need ability to spawn for the reconnect case
|
// hand and pond both still need ability to spawn for the reconnect case
|
||||||
let hand: Vec<Entity> = player_hand
|
let hand: Vec<Entity> = player_hand
|
||||||
|
|
@ -273,7 +211,7 @@ fn sync_open_hand(
|
||||||
commands.entity(hand_ent).replace_children(&hand);
|
commands.entity(hand_ent).replace_children(&hand);
|
||||||
commands.entity(pond_ent).replace_children(&pond);
|
commands.entity(pond_ent).replace_children(&pond);
|
||||||
|
|
||||||
if let Some(dbt) = &player_hand.working_tile
|
if let Some(dbt) = player_hand.working_tile
|
||||||
&& player_hand.turn_state == jong_db::TurnState::Tsumo
|
&& player_hand.turn_state == jong_db::TurnState::Tsumo
|
||||||
{
|
{
|
||||||
commands.spawn((Drawn, Tile::from(&dbt.tile), TileId(dbt.id)));
|
commands.spawn((Drawn, Tile::from(&dbt.tile), TileId(dbt.id)));
|
||||||
|
|
@ -281,55 +219,161 @@ fn sync_open_hand(
|
||||||
|
|
||||||
next_turnstate.set(player_hand.turn_state.into());
|
next_turnstate.set(player_hand.turn_state.into());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// fn sync_closed_hand(
|
fn sync_closed_hand(
|
||||||
// stdb: SpacetimeDB,
|
stdb: SpacetimeDB,
|
||||||
|
|
||||||
// mut messages: MessageReader<SyncClosedHand>,
|
mut events: MessageReader<SyncClosedHand>,
|
||||||
|
mut commands: Commands,
|
||||||
|
|
||||||
|
hands: Query<&mut Closed, With<Hand>>,
|
||||||
|
ponds: Query<&mut Children, With<Pond>>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sync_player_clock() {}
|
||||||
|
|
||||||
|
fn on_player_insert_update(
|
||||||
|
mut db_messages: ReadInsertUpdateMessage<jong_db::Player>,
|
||||||
|
|
||||||
|
mut writer: MessageWriter<SyncPlayer>,
|
||||||
|
) {
|
||||||
|
for msg in db_messages.read() {
|
||||||
|
trace!("on_player_insert_update");
|
||||||
|
writer.write(SyncPlayer(msg.new.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_bot_insert_update() {}
|
||||||
|
|
||||||
|
fn on_lobby_insert_update(
|
||||||
|
stdb: SpacetimeDB,
|
||||||
|
mut messages: ReadInsertUpdateMessage<jong_db::Lobby>,
|
||||||
|
|
||||||
|
mut commands: Commands,
|
||||||
|
mut next_gamestate: ResMut<NextState<jong_types::states::GameState>>,
|
||||||
|
) {
|
||||||
|
for msg in messages.read() {
|
||||||
|
// trace!("on_lobby_insert_update msg:\n{:#?}", msg.new);
|
||||||
|
|
||||||
|
let player = stdb
|
||||||
|
.db()
|
||||||
|
.player()
|
||||||
|
.identity()
|
||||||
|
.find(&stdb.identity())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
match msg.new.game_state {
|
||||||
|
jong_db::GameState::None => {
|
||||||
|
trace!("game entered none");
|
||||||
|
}
|
||||||
|
jong_db::GameState::Lobby => {
|
||||||
|
trace!("game entered lobby");
|
||||||
|
if !player.ready {
|
||||||
|
for _ in 0..3 {
|
||||||
|
stdb.reducers().add_bot(player.lobby_id).unwrap();
|
||||||
|
}
|
||||||
|
stdb.reducers().set_ready(true).unwrap();
|
||||||
|
// stdb.reducers().advance_game().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jong_db::GameState::Setup => {
|
||||||
|
trace!("game entered setup");
|
||||||
|
}
|
||||||
|
jong_db::GameState::Deal => {
|
||||||
|
trace!("game entered deal");
|
||||||
|
}
|
||||||
|
jong_db::GameState::Play => {
|
||||||
|
trace!("game entered play");
|
||||||
|
}
|
||||||
|
jong_db::GameState::Exit => {
|
||||||
|
trace!("game enetered exit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
next_gamestate.set(msg.new.game_state.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_view_hand_insert(
|
||||||
|
mut messages: ReadInsertMessage<jong_db::PlayerHand>,
|
||||||
|
mut writer: MessageWriter<SyncOpenHand>,
|
||||||
|
) {
|
||||||
|
for msg in messages.read() {
|
||||||
|
trace!("on_view_hand_insert");
|
||||||
|
writer.write(SyncOpenHand(msg.row.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_view_hand_update(
|
||||||
|
mut messages: ReadUpdateMessage<jong_db::PlayerHand>,
|
||||||
|
mut writer: MessageWriter<SyncOpenHand>,
|
||||||
// mut commands: Commands,
|
// mut commands: Commands,
|
||||||
|
|
||||||
// tiles: Query<(Entity, &TileId)>,
|
// tiles: Query<(Entity, &TileId)>,
|
||||||
// hands: Query<(Entity, &mut Closed, &Hand)>,
|
|
||||||
// ponds: Query<(Entity, &Pond)>,
|
|
||||||
// ) {
|
|
||||||
// for SyncClosedHand(id) in messages.read() {
|
|
||||||
// let Some(hand_view) = stdb
|
|
||||||
// .db()
|
|
||||||
// .view_closed_hands()
|
|
||||||
// .iter()
|
|
||||||
// .find(|hand| PlayerOrBot::from(&hand.player) == *id)
|
|
||||||
// else {
|
|
||||||
// todo!()
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let hand_ent = hands
|
// main_player: Single<(Entity, &Children), With<MainPlayer>>,
|
||||||
// .iter()
|
|
||||||
// .find_map(|(e, c, h)| (h.owner == *id).then_some(e))
|
|
||||||
// .unwrap_or_else(|| commands.spawn(Hand { owner: *id }).id());
|
|
||||||
// let pond_ent = ponds
|
|
||||||
// .iter()
|
|
||||||
// .find_map(|(e, p)| (p.owner == *id).then_some(e))
|
|
||||||
// .unwrap_or_else(|| commands.spawn(Pond { owner: *id }).id());
|
|
||||||
|
|
||||||
// let pond: Vec<Entity> = hand_view
|
// hand: Query<Entity, With<Hand>>,
|
||||||
|
// pond: Query<Entity, With<Pond>>,
|
||||||
|
// // drawn: Option<Single<Entity, With<Drawn>>>,
|
||||||
|
// mut next_turnstate: ResMut<NextState<jong_types::states::TurnState>>,
|
||||||
|
) {
|
||||||
|
// TODO can this and similar run at startup or on play/reconnect?
|
||||||
|
for msg in messages.read() {
|
||||||
|
trace!("on_view_hand_update");
|
||||||
|
writer.write(SyncOpenHand(msg.new.player_id));
|
||||||
|
}
|
||||||
|
// 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 })
|
||||||
|
// .unwrap_or_else(|| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
|
||||||
|
// })
|
||||||
|
// .collect();
|
||||||
|
// let pond_tiles: Vec<_> = msg
|
||||||
|
// .new
|
||||||
// .pond
|
// .pond
|
||||||
// .iter()
|
// .iter()
|
||||||
// .map(|dbt| {
|
// .map(|dbt| {
|
||||||
// tiles
|
// tiles
|
||||||
// .iter()
|
// .iter()
|
||||||
// .find_map(|(e, i)| (i.0 == dbt.id).then_some(e))
|
// .find_map(|(e, t)| if *t == TileId(dbt.id) { Some(e) } else { None })
|
||||||
// .unwrap_or_else(|| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
|
// .unwrap_or_else(|| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id())
|
||||||
// })
|
// })
|
||||||
// .collect();
|
// .collect();
|
||||||
|
|
||||||
// commands.entity(hand_ent).insert(Closed {
|
// commands
|
||||||
// length: hand_view.hand_length,
|
// .entity(hand.iter().find(|e| main_player.1.contains(e)).unwrap())
|
||||||
// });
|
// .replace_children(&hand_tiles);
|
||||||
// commands.entity(pond_ent).replace_children(&pond);
|
// commands
|
||||||
|
// .entity(pond.iter().find(|e| main_player.1.contains(e)).unwrap())
|
||||||
|
// .replace_children(&pond_tiles);
|
||||||
|
|
||||||
// if hand_view.drawn {
|
// match msg.new.turn_state {
|
||||||
// commands.spawn(Drawn);
|
// jong_db::TurnState::None => {
|
||||||
|
// trace!("turnstate none");
|
||||||
|
// // TODO do we reconcile hand state here or in ::End?
|
||||||
// }
|
// }
|
||||||
|
// jong_db::TurnState::Tsumo => {
|
||||||
|
// trace!("turnstate tsumo");
|
||||||
|
// let dbt = msg
|
||||||
|
// .new
|
||||||
|
// .working_tile
|
||||||
|
// .as_ref()
|
||||||
|
// .expect("entered tsumo without a drawn tile");
|
||||||
|
// commands.spawn((Drawn, Tile::from(&dbt.tile), TileId(dbt.id)));
|
||||||
// }
|
// }
|
||||||
|
// 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());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ pub(crate) fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessa
|
||||||
for msg in messages.read() {
|
for msg in messages.read() {
|
||||||
info!("you're now jongline");
|
info!("you're now jongline");
|
||||||
|
|
||||||
|
// FIXME hack that doesn't work for startup crash?
|
||||||
|
while stdb.try_identity().is_none() {}
|
||||||
|
|
||||||
debug!("with identity: {}", stdb.identity());
|
debug!("with identity: {}", stdb.identity());
|
||||||
creds_store()
|
creds_store()
|
||||||
.save(&msg.access_token)
|
.save(&msg.access_token)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
use jong_types::PlayerOrBot;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Player {
|
pub struct Player {
|
||||||
pub id: u32,
|
pub id: PlayerOrBot,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
|
|
@ -11,31 +13,27 @@ pub struct MainPlayer;
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct CurrentPlayer;
|
pub struct CurrentPlayer;
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct TopLord;
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct RightLord;
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct LeftLord;
|
|
||||||
|
|
||||||
#[derive(Component, PartialEq, Eq, Debug)]
|
#[derive(Component, PartialEq, Eq, Debug)]
|
||||||
pub struct TileId(pub u32);
|
pub struct TileId(pub u32);
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Hand {
|
pub struct Hand {
|
||||||
pub player_id: u32,
|
pub owner: PlayerOrBot,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Closed {
|
pub struct Closed {
|
||||||
pub player_id: u32,
|
pub(crate) owner: PlayerOrBot,
|
||||||
pub(crate) length: u8,
|
pub(crate) length: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Pond {
|
pub struct Pond {
|
||||||
pub player_id: u32,
|
pub owner: PlayerOrBot,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Drawn;
|
pub struct Drawn;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Discarded;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use spacetimedb_sdk::Table;
|
||||||
use tui_logger::TuiWidgetState;
|
use tui_logger::TuiWidgetState;
|
||||||
|
|
||||||
use jong::{SpacetimeDB, riichi::player::*};
|
use jong::{SpacetimeDB, riichi::player::*};
|
||||||
use jong_db::{self, advance_game, discard_tile as _};
|
use jong_db::{self, GameTimerTableAccess, advance_game, discard_tile as _};
|
||||||
use jong_types::states::{GameState, TurnState};
|
use jong_types::states::{GameState, TurnState};
|
||||||
|
|
||||||
mod input;
|
mod input;
|
||||||
|
|
@ -104,12 +104,13 @@ fn discard_tile(
|
||||||
|
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
// main_player: Single<&Children, With<MainPlayer>>,
|
// main_player: Single<&Children, With<MainPlayer>>,
|
||||||
// only main player will have a Drawn tile with TileId?
|
// only main player will have a Drawn tile?
|
||||||
drawn: Single<(Entity, &TileId), With<Drawn>>,
|
drawn: Single<(Entity, &TileId), With<Drawn>>,
|
||||||
tiles: Query<&TileId>,
|
tiles: Query<&TileId>,
|
||||||
) {
|
) {
|
||||||
// TODO disable this when we're not current player?
|
// TODO disable this when we're not current player?
|
||||||
if let Ok(tile_id) = tiles.get(selected.0) {
|
if let Ok(tile_id) = tiles.get(selected.0) {
|
||||||
|
trace!("{:?}, {tile_id:?}", selected.0);
|
||||||
stdb.reducers().discard_tile(tile_id.0).unwrap();
|
stdb.reducers().discard_tile(tile_id.0).unwrap();
|
||||||
stdb.reducers().advance_game().unwrap();
|
stdb.reducers().advance_game().unwrap();
|
||||||
commands.entity(drawn.0).remove::<Drawn>();
|
commands.entity(drawn.0).remove::<Drawn>();
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,11 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_ratatui::crossterm::event::KeyCode;
|
use bevy_ratatui::crossterm::event::KeyCode;
|
||||||
use bevy_ratatui::event::KeyMessage;
|
use bevy_ratatui::event::KeyMessage;
|
||||||
use spacetimedb_sdk::DbContext;
|
use jong_db::PlayerTableAccess;
|
||||||
use spacetimedb_sdk::Table;
|
use jong_db::join_or_create_lobby;
|
||||||
use tui_logger::TuiWidgetEvent;
|
use tui_logger::TuiWidgetEvent;
|
||||||
|
|
||||||
use jong::SpacetimeDB;
|
use jong::SpacetimeDB;
|
||||||
use jong_db::{
|
|
||||||
LobbyTableAccess, UserTableAccess, botQueryTableAccess,
|
|
||||||
join_or_create_lobby, lobbyQueryTableAccess, player_clockQueryTableAccess,
|
|
||||||
player_configQueryTableAccess, view_closed_handsQueryTableAccess, view_handQueryTableAccess,
|
|
||||||
};
|
|
||||||
use jong_types::GameState;
|
|
||||||
|
|
||||||
use crate::tui::layout::Overlays;
|
use crate::tui::layout::Overlays;
|
||||||
use crate::tui::states::ConsoleWidget;
|
use crate::tui::states::ConsoleWidget;
|
||||||
|
|
@ -44,51 +38,11 @@ pub(crate) fn keyboard(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if *curr_gamestate.get() != GameState::None {
|
|
||||||
next_tuistate.set(TuiState::InGame);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
match curr_tuistate.get() {
|
match curr_tuistate.get() {
|
||||||
TuiState::MainMenu => match key {
|
TuiState::MainMenu => match key {
|
||||||
KeyCode::Char('p') => {
|
KeyCode::Char('p') => {
|
||||||
// TODO this should be a msg/signal and handle the correct lobby
|
// TODO this should be a msg/signal and handle the correct lobby
|
||||||
stdb.reducers()
|
stdb.reducers().join_or_create_lobby(0).unwrap();
|
||||||
.join_or_create_lobby_then(0, |ctx, res| {
|
|
||||||
if res.is_ok() {
|
|
||||||
let user =
|
|
||||||
ctx.db().user().identity().find(&ctx.identity()).unwrap();
|
|
||||||
let lobby_id = user.lobby_id;
|
|
||||||
|
|
||||||
ctx.subscription_builder()
|
|
||||||
.on_applied(|ctx| {
|
|
||||||
// TODO subscribe other player configs?
|
|
||||||
// ctx.subscription_builder()
|
|
||||||
// .add_query(|q| {
|
|
||||||
// q.from.player_config().left_semijoin(right, on)
|
|
||||||
// })
|
|
||||||
// .subscribe();
|
|
||||||
})
|
|
||||||
.add_query(|q| q.from.lobby().r#where(|l| l.id.eq(lobby_id)))
|
|
||||||
.add_query(|q| {
|
|
||||||
q.from.bot().r#where(|b| b.lobby_id.eq(lobby_id))
|
|
||||||
})
|
|
||||||
.add_query(|q| {
|
|
||||||
q.from
|
|
||||||
.player_config()
|
|
||||||
.r#where(|pc| pc.id.eq(user.config_id))
|
|
||||||
})
|
|
||||||
.add_query(|q| {
|
|
||||||
q.from
|
|
||||||
.player_clock()
|
|
||||||
.r#where(|pk| pk.player_id.eq(user.config_id))
|
|
||||||
})
|
|
||||||
.add_query(|q| q.from.view_hand())
|
|
||||||
.add_query(|q| q.from.view_closed_hands())
|
|
||||||
.subscribe();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
next_tuistate.set(TuiState::InGame);
|
next_tuistate.set(TuiState::InGame);
|
||||||
}
|
}
|
||||||
KeyCode::Char('z') => {
|
KeyCode::Char('z') => {
|
||||||
|
|
|
||||||
|
|
@ -152,19 +152,19 @@ pub(crate) fn render_main_hand(
|
||||||
|
|
||||||
main_player: Single<&Player, With<MainPlayer>>,
|
main_player: Single<&Player, With<MainPlayer>>,
|
||||||
|
|
||||||
hands: Query<(&Hand, &Children)>,
|
hand: Query<(&Hand, &Children)>,
|
||||||
drawn_tile: Option<Single<Entity, With<Drawn>>>,
|
drawn_tile: Option<Single<Entity, With<Drawn>>>,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
let mut frame = tui.get_frame();
|
let mut frame = tui.get_frame();
|
||||||
debug_blocks(layouts.clone(), &mut frame);
|
debug_blocks(layouts.clone(), &mut frame);
|
||||||
|
|
||||||
if hands.is_empty() {
|
if hand.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let hand: Vec<_> = hands
|
let hand: Vec<_> = hand
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|(h, c)| (main_player.id == h.player_id).then_some(c))
|
.find_map(|(h, c)| (main_player.id == h.owner).then_some(c))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|entity| -> Result<_> {
|
.map(|entity| -> Result<_> {
|
||||||
|
|
@ -271,7 +271,7 @@ pub(crate) fn render_main_pond(
|
||||||
|
|
||||||
let pond: Vec<_> = pond
|
let pond: Vec<_> = pond
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|(p, c)| (main_player.id == p.player_id).then_some(c))
|
.find_map(|(p, c)| (main_player.id == p.owner).then_some(c))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|entity| -> Result<_> {
|
.map(|entity| -> Result<_> {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
"dev": {
|
"dev": {
|
||||||
"run": ""
|
"run": ""
|
||||||
},
|
},
|
||||||
|
"_source-config": "spacetime.local.json",
|
||||||
"module-path": "jong-line",
|
"module-path": "jong-line",
|
||||||
"server": "local",
|
"server": "local",
|
||||||
"database": "jong-line"
|
"database": "jong-line"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue