Compare commits
No commits in common. "9b01f6b96aac313c575bb93c1a02f94d001896f7" and "d183f5d993f8b0e3b605fcdd45673dfdf53a86b2" have entirely different histories.
9b01f6b96a
...
d183f5d993
23 changed files with 716 additions and 216 deletions
1
.ignore
1
.ignore
|
|
@ -1 +0,0 @@
|
|||
jong/src/stdb
|
||||
|
|
@ -12,9 +12,7 @@ bevy.default-features = false
|
|||
bevy_ratatui = "0.10.0"
|
||||
bevy_spacetimedb = "0.7"
|
||||
|
||||
spacetimedb.version = "1.11.*"
|
||||
spacetimedb.features = ["unstable"]
|
||||
|
||||
spacetimedb = "1.11.*"
|
||||
spacetimedb-sdk = "1.11.*"
|
||||
|
||||
strum.version = "0.27.2"
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@ use spacetimedb::Identity;
|
|||
use spacetimedb_sdk::{DbContext, Table, credentials};
|
||||
|
||||
use crate::stdb::{
|
||||
self, DbConnection, LobbyTableAccess, PlayerTableAccess, RemoteTables, add_bot,
|
||||
join_or_create_lobby, login_or_add_player, set_ready, shuffle_deal, start_game,
|
||||
self, DbConnection, HandTableAccess, LobbyTableAccess, PlayerTableAccess, RemoteTables,
|
||||
ViewPlayerHandTableAccess, add_bot, join_or_create_lobby, login_or_add_player, set_ready,
|
||||
shuffle_deal, start_game,
|
||||
};
|
||||
use crate::{
|
||||
SpacetimeDB, creds_store,
|
||||
|
|
@ -44,11 +45,11 @@ impl Plugin for Riichi {
|
|||
.with_uri("http://localhost:3000")
|
||||
.with_module_name("jongline")
|
||||
.with_run_fn(DbConnection::run_threaded)
|
||||
// TODO why don't I need to call add_reducer?
|
||||
|
||||
// TODO do these need to be subscription & vice-versa?
|
||||
.add_table(RemoteTables::player)
|
||||
.add_table(RemoteTables::lobby)
|
||||
.add_table(RemoteTables::hand)
|
||||
|
||||
// semicolon stopper
|
||||
;
|
||||
|
|
@ -82,7 +83,7 @@ impl Plugin for Riichi {
|
|||
.add_systems(Update, on_player_insert_update)
|
||||
.add_systems(Update, on_lobby_insert_update)
|
||||
// .add_systems(OnEnter(GameState::Lobby), join_or_create_lobby)
|
||||
|
||||
.add_systems(Update, view_hand.run_if(in_state(GameState::Play)))
|
||||
// semicolon stopper
|
||||
;
|
||||
}
|
||||
|
|
@ -114,6 +115,7 @@ fn subscriptions(stdb: SpacetimeDB) {
|
|||
stdb.identity()
|
||||
),
|
||||
"SELECT l.* FROM lobby l JOIN player p ON l.host_player_id = p.id".to_string(),
|
||||
"SELECT * FROM view_player_hand vph".to_string(),
|
||||
]);
|
||||
// .subscribe_to_all_tables();
|
||||
}
|
||||
|
|
@ -123,10 +125,7 @@ fn on_player_insert_update(
|
|||
mut messages: ReadInsertUpdateMessage<stdb::Player>,
|
||||
|
||||
mut commands: Commands,
|
||||
|
||||
tiles: Query<(&Tile, Entity)>,
|
||||
mut player: Option<Single<&mut player::Player>>,
|
||||
mut hand_ent: Option<Single<Entity, With<Hand>>>,
|
||||
) {
|
||||
use player::*;
|
||||
|
||||
|
|
@ -138,28 +137,6 @@ fn on_player_insert_update(
|
|||
// // TODO add a start game button in the future
|
||||
// stdb.reducers().start_game().unwrap();
|
||||
// }
|
||||
let mut view: Vec<_> = msg.new.hand.iter().map(Tile::from).collect();
|
||||
// let mut tiles = tiles
|
||||
// .iter()
|
||||
// .filter(|(tt, _)| {
|
||||
// if let Some((i, _)) = view.iter().enumerate().find(|(_, t)| t == tt) {
|
||||
// view.swap_remove(i);
|
||||
// true
|
||||
// } else {
|
||||
// false
|
||||
// }
|
||||
// })
|
||||
// // .map(|(t, e)| e)
|
||||
// .collect::<Vec<_>>();
|
||||
// tiles.sort_by_key(|(t, e)| **t);
|
||||
// tiles.get_many(entities)
|
||||
|
||||
|
||||
let tiles = tiles.into_iter().map(|(_, e)| e).collect::<Vec<_>>();
|
||||
|
||||
commands
|
||||
.entity(**hand_ent.as_ref().unwrap())
|
||||
.replace_children(&tiles);
|
||||
} else {
|
||||
let player = Player {
|
||||
name: msg
|
||||
|
|
@ -175,6 +152,21 @@ fn on_player_insert_update(
|
|||
}
|
||||
}
|
||||
|
||||
// fn join_or_create_lobby(stdb: SpacetimeDB) {
|
||||
// let player = stdb
|
||||
// .db()
|
||||
// .player()
|
||||
// .identity()
|
||||
// .find(&stdb.identity())
|
||||
// .unwrap();
|
||||
|
||||
// if player.lobby_id == 0 {
|
||||
// stdb.reducers().join_or_create_lobby(0).unwrap();
|
||||
// } else {
|
||||
// info!("in lobby: {}", player.lobby_id)
|
||||
// }
|
||||
// }
|
||||
|
||||
fn on_lobby_insert_update(
|
||||
stdb: SpacetimeDB,
|
||||
mut messages: ReadInsertUpdateMessage<stdb::Lobby>,
|
||||
|
|
@ -183,7 +175,7 @@ fn on_lobby_insert_update(
|
|||
mut next_gamestate: ResMut<NextState<GameState>>,
|
||||
) {
|
||||
for msg in messages.read() {
|
||||
// trace!("on_lobby_insert_update msg:\n{:#?}", msg.new);
|
||||
trace!("on_lobby_insert_update msg:\n{:#?}", msg.new);
|
||||
|
||||
let player = stdb
|
||||
.db()
|
||||
|
|
@ -198,7 +190,7 @@ fn on_lobby_insert_update(
|
|||
trace!("game entered none");
|
||||
}
|
||||
stdb::GameState::Lobby => {
|
||||
trace!("game entered lobby");
|
||||
trace!("game in lobby");
|
||||
if !player.ready {
|
||||
for _ in 0..3 {
|
||||
stdb.reducers().add_bot(player.lobby_id).unwrap();
|
||||
|
|
@ -225,3 +217,31 @@ fn on_lobby_insert_update(
|
|||
next_gamestate.set(msg.new.game_state.into());
|
||||
}
|
||||
}
|
||||
|
||||
fn view_hand(
|
||||
stdb: SpacetimeDB,
|
||||
|
||||
mut commands: Commands,
|
||||
tiles: Query<(&Tile, Entity)>,
|
||||
hand_ent: Single<Entity, With<Hand>>,
|
||||
) {
|
||||
// trace!("view_hand");
|
||||
if let Some(view) = stdb.db().view_player_hand().iter().next() {
|
||||
let mut view = view.tiles.iter().map(Tile::from).collect::<Vec<_>>();
|
||||
|
||||
let tiles = tiles
|
||||
.iter()
|
||||
.filter(|(tt, _)| {
|
||||
if let Some((i, _)) = view.iter().enumerate().find(|(_, t)| t == tt) {
|
||||
view.swap_remove(i);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.map(|(_, e)| e)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
commands.entity(*hand_ent).replace_children(&tiles);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#![allow(unused, clippy::all)]
|
||||
use super::bot_type::Bot;
|
||||
use super::tile_type::Tile;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `bot`.
|
||||
|
|
|
|||
|
|
@ -4,15 +4,13 @@
|
|||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::tile_type::Tile;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct Bot {
|
||||
pub id: u32,
|
||||
pub lobby_id: u32,
|
||||
pub hand: Vec<Tile>,
|
||||
pub pond: Vec<Tile>,
|
||||
pub hand_id: u32,
|
||||
pub pond_id: u32,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for Bot {
|
||||
|
|
|
|||
144
jong/src/stdb/hand_table.rs
Normal file
144
jong/src/stdb/hand_table.rs
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use super::hand_type::Hand;
|
||||
use super::player_or_bot_type::PlayerOrBot;
|
||||
use super::tile_type::Tile;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `hand`.
|
||||
///
|
||||
/// Obtain a handle from the [`HandTableAccess::hand`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.hand()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.hand().on_insert(...)`.
|
||||
pub struct HandTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<Hand>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `hand`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait HandTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`HandTableHandle`], which mediates access to the table `hand`.
|
||||
fn hand(&self) -> HandTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl HandTableAccess for super::RemoteTables {
|
||||
fn hand(&self) -> HandTableHandle<'_> {
|
||||
HandTableHandle {
|
||||
imp: self.imp.get_table::<Hand>("hand"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct HandInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct HandDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for HandTableHandle<'ctx> {
|
||||
type Row = Hand;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = Hand> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = HandInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> HandInsertCallbackId {
|
||||
HandInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: HandInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = HandDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> HandDeleteCallbackId {
|
||||
HandDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: HandDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table = client_cache.get_or_make_table::<Hand>("hand");
|
||||
_table.add_unique_constraint::<u32>("id", |row| &row.id);
|
||||
}
|
||||
pub struct HandUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for HandTableHandle<'ctx> {
|
||||
type UpdateCallbackId = HandUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> HandUpdateCallbackId {
|
||||
HandUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: HandUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::TableUpdate<__ws::BsatnFormat>,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<Hand>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<Hand>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
/// Access to the `id` unique index on the table `hand`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`HandIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.hand().id().find(...)`.
|
||||
pub struct HandIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<Hand, u32>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> HandTableHandle<'ctx> {
|
||||
/// Get a handle on the `id` unique index on the table `hand`.
|
||||
pub fn id(&self) -> HandIdUnique<'ctx> {
|
||||
HandIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<u32>("id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> HandIdUnique<'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<Hand> {
|
||||
self.imp.find(col_val)
|
||||
}
|
||||
}
|
||||
21
jong/src/stdb/hand_type.rs
Normal file
21
jong/src/stdb/hand_type.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::player_or_bot_type::PlayerOrBot;
|
||||
use super::tile_type::Tile;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct Hand {
|
||||
pub id: u32,
|
||||
pub owner: PlayerOrBot,
|
||||
pub sort: bool,
|
||||
pub tiles: Vec<Tile>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for Hand {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
|
@ -11,6 +11,8 @@ pub mod bot_table;
|
|||
pub mod bot_type;
|
||||
pub mod dragon_type;
|
||||
pub mod game_state_type;
|
||||
pub mod hand_table;
|
||||
pub mod hand_type;
|
||||
pub mod join_or_create_lobby_reducer;
|
||||
pub mod lobby_table;
|
||||
pub mod lobby_type;
|
||||
|
|
@ -18,6 +20,8 @@ pub mod login_or_add_player_reducer;
|
|||
pub mod player_or_bot_type;
|
||||
pub mod player_table;
|
||||
pub mod player_type;
|
||||
pub mod pond_table;
|
||||
pub mod pond_type;
|
||||
pub mod rank_type;
|
||||
pub mod set_ready_reducer;
|
||||
pub mod shuffle_deal_reducer;
|
||||
|
|
@ -25,6 +29,7 @@ pub mod start_game_reducer;
|
|||
pub mod suit_type;
|
||||
pub mod tile_type;
|
||||
pub mod turn_state_type;
|
||||
pub mod view_player_hand_table;
|
||||
pub mod wall_table;
|
||||
pub mod wall_type;
|
||||
pub mod wind_type;
|
||||
|
|
@ -34,6 +39,8 @@ pub use bot_table::*;
|
|||
pub use bot_type::Bot;
|
||||
pub use dragon_type::Dragon;
|
||||
pub use game_state_type::GameState;
|
||||
pub use hand_table::*;
|
||||
pub use hand_type::Hand;
|
||||
pub use join_or_create_lobby_reducer::{
|
||||
join_or_create_lobby, set_flags_for_join_or_create_lobby, JoinOrCreateLobbyCallbackId,
|
||||
};
|
||||
|
|
@ -45,6 +52,8 @@ pub use login_or_add_player_reducer::{
|
|||
pub use player_or_bot_type::PlayerOrBot;
|
||||
pub use player_table::*;
|
||||
pub use player_type::Player;
|
||||
pub use pond_table::*;
|
||||
pub use pond_type::Pond;
|
||||
pub use rank_type::Rank;
|
||||
pub use set_ready_reducer::{set_flags_for_set_ready, set_ready, SetReadyCallbackId};
|
||||
pub use shuffle_deal_reducer::{set_flags_for_shuffle_deal, shuffle_deal, ShuffleDealCallbackId};
|
||||
|
|
@ -52,6 +61,7 @@ pub use start_game_reducer::{set_flags_for_start_game, start_game, StartGameCall
|
|||
pub use suit_type::Suit;
|
||||
pub use tile_type::Tile;
|
||||
pub use turn_state_type::TurnState;
|
||||
pub use view_player_hand_table::*;
|
||||
pub use wall_table::*;
|
||||
pub use wall_type::Wall;
|
||||
pub use wind_type::Wind;
|
||||
|
|
@ -142,8 +152,11 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer {
|
|||
#[doc(hidden)]
|
||||
pub struct DbUpdate {
|
||||
bot: __sdk::TableUpdate<Bot>,
|
||||
hand: __sdk::TableUpdate<Hand>,
|
||||
lobby: __sdk::TableUpdate<Lobby>,
|
||||
player: __sdk::TableUpdate<Player>,
|
||||
pond: __sdk::TableUpdate<Pond>,
|
||||
view_player_hand: __sdk::TableUpdate<Hand>,
|
||||
wall: __sdk::TableUpdate<Wall>,
|
||||
}
|
||||
|
||||
|
|
@ -156,12 +169,21 @@ impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate {
|
|||
"bot" => db_update
|
||||
.bot
|
||||
.append(bot_table::parse_table_update(table_update)?),
|
||||
"hand" => db_update
|
||||
.hand
|
||||
.append(hand_table::parse_table_update(table_update)?),
|
||||
"lobby" => db_update
|
||||
.lobby
|
||||
.append(lobby_table::parse_table_update(table_update)?),
|
||||
"player" => db_update
|
||||
.player
|
||||
.append(player_table::parse_table_update(table_update)?),
|
||||
"pond" => db_update
|
||||
.pond
|
||||
.append(pond_table::parse_table_update(table_update)?),
|
||||
"view_player_hand" => db_update
|
||||
.view_player_hand
|
||||
.append(view_player_hand_table::parse_table_update(table_update)?),
|
||||
"wall" => db_update
|
||||
.wall
|
||||
.append(wall_table::parse_table_update(table_update)?),
|
||||
|
|
@ -194,15 +216,23 @@ impl __sdk::DbUpdate for DbUpdate {
|
|||
diff.bot = cache
|
||||
.apply_diff_to_table::<Bot>("bot", &self.bot)
|
||||
.with_updates_by_pk(|row| &row.id);
|
||||
diff.hand = cache
|
||||
.apply_diff_to_table::<Hand>("hand", &self.hand)
|
||||
.with_updates_by_pk(|row| &row.id);
|
||||
diff.lobby = cache
|
||||
.apply_diff_to_table::<Lobby>("lobby", &self.lobby)
|
||||
.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.pond = cache
|
||||
.apply_diff_to_table::<Pond>("pond", &self.pond)
|
||||
.with_updates_by_pk(|row| &row.id);
|
||||
diff.wall = cache
|
||||
.apply_diff_to_table::<Wall>("wall", &self.wall)
|
||||
.with_updates_by_pk(|row| &row.lobby_id);
|
||||
diff.view_player_hand =
|
||||
cache.apply_diff_to_table::<Hand>("view_player_hand", &self.view_player_hand);
|
||||
|
||||
diff
|
||||
}
|
||||
|
|
@ -213,8 +243,11 @@ impl __sdk::DbUpdate for DbUpdate {
|
|||
#[doc(hidden)]
|
||||
pub struct AppliedDiff<'r> {
|
||||
bot: __sdk::TableAppliedDiff<'r, Bot>,
|
||||
hand: __sdk::TableAppliedDiff<'r, Hand>,
|
||||
lobby: __sdk::TableAppliedDiff<'r, Lobby>,
|
||||
player: __sdk::TableAppliedDiff<'r, Player>,
|
||||
pond: __sdk::TableAppliedDiff<'r, Pond>,
|
||||
view_player_hand: __sdk::TableAppliedDiff<'r, Hand>,
|
||||
wall: __sdk::TableAppliedDiff<'r, Wall>,
|
||||
__unused: std::marker::PhantomData<&'r ()>,
|
||||
}
|
||||
|
|
@ -230,8 +263,15 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
|
|||
callbacks: &mut __sdk::DbCallbacks<RemoteModule>,
|
||||
) {
|
||||
callbacks.invoke_table_row_callbacks::<Bot>("bot", &self.bot, event);
|
||||
callbacks.invoke_table_row_callbacks::<Hand>("hand", &self.hand, 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::<Pond>("pond", &self.pond, event);
|
||||
callbacks.invoke_table_row_callbacks::<Hand>(
|
||||
"view_player_hand",
|
||||
&self.view_player_hand,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<Wall>("wall", &self.wall, event);
|
||||
}
|
||||
}
|
||||
|
|
@ -953,8 +993,11 @@ impl __sdk::SpacetimeModule for RemoteModule {
|
|||
|
||||
fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
|
||||
bot_table::register_table(client_cache);
|
||||
hand_table::register_table(client_cache);
|
||||
lobby_table::register_table(client_cache);
|
||||
player_table::register_table(client_cache);
|
||||
pond_table::register_table(client_cache);
|
||||
view_player_hand_table::register_table(client_cache);
|
||||
wall_table::register_table(client_cache);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#![allow(unused, clippy::all)]
|
||||
use super::player_type::Player;
|
||||
use super::tile_type::Tile;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `player`.
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@
|
|||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::tile_type::Tile;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct Player {
|
||||
|
|
@ -13,10 +11,9 @@ pub struct Player {
|
|||
pub id: u32,
|
||||
pub name: Option<String>,
|
||||
pub lobby_id: u32,
|
||||
pub hand_id: u32,
|
||||
pub pond_id: u32,
|
||||
pub ready: bool,
|
||||
pub sort: bool,
|
||||
pub hand: Vec<Tile>,
|
||||
pub pond: Vec<Tile>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for Player {
|
||||
|
|
|
|||
144
jong/src/stdb/pond_table.rs
Normal file
144
jong/src/stdb/pond_table.rs
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use super::player_or_bot_type::PlayerOrBot;
|
||||
use super::pond_type::Pond;
|
||||
use super::tile_type::Tile;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `pond`.
|
||||
///
|
||||
/// Obtain a handle from the [`PondTableAccess::pond`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.pond()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.pond().on_insert(...)`.
|
||||
pub struct PondTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<Pond>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `pond`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait PondTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`PondTableHandle`], which mediates access to the table `pond`.
|
||||
fn pond(&self) -> PondTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl PondTableAccess for super::RemoteTables {
|
||||
fn pond(&self) -> PondTableHandle<'_> {
|
||||
PondTableHandle {
|
||||
imp: self.imp.get_table::<Pond>("pond"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PondInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct PondDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for PondTableHandle<'ctx> {
|
||||
type Row = Pond;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = Pond> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = PondInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> PondInsertCallbackId {
|
||||
PondInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: PondInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = PondDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> PondDeleteCallbackId {
|
||||
PondDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: PondDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table = client_cache.get_or_make_table::<Pond>("pond");
|
||||
_table.add_unique_constraint::<u32>("id", |row| &row.id);
|
||||
}
|
||||
pub struct PondUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for PondTableHandle<'ctx> {
|
||||
type UpdateCallbackId = PondUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> PondUpdateCallbackId {
|
||||
PondUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: PondUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::TableUpdate<__ws::BsatnFormat>,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<Pond>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<Pond>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
/// Access to the `id` unique index on the table `pond`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`PondIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.pond().id().find(...)`.
|
||||
pub struct PondIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<Pond, u32>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> PondTableHandle<'ctx> {
|
||||
/// Get a handle on the `id` unique index on the table `pond`.
|
||||
pub fn id(&self) -> PondIdUnique<'ctx> {
|
||||
PondIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<u32>("id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> PondIdUnique<'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<Pond> {
|
||||
self.imp.find(col_val)
|
||||
}
|
||||
}
|
||||
20
jong/src/stdb/pond_type.rs
Normal file
20
jong/src/stdb/pond_type.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::player_or_bot_type::PlayerOrBot;
|
||||
use super::tile_type::Tile;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct Pond {
|
||||
pub id: u32,
|
||||
pub owner: PlayerOrBot,
|
||||
pub tiles: Vec<Tile>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for Pond {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
97
jong/src/stdb/view_player_hand_table.rs
Normal file
97
jong/src/stdb/view_player_hand_table.rs
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
// 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::hand_type::Hand;
|
||||
use super::player_or_bot_type::PlayerOrBot;
|
||||
use super::tile_type::Tile;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `view_player_hand`.
|
||||
///
|
||||
/// Obtain a handle from the [`ViewPlayerHandTableAccess::view_player_hand`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.view_player_hand()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.view_player_hand().on_insert(...)`.
|
||||
pub struct ViewPlayerHandTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<Hand>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `view_player_hand`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait ViewPlayerHandTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`ViewPlayerHandTableHandle`], which mediates access to the table `view_player_hand`.
|
||||
fn view_player_hand(&self) -> ViewPlayerHandTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl ViewPlayerHandTableAccess for super::RemoteTables {
|
||||
fn view_player_hand(&self) -> ViewPlayerHandTableHandle<'_> {
|
||||
ViewPlayerHandTableHandle {
|
||||
imp: self.imp.get_table::<Hand>("view_player_hand"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ViewPlayerHandInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct ViewPlayerHandDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for ViewPlayerHandTableHandle<'ctx> {
|
||||
type Row = Hand;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = Hand> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = ViewPlayerHandInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> ViewPlayerHandInsertCallbackId {
|
||||
ViewPlayerHandInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: ViewPlayerHandInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = ViewPlayerHandDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> ViewPlayerHandDeleteCallbackId {
|
||||
ViewPlayerHandDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: ViewPlayerHandDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table = client_cache.get_or_make_table::<Hand>("view_player_hand");
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::TableUpdate<__ws::BsatnFormat>,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<Hand>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<Hand>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ impl Plugin for TuiPlugin {
|
|||
.add_systems(
|
||||
Update,
|
||||
(
|
||||
render::render_hands.run_if(in_state(GameState::Play)),
|
||||
(render::render_hands, render::render_arg_check).run_if(in_state(GameState::Play)),
|
||||
render::render,
|
||||
)
|
||||
.chain()
|
||||
|
|
|
|||
|
|
@ -95,24 +95,23 @@ pub(crate) fn render(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// pub(crate) fn render_arg_check(
|
||||
// mut commands: Commands,
|
||||
// mut tui: ResMut<RatatuiContext>,
|
||||
pub(crate) fn render_arg_check(
|
||||
mut commands: Commands,
|
||||
mut tui: ResMut<RatatuiContext>,
|
||||
|
||||
// hovered: Query<Entity, With<Hovered>>,
|
||||
// layouts: Res<HandLayouts>,
|
||||
hovered: Query<Entity, With<Hovered>>,
|
||||
layouts: Res<HandLayouts>,
|
||||
|
||||
// tiles: Query<&jong_types::Tile>,
|
||||
// // main_player: Single<(&Player, Entity, &Wind), With<MainPlayer>>,
|
||||
// curr_player: Single<Entity, With<CurrentPlayer>>,
|
||||
// players: Query<(&Player, Entity, &Children)>,
|
||||
// hands: Query<(&Children, Entity), (With<Hand>, Without<Player>)>,
|
||||
// // drawn_tile: Single<Entity, With<Drawn>>,
|
||||
// ) {
|
||||
// // trace!("arg!");
|
||||
// }
|
||||
tiles: Query<&jong_types::Tile>,
|
||||
// main_player: Single<(&Player, Entity, &Wind), With<MainPlayer>>,
|
||||
curr_player: Single<Entity, With<CurrentPlayer>>,
|
||||
players: Query<(&Player, Entity, &Children)>,
|
||||
hands: Query<(&Children, Entity), (With<Hand>, Without<Player>)>,
|
||||
// drawn_tile: Single<Entity, With<Drawn>>,
|
||||
) {
|
||||
// trace!("arg!");
|
||||
}
|
||||
|
||||
// FIXME we don't care about other players atm
|
||||
#[allow(clippy::too_many_arguments, clippy::type_complexity)]
|
||||
pub(crate) fn render_hands(
|
||||
mut commands: Commands,
|
||||
|
|
@ -122,21 +121,23 @@ pub(crate) fn render_hands(
|
|||
layouts: Res<HandLayouts>,
|
||||
|
||||
tiles: Query<&jong_types::Tile>,
|
||||
main_player: Single<(&Player, Entity /* , &Wind */), With<MainPlayer>>,
|
||||
main_player: Single<(&Player, Entity, &Wind), With<MainPlayer>>,
|
||||
curr_player: Single<Entity, With<CurrentPlayer>>,
|
||||
players: Query<(&Player, Entity, &Children)>,
|
||||
hands: Query<(&Children, Entity), With<Hand>>,
|
||||
// drawn_tile: Single<Entity, With<Drawn>>,
|
||||
hands: Query<(&Children, Entity), (With<Hand>, Without<Player>)>,
|
||||
drawn_tile: Single<Entity, With<Drawn>>,
|
||||
) -> Result {
|
||||
trace!("render_hands");
|
||||
|
||||
let mut frame = tui.get_frame();
|
||||
debug_blocks(*layouts, &mut frame);
|
||||
|
||||
for (hand, hand_ent) in hands {
|
||||
// debug!("{hand:?}");
|
||||
// let (player, player_ent, _) = players
|
||||
// .iter()
|
||||
// .find(|(_, e, c)| c.contains(&hand_ent))
|
||||
// .unwrap();
|
||||
let (player, player_ent, _) = players
|
||||
.iter()
|
||||
.find(|(_, e, c)| c.contains(&hand_ent))
|
||||
.unwrap();
|
||||
let hand: Vec<_> = hand
|
||||
.iter()
|
||||
.map(|entity| -> Result<_> {
|
||||
|
|
@ -148,81 +149,80 @@ pub(crate) fn render_hands(
|
|||
})
|
||||
.collect::<Result<_>>()?;
|
||||
|
||||
let (player, player_ent) = *main_player;
|
||||
// if player == main_player.0 {
|
||||
// split main box into thirds
|
||||
let mut this_hand = layouts.this_hand;
|
||||
// let this_drawer = drawn_tile..is_some_and(|dt| dt.0 == player);
|
||||
let this_drawer = player_ent == *curr_player;
|
||||
let tile_drawn = if this_drawer { 7 } else { 0 };
|
||||
let hand_draw_meld = Layout::horizontal([
|
||||
Constraint::Max(hand.len() as u16 * 5),
|
||||
Constraint::Max(tile_drawn),
|
||||
Constraint::Fill(1),
|
||||
])
|
||||
.flex(Flex::SpaceBetween);
|
||||
this_hand = this_hand.offset(Offset {
|
||||
x: 0,
|
||||
y: this_hand.height.abs_diff(5) as i32 + 1,
|
||||
});
|
||||
this_hand = this_hand.resize(Size {
|
||||
width: this_hand.width,
|
||||
height: 4,
|
||||
});
|
||||
let [hand_area, drawn_area, meld_area] = hand_draw_meld.areas::<3>(this_hand);
|
||||
if player == main_player.0 {
|
||||
// split main box into thirds
|
||||
let mut this_hand = layouts.this_hand;
|
||||
// let this_drawer = drawn_tile..is_some_and(|dt| dt.0 == player);
|
||||
let this_drawer = player_ent == *curr_player;
|
||||
let tile_drawn = if this_drawer { 7 } else { 0 };
|
||||
let hand_draw_meld = Layout::horizontal([
|
||||
Constraint::Max(hand.len() as u16 * 5),
|
||||
Constraint::Max(tile_drawn),
|
||||
Constraint::Fill(1),
|
||||
])
|
||||
.flex(Flex::SpaceBetween);
|
||||
this_hand = this_hand.offset(Offset {
|
||||
x: 0,
|
||||
y: this_hand.height.abs_diff(5) as i32 + 1,
|
||||
});
|
||||
this_hand = this_hand.resize(Size {
|
||||
width: this_hand.width,
|
||||
height: 4,
|
||||
});
|
||||
let [hand_area, drawn_area, meld_area] = hand_draw_meld.areas::<3>(this_hand);
|
||||
|
||||
// split hand area into tile areas
|
||||
let mut constraints = vec![Constraint::Max(5); hand.len()];
|
||||
constraints.push(Constraint::Fill(1));
|
||||
let layout = Layout::horizontal(constraints).flex(Flex::Start);
|
||||
let tile_areas = layout.split(hand_area);
|
||||
// split hand area into tile areas
|
||||
let mut constraints = vec![Constraint::Max(5); hand.len()];
|
||||
constraints.push(Constraint::Fill(1));
|
||||
let layout = Layout::horizontal(constraints).flex(Flex::Start);
|
||||
let tile_areas = layout.split(hand_area);
|
||||
|
||||
for ((entity, widget, hovered), mut area) in
|
||||
hand.into_iter().zip(tile_areas.iter().copied())
|
||||
{
|
||||
if hovered {
|
||||
area = area.offset(Offset { x: 0, y: -1 });
|
||||
let mut hitbox = area.as_size();
|
||||
hitbox.height += 1;
|
||||
commands.entity(entity).insert(PickRegion {
|
||||
area: area.resize(hitbox),
|
||||
});
|
||||
} else {
|
||||
commands.entity(entity).insert(PickRegion { area });
|
||||
for ((entity, widget, hovered), mut area) in
|
||||
hand.into_iter().zip(tile_areas.iter().copied())
|
||||
{
|
||||
if hovered {
|
||||
area = area.offset(Offset { x: 0, y: -1 });
|
||||
let mut hitbox = area.as_size();
|
||||
hitbox.height += 1;
|
||||
commands.entity(entity).insert(PickRegion {
|
||||
area: area.resize(hitbox),
|
||||
});
|
||||
} else {
|
||||
commands.entity(entity).insert(PickRegion { area });
|
||||
}
|
||||
frame.render_widget(widget, area);
|
||||
}
|
||||
frame.render_widget(widget, area);
|
||||
}
|
||||
|
||||
// tsumo tile
|
||||
// if this_drawer {
|
||||
// // trace!("this_drawer");
|
||||
// let mut area = drawn_area.resize(Size {
|
||||
// width: 5,
|
||||
// height: 4,
|
||||
// });
|
||||
// area = area.offset(Offset { x: 2, y: 0 });
|
||||
// let hovered = hovered.contains(*drawn_tile);
|
||||
// let widget = render_tile(tiles.get(*drawn_tile)?, hovered);
|
||||
// if hovered {
|
||||
// area = area.offset(Offset { x: 0, y: -1 });
|
||||
// let mut hitbox = area.as_size();
|
||||
// hitbox.height += 1;
|
||||
// commands.entity(*drawn_tile).insert(PickRegion {
|
||||
// area: area.resize(hitbox),
|
||||
// });
|
||||
// } else {
|
||||
// commands.entity(*drawn_tile).insert(PickRegion { area });
|
||||
// }
|
||||
// frame.render_widget(widget, area);
|
||||
// }
|
||||
// TODO draw melds
|
||||
// } else {
|
||||
// match mainplayer.1.relate(wind) {
|
||||
// jong::game::round::WindRelation::Shimocha => todo!(),
|
||||
// jong::game::round::WindRelation::Toimen => todo!(),
|
||||
// jong::game::round::WindRelation::Kamicha => todo!(),
|
||||
// }
|
||||
// }
|
||||
// tsumo tile
|
||||
if this_drawer {
|
||||
// trace!("this_drawer");
|
||||
let mut area = drawn_area.resize(Size {
|
||||
width: 5,
|
||||
height: 4,
|
||||
});
|
||||
area = area.offset(Offset { x: 2, y: 0 });
|
||||
let hovered = hovered.contains(*drawn_tile);
|
||||
let widget = render_tile(tiles.get(*drawn_tile)?, hovered);
|
||||
if hovered {
|
||||
area = area.offset(Offset { x: 0, y: -1 });
|
||||
let mut hitbox = area.as_size();
|
||||
hitbox.height += 1;
|
||||
commands.entity(*drawn_tile).insert(PickRegion {
|
||||
area: area.resize(hitbox),
|
||||
});
|
||||
} else {
|
||||
commands.entity(*drawn_tile).insert(PickRegion { area });
|
||||
}
|
||||
frame.render_widget(widget, area);
|
||||
}
|
||||
// TODO draw melds
|
||||
} else {
|
||||
// match mainplayer.1.relate(wind) {
|
||||
// jong::game::round::WindRelation::Shimocha => todo!(),
|
||||
// jong::game::round::WindRelation::Toimen => todo!(),
|
||||
// jong::game::round::WindRelation::Kamicha => todo!(),
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
4
justfile
4
justfile
|
|
@ -8,8 +8,8 @@ default:
|
|||
just --list
|
||||
|
||||
run-tui:
|
||||
mprocs -s localhost:4050 --ctl $"({c: restart-proc, name: spacetimedb_generate_bindings} | to yaml)"
|
||||
sleep 3sec
|
||||
# mprocs -s localhost:4050 --ctl $"({c: restart-proc, name: spacetimedb_generate_bindings} | to yaml)"
|
||||
# sleep 3sec
|
||||
cargo run -- run-tui
|
||||
|
||||
update:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use log::{info, trace};
|
||||
use spacetimedb::{ReducerContext, Table, reducer};
|
||||
|
||||
use crate::tables::{player::player, *};
|
||||
use crate::tables::*;
|
||||
use jong_types::*;
|
||||
|
||||
mod hand;
|
||||
|
|
@ -50,8 +50,8 @@ pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> {
|
|||
let bot = ctx.db.bot().insert(Bot {
|
||||
id: 0,
|
||||
lobby_id,
|
||||
hand: vec![],
|
||||
pond: vec![],
|
||||
hand_id: 0,
|
||||
pond_id: 0,
|
||||
});
|
||||
lobby.players.push(PlayerOrBot::Bot { id: bot.id });
|
||||
ctx.db.lobby().id().update(lobby);
|
||||
|
|
@ -80,7 +80,7 @@ pub fn start_game(ctx: &ReducerContext) {
|
|||
PlayerOrBot::Bot { id } => ctx.db.bot().id().find(id).is_some(),
|
||||
})
|
||||
{
|
||||
lobby.game_state = GameState::Setup;
|
||||
lobby.game_state = GameState::Deal;
|
||||
ctx.db.lobby().id().update(lobby);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use spacetimedb::{ReducerContext, Table, ViewContext, reducer, view};
|
||||
|
||||
use crate::tables::{player::player, *};
|
||||
use crate::tables::*;
|
||||
use jong_types::*;
|
||||
|
||||
pub fn deal_hands(ctx: &ReducerContext, lobby_id: u32) {
|
||||
|
|
@ -12,28 +12,40 @@ pub fn deal_hands(ctx: &ReducerContext, lobby_id: u32) {
|
|||
// FIXME rectify deal orders
|
||||
for mut player in players {
|
||||
let mut tiles = wall.tiles.split_off(wall.tiles.len() - 13);
|
||||
wall = ctx.db.wall().lobby_id().update(wall);
|
||||
tiles.sort();
|
||||
player.hand = tiles;
|
||||
wall = ctx.db.wall().lobby_id().update(wall);
|
||||
let hand = ctx.db.hand().insert(Hand {
|
||||
id: 0,
|
||||
owner: PlayerOrBot::Player { id: player.id },
|
||||
sort: true,
|
||||
tiles,
|
||||
});
|
||||
player.hand_id = hand.id;
|
||||
ctx.db.player().id().update(player);
|
||||
}
|
||||
for mut bot in bots {
|
||||
let mut tiles = wall.tiles.split_off(wall.tiles.len() - 13);
|
||||
wall = ctx.db.wall().lobby_id().update(wall);
|
||||
tiles.sort();
|
||||
bot.hand = tiles;
|
||||
wall = ctx.db.wall().lobby_id().update(wall);
|
||||
let hand = ctx.db.hand().insert(Hand {
|
||||
id: 0,
|
||||
owner: PlayerOrBot::Bot { id: bot.id },
|
||||
sort: true,
|
||||
tiles,
|
||||
});
|
||||
bot.hand_id = hand.id;
|
||||
ctx.db.bot().id().update(bot);
|
||||
}
|
||||
}
|
||||
|
||||
// #[view(name = view_player_hand, public)]
|
||||
// pub fn view_player_hand(ctx: &ViewContext) -> Option<Hand> {
|
||||
// ctx.db
|
||||
// .player()
|
||||
// .identity()
|
||||
// .find(ctx.sender)
|
||||
// .map(|p| ctx.db.hand().id().find(p.hand_id))?
|
||||
// }
|
||||
#[view(name = view_player_hand, public)]
|
||||
pub fn view_player_hand(ctx: &ViewContext) -> Option<Hand> {
|
||||
ctx.db
|
||||
.player()
|
||||
.identity()
|
||||
.find(ctx.sender)
|
||||
.map(|p| ctx.db.hand().id().find(p.hand_id))?
|
||||
}
|
||||
|
||||
// #[reducer]
|
||||
// pub fn sort_hand(ctx: &ReducerContext) {
|
||||
|
|
|
|||
|
|
@ -10,10 +10,7 @@ pub fn shuffle_deal(ctx: &ReducerContext, lobby_id: u32) {
|
|||
debug!("lobby_id: {lobby_id}");
|
||||
let mut lobby = ctx.db.lobby().id().find(lobby_id).unwrap();
|
||||
|
||||
if lobby.game_state == GameState::Setup {
|
||||
lobby.game_state = GameState::Deal;
|
||||
lobby = ctx.db.lobby().id().update(lobby);
|
||||
|
||||
if lobby.game_state == GameState::Deal {
|
||||
let tiles = new_shuffled_wall(ctx);
|
||||
ctx.db.wall().insert(Wall {
|
||||
// id: 0,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use log::info;
|
||||
use spacetimedb::{ReducerContext, Table, reducer};
|
||||
|
||||
use crate::tables::{player::player, *};
|
||||
use crate::tables::*;
|
||||
|
||||
mod game;
|
||||
mod tables;
|
||||
|
|
@ -16,10 +16,9 @@ pub fn login_or_add_player(ctx: &ReducerContext) {
|
|||
id: 0,
|
||||
name: None,
|
||||
lobby_id: 0,
|
||||
hand_id: 0,
|
||||
pond_id: 0,
|
||||
ready: false,
|
||||
sort: true,
|
||||
hand: vec![],
|
||||
pond: vec![],
|
||||
}) {
|
||||
info!("added player: {:?}", player);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,44 @@
|
|||
use spacetimedb::{Filter, SpacetimeType, client_visibility_filter, table};
|
||||
use spacetimedb::{Identity, SpacetimeType, table};
|
||||
|
||||
use jong_types::*;
|
||||
|
||||
pub mod player;
|
||||
pub use player::*;
|
||||
#[derive(Debug)]
|
||||
#[table(name = player, public)]
|
||||
pub struct Player {
|
||||
#[primary_key]
|
||||
pub identity: Identity,
|
||||
|
||||
#[unique]
|
||||
#[auto_inc]
|
||||
pub id: u32,
|
||||
|
||||
pub name: Option<String>,
|
||||
|
||||
#[index(btree)]
|
||||
pub lobby_id: u32,
|
||||
pub hand_id: u32,
|
||||
pub pond_id: u32,
|
||||
|
||||
pub ready: bool,
|
||||
}
|
||||
|
||||
#[table(name = bot)]
|
||||
pub struct Bot {
|
||||
#[primary_key]
|
||||
#[auto_inc]
|
||||
pub id: u32,
|
||||
|
||||
#[index(btree)]
|
||||
pub lobby_id: u32,
|
||||
pub hand_id: u32,
|
||||
pub pond_id: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, SpacetimeType)]
|
||||
pub enum PlayerOrBot {
|
||||
Player { id: u32 },
|
||||
Bot { id: u32 },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[table(name = lobby, public)]
|
||||
|
|
@ -14,7 +49,7 @@ pub struct Lobby {
|
|||
|
||||
#[unique]
|
||||
pub host_player_id: u32,
|
||||
pub players: Vec<player::PlayerOrBot>,
|
||||
pub players: Vec<PlayerOrBot>,
|
||||
|
||||
pub game_state: GameState,
|
||||
pub turn_state: TurnState,
|
||||
|
|
@ -27,3 +62,26 @@ pub struct Wall {
|
|||
|
||||
pub tiles: Vec<Tile>,
|
||||
}
|
||||
|
||||
#[table(name = hand)]
|
||||
pub struct Hand {
|
||||
#[primary_key]
|
||||
#[auto_inc]
|
||||
pub id: u32,
|
||||
|
||||
pub owner: PlayerOrBot,
|
||||
|
||||
pub sort: bool,
|
||||
pub tiles: Vec<Tile>,
|
||||
}
|
||||
|
||||
#[table(name = pond, public)]
|
||||
pub struct Pond {
|
||||
#[primary_key]
|
||||
#[auto_inc]
|
||||
pub id: u32,
|
||||
|
||||
pub owner: PlayerOrBot,
|
||||
|
||||
pub tiles: Vec<Tile>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
use spacetimedb::Identity;
|
||||
use spacetimedb::{SpacetimeType, table};
|
||||
|
||||
use jong_types::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[table(name = player, public)]
|
||||
pub struct Player {
|
||||
#[primary_key]
|
||||
pub identity: Identity,
|
||||
|
||||
#[unique]
|
||||
#[auto_inc]
|
||||
pub id: u32,
|
||||
|
||||
pub name: Option<String>,
|
||||
|
||||
#[index(btree)]
|
||||
pub lobby_id: u32,
|
||||
pub ready: bool,
|
||||
|
||||
pub sort: bool,
|
||||
|
||||
pub hand: Vec<Tile>,
|
||||
pub pond: Vec<Tile>,
|
||||
}
|
||||
|
||||
#[table(name = bot)]
|
||||
pub struct Bot {
|
||||
#[primary_key]
|
||||
#[auto_inc]
|
||||
pub id: u32,
|
||||
|
||||
#[index(btree)]
|
||||
pub lobby_id: u32,
|
||||
|
||||
pub hand: Vec<Tile>,
|
||||
pub pond: Vec<Tile>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, SpacetimeType)]
|
||||
pub enum PlayerOrBot {
|
||||
Player { id: u32 },
|
||||
Bot { id: u32 },
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue