diff --git a/devenv.nix b/devenv.nix index 72ac11b..782205c 100644 --- a/devenv.nix +++ b/devenv.nix @@ -3,9 +3,6 @@ lib, ... }: rec { - env.RUST_LOG = "jong=trace"; - env.RUST_BACKTRACE = "1"; - # https://devenv.sh/processes/ processes.lspmux.exec = "lspmux server"; processes.spacetimedb_start.exec = "spacetime start"; @@ -47,6 +44,8 @@ wayland ]; env.LD_LIBRARY_PATH = lib.makeLibraryPath packages; + env.RUST_LOG = "jong=trace"; + env.RUST_BACKTRACE = "full"; # https://devenv.sh/languages/ languages.rust = { diff --git a/jong-db/src/db/bot_table.rs b/jong-db/src/db/bot_table.rs index be072da..73bc154 100644 --- a/jong-db/src/db/bot_table.rs +++ b/jong-db/src/db/bot_table.rs @@ -125,41 +125,10 @@ impl<'ctx> BotIdUnique<'ctx> { } } -/// Access to the `config_id` unique index on the table `bot`, -/// which allows point queries on the field of the same name -/// via the [`BotConfigIdUnique::find`] method. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.bot().config_id().find(...)`. -pub struct BotConfigIdUnique<'ctx> { - imp: __sdk::UniqueConstraintHandle, - phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -impl<'ctx> BotTableHandle<'ctx> { - /// Get a handle on the `config_id` unique index on the table `bot`. - pub fn config_id(&self) -> BotConfigIdUnique<'ctx> { - BotConfigIdUnique { - imp: self.imp.get_unique_constraint::("config_id"), - phantom: std::marker::PhantomData, - } - } -} - -impl<'ctx> BotConfigIdUnique<'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 { - self.imp.find(col_val) - } -} - #[doc(hidden)] pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { let _table = client_cache.get_or_make_table::("bot"); _table.add_unique_constraint::("id", |row| &row.id); - _table.add_unique_constraint::("config_id", |row| &row.config_id); } #[doc(hidden)] diff --git a/jong-db/src/db/bot_type.rs b/jong-db/src/db/bot_type.rs index dcb1bb8..a49650a 100644 --- a/jong-db/src/db/bot_type.rs +++ b/jong-db/src/db/bot_type.rs @@ -40,7 +40,6 @@ impl __sdk::__query_builder::HasCols for Bot { /// /// Provides typed access to indexed columns for query building. pub struct BotIxCols { - pub config_id: __sdk::__query_builder::IxCol, pub id: __sdk::__query_builder::IxCol, pub lobby_id: __sdk::__query_builder::IxCol, } @@ -49,7 +48,6 @@ impl __sdk::__query_builder::HasIxCols for Bot { type IxCols = BotIxCols; fn ix_cols(table_name: &'static str) -> Self::IxCols { BotIxCols { - config_id: __sdk::__query_builder::IxCol::new(table_name, "config_id"), id: __sdk::__query_builder::IxCol::new(table_name, "id"), lobby_id: __sdk::__query_builder::IxCol::new(table_name, "lobby_id"), } diff --git a/jong-line/src/tables.rs b/jong-line/src/tables.rs index 4c22804..0b09f6c 100644 --- a/jong-line/src/tables.rs +++ b/jong-line/src/tables.rs @@ -72,7 +72,6 @@ pub struct Bot { #[index(btree)] pub lobby_id: u32, - #[unique] pub config_id: u32, } @@ -150,21 +149,16 @@ fn view_closed_hands(ctx: &ViewContext) -> Vec { .players .iter() .filter_map(|id| { - if *id == this_player.config_id { - None - } else { - ctx.db - .player_hand() - .player_id() - .find(id) - .map(|hand| HandView { - player_id: hand.player_id, - hand_length: hand.hand.len() as u8, - pond: hand.pond, - drawn: hand.turn_state == TurnState::Tsumo - && hand.working_tile.is_some(), - }) - } + ctx.db + .player_hand() + .player_id() + .find(id) + .map(|hand| HandView { + player_id: hand.player_id, + hand_length: hand.hand.len() as u8, + pond: hand.pond, + drawn: hand.turn_state == TurnState::Tsumo && hand.working_tile.is_some(), + }) }) .collect() } else { diff --git a/jong/src/riichi.rs b/jong/src/riichi.rs index bb4b9fd..7da69e4 100644 --- a/jong/src/riichi.rs +++ b/jong/src/riichi.rs @@ -5,9 +5,9 @@ use bevy::render::render_resource::AsBindGroupShaderType; use bevy_spacetimedb::{ReadInsertMessage, ReadInsertUpdateMessage, ReadUpdateMessage, StdbPlugin}; use jong_db::{ - self, HandView, PlayerClockTableAccess, PlayerConfigTableAccess, UserTableAccess, add_bot, - advance_game, join_or_create_lobby, lobbyQueryTableAccess, player_configQueryTableAccess, - set_ready, userQueryTableAccess, + self, PlayerClockTableAccess, PlayerConfigTableAccess, UserTableAccess, add_bot, advance_game, + join_or_create_lobby, lobbyQueryTableAccess, player_configQueryTableAccess, set_ready, + userQueryTableAccess, }; use jong_db::{ BotTableAccess, DbConnection, LobbyTableAccess, PlayerHand, RemoteTables, @@ -61,13 +61,7 @@ impl Plugin for Riichi { ) .add_systems( Update, - ( - on_view_hand_insert, - on_view_hand_update, - on_view_closed_insert, - on_view_closed_update, - ) - .after(on_player_config_insert_update) + (on_view_hand_insert, on_view_hand_update) .run_if(in_state(GameState::Play).or(in_state(GameState::Deal))), ); } @@ -171,16 +165,13 @@ fn on_player_config_insert_update( players: Query<(Entity, &Player)>, ) { for msg in messages.read() { - trace!("on_player_config_insert_update"); + trace!("on_player_insert_update"); let player = &msg.new; let player_ent = players .iter() .find_map(|(e, p)| (p.id == player.id).then_some(e)) - .unwrap_or_else(|| { - trace!("spawn_player"); - commands.spawn(Player { id: player.id }).id() - }); + .unwrap_or_else(|| commands.spawn(Player { id: player.id }).id()); if player.id == stdb @@ -200,7 +191,6 @@ fn on_player_config_insert_update( fn on_view_hand_insert( mut messages: ReadInsertMessage, mut commands: Commands, - players: Populated<(Entity, &Player, Option<&Children>)>, tiles: Query<(Entity, &TileId)>, hands: Query<(Entity, &Hand)>, ponds: Query<(Entity, &Pond)>, @@ -210,7 +200,6 @@ fn on_view_hand_insert( trace!("on_view_hand_insert"); sync_open_hand( &mut commands, - &players, tiles, hands, ponds, @@ -223,7 +212,6 @@ fn on_view_hand_insert( fn on_view_hand_update( mut messages: ReadUpdateMessage, mut commands: Commands, - players: Populated<(Entity, &Player, Option<&Children>)>, tiles: Query<(Entity, &TileId)>, hands: Query<(Entity, &Hand)>, ponds: Query<(Entity, &Pond)>, @@ -233,7 +221,6 @@ fn on_view_hand_update( trace!("on_view_hand_update"); sync_open_hand( &mut commands, - &players, tiles, hands, ponds, @@ -245,7 +232,6 @@ fn on_view_hand_update( fn sync_open_hand( commands: &mut Commands, - players: &Populated<(Entity, &Player, Option<&Children>)>, tiles: Query<(Entity, &TileId)>, hands: Query<(Entity, &Hand)>, ponds: Query<(Entity, &Pond)>, @@ -253,28 +239,14 @@ fn sync_open_hand( player_hand: &PlayerHand, ) { let player_id = player_hand.player_id; - - let (player_ent, player_children) = players - .iter() - .find_map(|(e, p, c)| (p.id == player_id).then_some((e, c))) - .unwrap(); - let hand_ent = hands .iter() - .find_map(|(e, _)| player_children.is_some_and(|c| c.contains(&e)).then_some(e)) - .unwrap_or_else(|| { - let id = commands.spawn(Hand).id(); - commands.entity(player_ent).add_child(id); - id - }); + .find_map(|(e, h)| (h.player_id == player_id).then_some(e)) + .unwrap_or_else(|| commands.spawn(Hand { player_id }).id()); let pond_ent = ponds .iter() - .find_map(|(e, _)| player_children.is_some_and(|c| c.contains(&e)).then_some(e)) - .unwrap_or_else(|| { - let id = commands.spawn(Pond).id(); - commands.entity(player_ent).add_child(id); - id - }); + .find_map(|(e, p)| (p.player_id == player_id).then_some(e)) + .unwrap_or_else(|| commands.spawn(Pond { player_id }).id()); // hand and pond both still need ability to spawn for the reconnect case let hand: Vec = player_hand @@ -304,97 +276,60 @@ fn sync_open_hand( if let Some(dbt) = &player_hand.working_tile && player_hand.turn_state == jong_db::TurnState::Tsumo { - let id = commands - .spawn((Drawn, Tile::from(&dbt.tile), TileId(dbt.id))) - .id(); - commands.entity(player_ent).add_child(id); - } else { - // TODO clear Drawn from auto-discarded tile + commands.spawn((Drawn, Tile::from(&dbt.tile), TileId(dbt.id))); } next_turnstate.set(player_hand.turn_state.into()); } -fn on_view_closed_insert( - mut messages: ReadInsertMessage, - mut commands: Commands, - players: Populated<(Entity, &Player, Option<&Children>)>, - tiles: Query<(Entity, &TileId)>, - hands: Query<(Entity, &Hand)>, - ponds: Query<(Entity, &Pond)>, -) { - for msg in messages.read() { - trace!("on_view_closed_insert"); - sync_closed_hand(&mut commands, &players, tiles, hands, ponds, &msg.row); - } -} +// fn sync_closed_hand( +// stdb: SpacetimeDB, -fn on_view_closed_update( - mut messages: ReadUpdateMessage, - mut commands: Commands, - players: Populated<(Entity, &Player, Option<&Children>)>, - tiles: Query<(Entity, &TileId)>, - hands: Query<(Entity, &Hand)>, - ponds: Query<(Entity, &Pond)>, -) { - for msg in messages.read() { - trace!("on_view_closed_update"); - sync_closed_hand(&mut commands, &players, tiles, hands, ponds, &msg.new); - } -} +// mut messages: MessageReader, +// mut commands: Commands, -fn sync_closed_hand( - commands: &mut Commands, - players: &Populated<(Entity, &Player, Option<&Children>)>, - tiles: Query<(Entity, &TileId)>, - hands: Query<(Entity, &Hand)>, - ponds: Query<(Entity, &Pond)>, - hand_view: &HandView, -) { - let player_id = hand_view.player_id; +// 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 (player_ent, player_children) = players - .iter() - .find_map(|(e, p, c)| (p.id == player_id).then_some((e, c))) - .unwrap(); +// let hand_ent = hands +// .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 hand_ent = hands - .iter() - .find_map(|(e, _)| player_children.is_some_and(|c| c.contains(&e)).then_some(e)) - .unwrap_or_else(|| { - let id = commands.spawn(Hand).id(); - commands.entity(player_ent).add_child(id); - id - }); - let pond_ent = ponds - .iter() - .find_map(|(e, _)| player_children.is_some_and(|c| c.contains(&e)).then_some(e)) - .unwrap_or_else(|| { - let id = commands.spawn(Pond).id(); - commands.entity(player_ent).add_child(id); - id - }); +// let pond: Vec = hand_view +// .pond +// .iter() +// .map(|dbt| { +// tiles +// .iter() +// .find_map(|(e, i)| (i.0 == dbt.id).then_some(e)) +// .unwrap_or_else(|| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id()) +// }) +// .collect(); - let pond: Vec = hand_view - .pond - .iter() - .map(|dbt| { - tiles - .iter() - .find_map(|(e, i)| (i.0 == dbt.id).then_some(e)) - .unwrap_or_else(|| commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id()) - }) - .collect(); +// commands.entity(hand_ent).insert(Closed { +// length: hand_view.hand_length, +// }); +// commands.entity(pond_ent).replace_children(&pond); - commands.entity(hand_ent).insert(Closed { - length: hand_view.hand_length, - }); - commands.entity(pond_ent).replace_children(&pond); +// if hand_view.drawn { +// commands.spawn(Drawn); +// } +// } +// } - if hand_view.drawn { - let id = commands.spawn(Drawn).id(); - commands.entity(player_ent).add_child(id); - } else { - // TODO clear Drawn from auto-discarded tile - } -} diff --git a/jong/src/riichi/connection.rs b/jong/src/riichi/connection.rs index f33d96f..b869105 100644 --- a/jong/src/riichi/connection.rs +++ b/jong/src/riichi/connection.rs @@ -8,7 +8,7 @@ pub(crate) fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessa for msg in messages.read() { info!("you're now jongline"); - // debug!("with identity: {}", stdb.identity()); + debug!("with identity: {}", stdb.identity()); creds_store() .save(&msg.access_token) .expect("i/o error saving token"); diff --git a/jong/src/riichi/player.rs b/jong/src/riichi/player.rs index a489ad6..bb90d87 100644 --- a/jong/src/riichi/player.rs +++ b/jong/src/riichi/player.rs @@ -22,15 +22,20 @@ pub struct LeftLord; pub struct TileId(pub u32); #[derive(Component)] -pub struct Hand; +pub struct Hand { + pub player_id: u32, +} #[derive(Component)] pub struct Closed { + pub player_id: u32, pub(crate) length: u8, } #[derive(Component)] -pub struct Pond; +pub struct Pond { + pub player_id: u32, +} #[derive(Component)] pub struct Drawn; diff --git a/jong/src/tui.rs b/jong/src/tui.rs index db0267b..fa38da2 100644 --- a/jong/src/tui.rs +++ b/jong/src/tui.rs @@ -1,3 +1,5 @@ +#![allow(unused)] + use std::time::Duration; use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin}; @@ -82,7 +84,7 @@ impl Plugin for TuiPlugin { .add_systems( Update, ( - (render::render_main_hand, render::render_main_pond, render::render_other_hands) + (render::render_main_hand, render::render_main_pond) .run_if(in_state(GameState::Play).or(in_state(GameState::Deal))), render::render, ) diff --git a/jong/src/tui/input/keyboard.rs b/jong/src/tui/input/keyboard.rs index 88c5c36..64685d6 100644 --- a/jong/src/tui/input/keyboard.rs +++ b/jong/src/tui/input/keyboard.rs @@ -7,9 +7,9 @@ use tui_logger::TuiWidgetEvent; use jong::SpacetimeDB; use jong_db::{ - LobbyTableAccess, UserTableAccess, botQueryTableAccess, join_or_create_lobby, - lobbyQueryTableAccess, player_clockQueryTableAccess, player_configQueryTableAccess, - view_closed_handsQueryTableAccess, view_handQueryTableAccess, + LobbyTableAccess, UserTableAccess, botQueryTableAccess, + join_or_create_lobby, lobbyQueryTableAccess, player_clockQueryTableAccess, + player_configQueryTableAccess, view_closed_handsQueryTableAccess, view_handQueryTableAccess, }; use jong_types::GameState; @@ -78,14 +78,6 @@ pub(crate) fn keyboard( .player_config() .r#where(|pc| pc.id.eq(user.config_id)) }) - .add_query(|q| { - q.from - .bot() - .r#where(|b| b.lobby_id.eq(lobby_id)) - .right_semijoin(q.from.player_config(), |b, pc| { - b.config_id.eq(pc.id) - }) - }) .add_query(|q| { q.from .player_clock() diff --git a/jong/src/tui/render.rs b/jong/src/tui/render.rs index 83aa271..2d40ff6 100644 --- a/jong/src/tui/render.rs +++ b/jong/src/tui/render.rs @@ -7,7 +7,7 @@ use ratatui::style::{Color, Modifier, Style, Stylize}; use ratatui::text::{Line, Span, Text}; use ratatui::widgets::{Block, Borders, Clear, Paragraph}; -use jong::riichi::{Lobby, player::*}; +use jong::riichi::player::*; use jong_types::*; use crate::tui::input::Hovered; @@ -150,9 +150,9 @@ pub(crate) fn render_main_hand( tiles: Query<&jong_types::Tile>, hovered: Query>, - main_player: Single<(&Player, &Children), With>, + main_player: Single<&Player, With>, - hands: Query<(Entity, &Hand, &Children)>, + hands: Query<(&Hand, &Children)>, drawn_tile: Option>>, ) -> Result { let mut frame = tui.get_frame(); @@ -164,7 +164,7 @@ pub(crate) fn render_main_hand( let hand: Vec<_> = hands .iter() - .find_map(|(e, h, c)| (main_player.1.contains(&e)).then_some(c)) + .find_map(|(h, c)| (main_player.id == h.player_id).then_some(c)) .unwrap() .iter() .map(|entity| -> Result<_> { @@ -217,9 +217,7 @@ pub(crate) fn render_main_hand( } // tsumo tile - if let Some(drawn_tile) = drawn_tile - && main_player.1.contains(&*drawn_tile) - { + if let Some(drawn_tile) = drawn_tile { let mut area = drawn_area.resize(Size { width: 5, height: 4, @@ -261,9 +259,9 @@ pub(crate) fn render_main_pond( tiles: Query<&Tile>, hovered: Query>, - main_player: Single<(&Player, &Children), With>, + main_player: Single<&Player, With>, - pond: Query<(Entity, &Pond, &Children)>, + pond: Query<(&Pond, &Children)>, ) -> Result { let mut frame = tui.get_frame(); @@ -273,7 +271,7 @@ pub(crate) fn render_main_pond( let pond: Vec<_> = pond .iter() - .find_map(|(e, p, c)| (main_player.1.contains(&e)).then_some(c)) + .find_map(|(p, c)| (main_player.id == p.player_id).then_some(c)) .unwrap() .iter() .map(|entity| -> Result<_> { @@ -291,51 +289,4 @@ pub(crate) fn render_main_pond( Ok(()) } -pub(crate) fn render_other_hands( - mut tui: ResMut, - layouts: Res, - - lobby: Res, - - main_player: Single<&Player, With>, - players: Query<(&Player, &Children), Without>, - hands: Query<(Entity, &Closed)>, - ponds: Query<(Entity, &Children), With>, - drawn: Option>>, -) { - let mut frame = tui.get_frame(); - - let main_idx = lobby - .players - .iter() - .position(|id| *id == main_player.id) - .unwrap(); - - let mut player_it = lobby.players.iter().copied().cycle().skip(main_idx + 1); - - let right_id = player_it.next().unwrap(); - let top_id = player_it.next().unwrap(); - let left_id = player_it.next().unwrap(); - - { - let children = players - .iter() - .find_map(|(p, c)| (p.id == right_id).then_some(c)) - .unwrap(); - let hand = hands - .iter() - .find_map(|(e, h)| children.contains(&e).then_some(h)) - .unwrap(); - // let pond = ponds - // .iter() - // .find_map(|(e, c)| children.contains(&e).then_some(c)) - // .unwrap(); - let drawn = drawn.is_some_and(|e| children.contains(&*e)); - - // let hand_draw_meld = Layout::vertical([ - // Constraint::() - // ]) - } - {} - {} -} +pub(crate) fn render_other_hands() {}