From c3686221aa1e518c1cd841dd67e54b8fbd16f08d Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Mon, 16 Feb 2026 00:05:57 -0800 Subject: [PATCH] more refactor, start using stdb for everything??? 4.5th rewrite for tui --- .helix/languages.toml | 10 +- devenv.nix | 4 +- jong-db/src/lib.rs | 90 +++---- jong-line/src/lib.rs | 16 +- jong-line/src/reducers/{game => }/bot.rs | 0 jong-line/src/reducers/{game => }/deal.rs | 11 +- jong-line/src/reducers/{game => }/hand.rs | 6 +- jong-line/src/reducers/{game.rs => lobby.rs} | 12 +- jong-line/src/tables.rs | 17 +- jong-line/src/tables/player.rs | 6 - jong-types/src/lib.rs | 127 +--------- jong-types/src/states.rs | 37 +++ jong-types/src/tiles.rs | 94 ++++++++ jong/src/game/hand.rs | 41 ---- jong/src/game/player.rs | 21 -- jong/src/game/round.rs | 232 ------------------- jong/src/game/wall.rs | 7 - jong/src/gui/mod.rs | 29 --- jong/src/lib.rs | 7 +- jong/src/main.rs | 18 +- jong/src/{game.rs => riichi.rs} | 97 +++----- jong/src/riichi/player.rs | 25 ++ jong/src/riichi/round.rs | 100 ++++++++ jong/src/tile.rs | 11 - jong/src/tui.rs | 38 ++- jong/src/tui/input/keyboard.rs | 5 +- jong/src/tui/render.rs | 156 +++++-------- jong/src/yakus.rs | 1 - justfile | 4 +- 29 files changed, 478 insertions(+), 744 deletions(-) rename jong-line/src/reducers/{game => }/bot.rs (100%) rename jong-line/src/reducers/{game => }/deal.rs (73%) rename jong-line/src/reducers/{game => }/hand.rs (97%) rename jong-line/src/reducers/{game.rs => lobby.rs} (91%) create mode 100644 jong-types/src/states.rs create mode 100644 jong-types/src/tiles.rs delete mode 100644 jong/src/game/hand.rs delete mode 100644 jong/src/game/player.rs delete mode 100644 jong/src/game/round.rs delete mode 100644 jong/src/game/wall.rs delete mode 100644 jong/src/gui/mod.rs rename jong/src/{game.rs => riichi.rs} (72%) create mode 100644 jong/src/riichi/player.rs create mode 100644 jong/src/riichi/round.rs delete mode 100644 jong/src/tile.rs delete mode 100644 jong/src/yakus.rs diff --git a/.helix/languages.toml b/.helix/languages.toml index 3b9df02..a35a590 100644 --- a/.helix/languages.toml +++ b/.helix/languages.toml @@ -1,6 +1,6 @@ -# [language-server.lspmux] -# command = "lspmux" +[language-server.lspmux] +command = "lspmux" -# [[language]] -# name = "rust" -# language-servers = ["lspmux"] +[[language]] +name = "rust" +language-servers = ["lspmux"] diff --git a/devenv.nix b/devenv.nix index ea36f0b..af52a59 100644 --- a/devenv.nix +++ b/devenv.nix @@ -4,10 +4,10 @@ ... }: rec { # https://devenv.sh/processes/ - # processes.lspmux.exec = "lspmux server"; + processes.lspmux.exec = "lspmux server"; processes.spacetimedb_start.exec = "spacetime start"; processes.spacetimedb_dev = { - exec = "spacetime dev --module-bindings-path jong-db/src/db jong-line --delete-data=always"; + exec = "just spacetime_dev"; # notify.enable = true; # TODO features not yet supp??? # restart = "always"; diff --git a/jong-db/src/lib.rs b/jong-db/src/lib.rs index c6f9297..0d2a8d5 100644 --- a/jong-db/src/lib.rs +++ b/jong-db/src/lib.rs @@ -1,54 +1,56 @@ pub mod db; pub use db::*; -impl From for jong_types::GameState { - fn from(value: GameState) -> Self { - Self::from_repr(value as usize).unwrap() +mod conversions { + impl From for jong_types::states::GameState { + fn from(value: crate::db::GameState) -> Self { + Self::from_repr(value as usize).unwrap() + } } -} -impl From for jong_types::TurnState { - fn from(value: TurnState) -> Self { - Self::from_repr(value as usize).unwrap() + impl From for jong_types::states::TurnState { + fn from(value: crate::db::TurnState) -> Self { + Self::from_repr(value as usize).unwrap() + } } -} -impl From<&Tile> for jong_types::Tile { - fn from(value: &tile_type::Tile) -> Self { - Self { - suit: value.suit.clone().into(), + impl From<&crate::db::Tile> for jong_types::tiles::Tile { + fn from(value: &crate::db::Tile) -> Self { + Self { + suit: value.suit.clone().into(), + } + } + } + + impl From for jong_types::tiles::Suit { + fn from(value: crate::db::Suit) -> Self { + match value { + crate::db::Suit::Man(rank) => Self::Man(rank.into()), + crate::db::Suit::Pin(rank) => Self::Pin(rank.into()), + crate::db::Suit::Sou(rank) => Self::Sou(rank.into()), + crate::db::Suit::Wind(wind) => Self::Wind(wind.into()), + crate::db::Suit::Dragon(dragon) => Self::Dragon(dragon.into()), + } + } + } + + impl From for jong_types::tiles::Rank { + fn from(value: crate::db::Rank) -> Self { + Self { + number: value.number, + } + } + } + + impl From for jong_types::tiles::Wind { + fn from(value: crate::db::Wind) -> Self { + Self::from_repr(value as usize).unwrap() + } + } + + impl From for jong_types::tiles::Dragon { + fn from(value: crate::db::Dragon) -> Self { + Self::from_repr(value as usize).unwrap() } } } - -impl From for jong_types::Suit { - fn from(value: Suit) -> Self { - match value { - Suit::Man(rank) => Self::Man(rank.into()), - Suit::Pin(rank) => Self::Pin(rank.into()), - Suit::Sou(rank) => Self::Sou(rank.into()), - Suit::Wind(wind) => Self::Wind(wind.into()), - Suit::Dragon(dragon) => Self::Dragon(dragon.into()), - } - } -} - -impl From for jong_types::Rank { - fn from(value: Rank) -> Self { - Self { - number: value.number, - } - } -} - -impl From for jong_types::Wind { - fn from(value: Wind) -> Self { - Self::from_repr(value as usize).unwrap() - } -} - -impl From for jong_types::Dragon { - fn from(value: Dragon) -> Self { - Self::from_repr(value as usize).unwrap() - } -} diff --git a/jong-line/src/lib.rs b/jong-line/src/lib.rs index 4a1b889..b626822 100644 --- a/jong-line/src/lib.rs +++ b/jong-line/src/lib.rs @@ -4,7 +4,9 @@ use spacetimedb::{ReducerContext, Table, reducer}; use crate::tables::{player::player, *}; mod reducers { - mod game; + mod deal; + mod hand; + mod lobby; } mod tables; @@ -13,6 +15,18 @@ 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)] diff --git a/jong-line/src/reducers/game/bot.rs b/jong-line/src/reducers/bot.rs similarity index 100% rename from jong-line/src/reducers/game/bot.rs rename to jong-line/src/reducers/bot.rs diff --git a/jong-line/src/reducers/game/deal.rs b/jong-line/src/reducers/deal.rs similarity index 73% rename from jong-line/src/reducers/game/deal.rs rename to jong-line/src/reducers/deal.rs index 99069f6..e6e280f 100644 --- a/jong-line/src/reducers/game/deal.rs +++ b/jong-line/src/reducers/deal.rs @@ -3,15 +3,14 @@ use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer}; use super::hand::deal_hands; use crate::tables::*; -use jong_types::*; #[reducer] pub fn shuffle_deal(ctx: &ReducerContext, lobby_id: u32) { debug!("lobby_id: {lobby_id}"); let mut lobby = ctx.db.lobby().id().find(lobby_id).unwrap(); - if lobby.game_state == GameState::Setup { - lobby.game_state = GameState::Deal; + if lobby.game_state == jong_types::states::GameState::Setup { + lobby.game_state = jong_types::states::GameState::Deal; lobby = ctx.db.lobby().id().update(lobby); let tiles = new_shuffled_wall(ctx); @@ -24,15 +23,15 @@ pub fn shuffle_deal(ctx: &ReducerContext, lobby_id: u32) { deal_hands(ctx, lobby_id); - lobby.game_state = GameState::Play; - lobby.turn_state = TurnState::Tsumo; + lobby.game_state = jong_types::states::GameState::Play; + lobby.turn_state = jong_types::states::TurnState::Tsumo; ctx.db.lobby().id().update(lobby); } } pub fn new_shuffled_wall(ctx: &ReducerContext) -> Vec { let mut rng = ctx.rng(); - let mut wall: Vec<_> = tiles() + let mut wall: Vec<_> = jong_types::tiles::tiles() .into_iter() .map(|tile| ctx.db.tile().insert(DbTile { id: 0, tile })) .collect(); diff --git a/jong-line/src/reducers/game/hand.rs b/jong-line/src/reducers/hand.rs similarity index 97% rename from jong-line/src/reducers/game/hand.rs rename to jong-line/src/reducers/hand.rs index 96fedb2..06257e7 100644 --- a/jong-line/src/reducers/game/hand.rs +++ b/jong-line/src/reducers/hand.rs @@ -1,8 +1,8 @@ use log::{debug, trace}; -use spacetimedb::{ReducerContext, Table, reducer}; +use spacetimedb::{ReducerContext, reducer}; use crate::tables::{player::player, *}; -use jong_types::*; +use jong_types::states::TurnState; pub fn deal_hands(ctx: &ReducerContext, lobby_id: u32) { let players = ctx.db.player().lobby_id().filter(lobby_id); @@ -79,7 +79,7 @@ pub fn discard_tile(ctx: &ReducerContext, tile_id: u32) -> Result<(), String> { #[reducer] pub fn skip_call(ctx: &ReducerContext) { trace!("skip_call"); - + let player = ctx.db.player().identity().find(ctx.sender).unwrap(); let mut lobby = ctx.db.lobby().id().find(player.lobby_id).unwrap(); diff --git a/jong-line/src/reducers/game.rs b/jong-line/src/reducers/lobby.rs similarity index 91% rename from jong-line/src/reducers/game.rs rename to jong-line/src/reducers/lobby.rs index 0519bd2..1a4df28 100644 --- a/jong-line/src/reducers/game.rs +++ b/jong-line/src/reducers/lobby.rs @@ -2,10 +2,6 @@ use log::info; use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer}; use crate::tables::{player::player, *}; -use jong_types::*; - -mod deal; -mod hand; #[reducer] pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<(), String> { @@ -22,12 +18,12 @@ pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<( id: 0, host_player_id: player.id, players: vec![PlayerOrBot::Player { id: player.id }], - game_state: GameState::Lobby, - turn_state: TurnState::None, + game_state: jong_types::states::GameState::Lobby, + turn_state: jong_types::states::TurnState::None, dealer_idx: 0, current_idx: 0, }); - info!("created lobby: {:?}", lobby); + info!("created lobby: {}", lobby.id); lobby_id = lobby.id; } @@ -83,7 +79,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 = jong_types::states::GameState::Setup; lobby.players.shuffle(&mut ctx.rng()); lobby.dealer_idx += 1; if lobby.dealer_idx > 3 { diff --git a/jong-line/src/tables.rs b/jong-line/src/tables.rs index 4295811..17ec267 100644 --- a/jong-line/src/tables.rs +++ b/jong-line/src/tables.rs @@ -1,6 +1,9 @@ -use spacetimedb::table; +use spacetimedb::{SpacetimeType, table}; -use jong_types::*; +use jong_types::{ + tiles::Tile, + states::{GameState, TurnState}, +}; pub mod player; pub use player::*; @@ -14,7 +17,7 @@ pub struct Lobby { #[unique] pub host_player_id: u32, - pub players: Vec, + pub players: Vec, pub dealer_idx: u8, pub current_idx: u8, @@ -37,5 +40,11 @@ pub struct DbTile { #[auto_inc] pub id: u32, - pub tile: jong_types::Tile, + pub tile: Tile, +} + +#[derive(Debug, Clone, SpacetimeType)] +pub enum PlayerOrBot { + Player { id: u32 }, + Bot { id: u32 }, } diff --git a/jong-line/src/tables/player.rs b/jong-line/src/tables/player.rs index 1767758..c3bf342 100644 --- a/jong-line/src/tables/player.rs +++ b/jong-line/src/tables/player.rs @@ -42,9 +42,3 @@ pub struct Bot { pub drawn_tile: Option, } - -#[derive(Debug, Clone, SpacetimeType)] -pub enum PlayerOrBot { - Player { id: u32 }, - Bot { id: u32 }, -} diff --git a/jong-types/src/lib.rs b/jong-types/src/lib.rs index 27b8fc5..e8c26f3 100644 --- a/jong-types/src/lib.rs +++ b/jong-types/src/lib.rs @@ -9,127 +9,8 @@ mod derive_alias { } use derive_aliases::derive; -use bevy::prelude::*; -use spacetimedb::SpacetimeType; -use strum::{EnumCount, FromRepr}; +pub mod states; +pub mod tiles; -#[derive(..Base, Hash, Default, FromRepr)] -#[derive(States, SpacetimeType)] -pub enum GameState { - #[default] - None, - Lobby, - Setup, - Deal, - Play, - Exit, -} - -#[derive(..Base)] -#[derive(Component, SpacetimeType)] -pub struct Tile { - pub suit: Suit, -} - -#[derive(..Base)] -#[derive(SpacetimeType)] -pub enum Suit { - Man(Rank), - Pin(Rank), - Sou(Rank), - Wind(Wind), - Dragon(Dragon), -} - -impl Suit { - pub fn rank(&self) -> Option { - match self { - Suit::Man(rank) => Some(*rank), - Suit::Pin(rank) => Some(*rank), - Suit::Sou(rank) => Some(*rank), - // Suit::Wind(wind) | Suit::Dragon(dragon) => None, - _ => None, - } - } -} - -#[derive( - ..Base, - Deref, - DerefMut, -)] -#[derive(SpacetimeType)] -pub struct Rank { - pub number: u8, -} - -#[derive( - ..Base, - FromRepr, -)] -#[derive(SpacetimeType)] -pub enum Wind { - Ton, - Nan, - Shaa, - Pei, -} - -#[derive( - ..Base, - FromRepr, -)] -#[derive(SpacetimeType)] -pub enum Dragon { - Haku, - Hatsu, - Chun, -} - -pub fn tiles() -> Vec { - let mut tiles = vec![]; - for _ in 0..4 { - for i in 1..=9 { - tiles.push(Tile { - suit: Suit::Pin(Rank { number: i }), - }); - tiles.push(Tile { - suit: Suit::Sou(Rank { number: i }), - }); - tiles.push(Tile { - suit: Suit::Man(Rank { number: i }), - }); - } - for i in 0..4 { - tiles.push(Tile { - suit: Suit::Wind(Wind::from_repr(i).unwrap()), - }); - } - for i in 0..3 { - tiles.push(Tile { - suit: Suit::Dragon(Dragon::from_repr(i).unwrap()), - }); - } - } - tiles -} - -#[derive( - Default, - ..Copy, - PartialEq, - Eq, - Hash, - Debug, -)] -#[derive(SubStates, FromRepr, EnumCount, SpacetimeType)] -#[source(GameState = GameState::Play)] -pub enum TurnState { - #[default] - None, - Tsumo, - Menzen, - RiichiKan, - RonChiiPonKan, - End, -} +pub use states::*; +pub use tiles::*; diff --git a/jong-types/src/states.rs b/jong-types/src/states.rs new file mode 100644 index 0000000..ccf0c5f --- /dev/null +++ b/jong-types/src/states.rs @@ -0,0 +1,37 @@ +use bevy::prelude::*; +use spacetimedb::SpacetimeType; +use strum::{EnumCount, FromRepr}; + +use super::derive; + +#[derive(..Base, Hash, Default, FromRepr)] +#[derive(States, SpacetimeType)] +pub enum GameState { + #[default] + None, + Lobby, + Setup, + Deal, + Play, + Exit, +} + +#[derive( + Default, + ..Copy, + PartialEq, + Eq, + Hash, + Debug, +)] +#[derive(SubStates, FromRepr, EnumCount, SpacetimeType)] +#[source(GameState = GameState::Play)] +pub enum TurnState { + #[default] + None, + Tsumo, + Menzen, + RiichiKan, + RonChiiPonKan, + End, +} diff --git a/jong-types/src/tiles.rs b/jong-types/src/tiles.rs new file mode 100644 index 0000000..c70ee29 --- /dev/null +++ b/jong-types/src/tiles.rs @@ -0,0 +1,94 @@ +use bevy::prelude::*; +use spacetimedb::SpacetimeType; +use strum::{EnumCount, FromRepr}; + +use super::derive; + +#[derive(..Base)] +#[derive(Component, SpacetimeType)] +pub struct Tile { + pub suit: Suit, +} + +#[derive(..Base)] +#[derive(SpacetimeType)] +pub enum Suit { + Man(Rank), + Pin(Rank), + Sou(Rank), + Wind(Wind), + Dragon(Dragon), +} + +impl Suit { + pub fn rank(&self) -> Option { + match self { + Suit::Man(rank) => Some(*rank), + Suit::Pin(rank) => Some(*rank), + Suit::Sou(rank) => Some(*rank), + // Suit::Wind(wind) | Suit::Dragon(dragon) => None, + _ => None, + } + } +} + +#[derive( + ..Base, + Deref, + DerefMut, +)] +#[derive(SpacetimeType)] +pub struct Rank { + pub number: u8, +} + +#[derive( + ..Base, + FromRepr, +)] +#[derive(SpacetimeType)] +pub enum Wind { + Ton, + Nan, + Shaa, + Pei, +} + +#[derive( + ..Base, + FromRepr, +)] +#[derive(SpacetimeType)] +pub enum Dragon { + Haku, + Hatsu, + Chun, +} + +pub fn tiles() -> Vec { + let mut tiles = vec![]; + for _ in 0..4 { + for i in 1..=9 { + tiles.push(Tile { + suit: Suit::Pin(Rank { number: i }), + }); + tiles.push(Tile { + suit: Suit::Sou(Rank { number: i }), + }); + tiles.push(Tile { + suit: Suit::Man(Rank { number: i }), + }); + } + for i in 0..4 { + tiles.push(Tile { + suit: Suit::Wind(Wind::from_repr(i).unwrap()), + }); + } + for i in 0..3 { + tiles.push(Tile { + suit: Suit::Dragon(Dragon::from_repr(i).unwrap()), + }); + } + } + tiles +} diff --git a/jong/src/game/hand.rs b/jong/src/game/hand.rs deleted file mode 100644 index 2387f4a..0000000 --- a/jong/src/game/hand.rs +++ /dev/null @@ -1,41 +0,0 @@ - -use bevy::prelude::*; - -use jong_types::*; - -#[derive(Component)] -pub struct Hand; - -#[derive(Component)] -pub struct Pond; - -#[derive(Component)] -pub struct Drawn; - -#[derive(Component)] -pub struct Discarded; - -// #[derive(Component, Default)] -// enum SortHand { -// #[default] -// Unsorted, -// Sort, -// Manual, -// } - -/// assumes hand is sorted -pub(crate) fn check_wincon(_hand: &[Tile; 14], _melds: &[&[Tile]]) -> bool { - // 4x3 + pair - // assume sorted - // - // let melds = hand.iter().array_chunks::<3>().all(|tiles| { - // let suit = discriminant(&tiles[0].suit); - // let starting_rank = tiles[0].suit - // // tiles.iter().all(|t| discriminant(&t.suit) == suit) && tiles.iter().zip(tiles[0].suit.rank()) - // }) && melds.iter().all(|meld| todo!()); - // let eyeball = todo!(); - - todo!(); - - // melds && eyeball -} diff --git a/jong/src/game/player.rs b/jong/src/game/player.rs deleted file mode 100644 index 32a531f..0000000 --- a/jong/src/game/player.rs +++ /dev/null @@ -1,21 +0,0 @@ -use bevy::prelude::*; - -#[derive(Component, Debug, PartialEq)] -pub struct Player { - pub name: String, -} - -#[derive(Component)] -pub struct Points(pub isize); - -#[derive(Component)] -pub struct MainPlayer; - -#[derive(Component)] -pub struct CurrentPlayer; - -#[derive(Component)] -pub struct Dealer; - -#[derive(Component)] -pub struct Tsumo; diff --git a/jong/src/game/round.rs b/jong/src/game/round.rs deleted file mode 100644 index 031e8ed..0000000 --- a/jong/src/game/round.rs +++ /dev/null @@ -1,232 +0,0 @@ - -use bevy::{platform::collections::HashMap, prelude::*}; -use strum::{EnumCount, FromRepr}; - -use crate::EnumNextCycle; -use jong_types::TurnState; - -// #[derive(Resource)] -// pub struct CurrentPlayer(pub Entity); - -#[derive(Resource)] -pub(crate) struct MatchSettings { - pub(crate) starting_points: isize, - pub(crate) player_count: u8, -} - -#[derive(Component)] -pub(crate) struct Dice(u8, u8); - -#[derive(Resource)] -pub(crate) struct Compass { - pub(crate) prevalent_wind: Wind, - pub(crate) round: u8, - pub(crate) dealer_wind: Wind, - pub(crate) riichi: usize, - pub(crate) honba: usize, -} - -#[derive(Component, Clone, Copy, FromRepr, EnumCount, PartialEq)] -pub enum Wind { - Ton, - Nan, - Shaa, - Pei, -} - -pub enum WindRelation { - Shimocha, - Toimen, - Kamicha, -} - -#[derive(Component, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub(crate) enum CallType { - Skip, - Ron, - Chii, - Pon, - Kan, -} - -impl Default for MatchSettings { - fn default() -> Self { - Self { - starting_points: 25000, - player_count: 4, - } - } -} - -impl Default for Compass { - fn default() -> Self { - Self { - prevalent_wind: Wind::Ton, - round: 1, - dealer_wind: Wind::Ton, - riichi: 0, - honba: 0, - } - } -} - -impl EnumNextCycle for Wind { - fn next(&self) -> Self { - if (*self as usize + 1) >= Self::COUNT { - Self::from_repr(0).unwrap() - } else { - Self::from_repr(*self as usize + 1).unwrap() - } - } -} - -impl Wind { - pub fn relate(&self, other: &Self) -> WindRelation { - if self.next() == *other { - WindRelation::Shimocha - } else if other.next() == *self { - WindRelation::Kamicha - } else { - WindRelation::Toimen - } - } -} - -impl EnumNextCycle for TurnState { - fn next(&self) -> Self { - if (*self as usize + 1) >= Self::COUNT { - Self::from_repr(0).unwrap() - } else { - Self::from_repr(*self as usize + 1).unwrap() - } - } -} - -// pub(crate) fn tsumo( -// mut commands: Commands, - -// // curr_player: Res, -// curr_player: Single>, -// wall: Single>, -// walltiles: Single<&Children, With>, - -// curr_turnstate: Res>, -// mut next_turnstate: ResMut>, -// ) { -// let drawn = walltiles.last().unwrap(); -// commands.entity(*wall).remove_child(*drawn); - -// let drawn = commands.entity(*drawn).insert(Drawn).id(); -// commands.entity(*curr_player).add_child(drawn); - -// debug!("tsumo for: {:?}, tile: {:?}", *curr_player, drawn); -// next_turnstate.set(curr_turnstate.next()); -// } - -// pub(crate) fn menzen( -// curr_turnstate: Res>, -// mut next_turnstate: ResMut>, -// ) { -// trace!("menzen check"); -// next_turnstate.set(curr_turnstate.next()); -// } - -// pub(crate) fn riichi_kan( -// curr_turnstate: Res>, -// mut next_turnstate: ResMut>, -// ) { -// trace!("riichi_kan"); -// next_turnstate.set(curr_turnstate.next()); -// } - -// #[allow(clippy::too_many_arguments, irrefutable_let_patterns)] -// pub(crate) fn discard( -// mut commands: Commands, -// mut reader: MessageReader, - -// curr_player: Single>, -// players: Query<&Children, With>, -// mut hands: Query<(&Children, Entity), (With, Without)>, -// drawn: Single>, - -// curr_turnstate: Res>, -// mut next_turnstate: ResMut>, -// ) -> Result { -// // trace!("discard"); -// let (handtiles, hand) = hands.get_mut(players.get(*curr_player)?.iter().next().unwrap())?; - -// let mut done = false; -// while let Some(message) = reader.read().next() { -// if let GameMessage::Discarded(discarded) = message { -// debug!("discarded: {discarded:?}"); -// if *discarded == *drawn { -// } else if handtiles.contains(discarded) { -// commands -// .entity(hand) -// .remove_child(*discarded) -// .add_child(*drawn); -// } else { -// panic!("current hand nor drawn tile contains discarded tile") -// } -// commands.entity(*drawn).remove::(); -// commands.entity(*discarded).insert(Discarded); - -// done = true; -// break; -// } -// } - -// if done { -// next_turnstate.set(curr_turnstate.next()); -// } -// Ok(()) -// } - -#[derive(Resource)] -pub struct PendingCalls { - eligible: Vec, - calls: HashMap, -} - -// pub(crate) fn notify_callable() {} - -// pub(crate) fn ron_chi_pon_kan( -// mut commands: Commands, -// mut reader: MessageReader, - -// discarded: Single>, -// mut ponds: Query<(&Children, Entity), (With, Without)>, -// calls: Query<&CallType>, - -// curr_turnstate: Res>, -// mut next_turnstate: ResMut>, -// ) { -// // check if can call? -// // message players? -// // collect then prioritize - -// // let mut received = vec![]; -// let mut received: Vec<_> = reader -// .read() -// .filter_map(|m| { -// if let GameMessage::Called { player, calltype } = m -// && let Ok(calltype) = calls.get(*calltype) -// { -// Some((calltype, player)) -// } else { -// None -// } -// }) -// .collect(); -// // received.sort_unstable_by_key(|(c, t)| c); -// // received.sort_unstable_by_key(|m| m.); - -// next_turnstate.set(curr_turnstate.next()); -// } - -// pub(crate) fn end( -// curr_turnstate: Res>, -// mut next_turnstate: ResMut>, -// ) { -// next_turnstate.set(curr_turnstate.next()); -// } diff --git a/jong/src/game/wall.rs b/jong/src/game/wall.rs deleted file mode 100644 index e382cf6..0000000 --- a/jong/src/game/wall.rs +++ /dev/null @@ -1,7 +0,0 @@ -use bevy::prelude::*; - -#[derive(Component)] -pub struct Wall; - -#[derive(Component)] -pub struct Dead; diff --git a/jong/src/gui/mod.rs b/jong/src/gui/mod.rs deleted file mode 100644 index 36ea966..0000000 --- a/jong/src/gui/mod.rs +++ /dev/null @@ -1,29 +0,0 @@ -use bevy::{color::palettes::css::GREEN, prelude::*}; - -pub(crate) fn init_environment(mut commands: Commands) { - commands.spawn(( - DirectionalLight { - shadows_enabled: true, - ..default() - }, - // Transform::from_xyz(), - )); - commands.spawn(( - Camera3d::default(), - Transform::from_xyz(-200.5, 100., 0.).looking_at(Vec3::ZERO, Vec3::Y), - )); -} - -pub(crate) fn init_table( - mut commands: Commands, - mut meshes: ResMut>, - mut materials: ResMut>, -) { - let green: Color = GREEN.into(); - let table = Cuboid::new(1000., 5., 1000.); - - commands.spawn(( - Mesh3d(meshes.add(table)), - MeshMaterial3d(materials.add(green)), - )); -} diff --git a/jong/src/lib.rs b/jong/src/lib.rs index 1d548af..9dcaa70 100644 --- a/jong/src/lib.rs +++ b/jong/src/lib.rs @@ -4,9 +4,7 @@ use bevy::prelude::*; use bevy_spacetimedb::StdbConnection; use spacetimedb_sdk::credentials; -pub mod game; -pub mod tile; -pub mod yakus; +pub mod riichi; trait EnumNextCycle { fn next(&self) -> Self; @@ -15,6 +13,5 @@ trait EnumNextCycle { pub type SpacetimeDB<'a> = Res<'a, StdbConnection>; fn creds_store() -> credentials::File { - credentials::File::new("jongline") + credentials::File::new("jong-line") } - diff --git a/jong/src/main.rs b/jong/src/main.rs index 66cb09b..137cbff 100644 --- a/jong/src/main.rs +++ b/jong/src/main.rs @@ -3,7 +3,7 @@ use clap::{Parser, Subcommand}; use tracing::Level; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; -mod gui; +// mod gui; mod tui; #[derive(Parser)] @@ -25,15 +25,11 @@ fn main() { let mut app = App::new(); let app = match args.mode { - Mode::RunGui => { - app.add_plugins(DefaultPlugins.set(LogPlugin { - filter: FILTERSTRING.into(), - level: Level::TRACE, - // custom_layer: todo!(), - // fmt_layer: todo!(), - ..Default::default() - })) - } + Mode::RunGui => app.add_plugins(DefaultPlugins.set(LogPlugin { + filter: FILTERSTRING.into(), + level: Level::TRACE, + ..Default::default() + })), Mode::RunTui => { tracing_subscriber::registry() .with(tui_logger::TuiTracingSubscriberLayer) @@ -45,7 +41,7 @@ fn main() { } }; - app.add_plugins(jong::game::Riichi); + app.add_plugins(jong::riichi::Riichi); app.run(); } diff --git a/jong/src/game.rs b/jong/src/riichi.rs similarity index 72% rename from jong/src/game.rs rename to jong/src/riichi.rs index 344d5f3..cde1938 100644 --- a/jong/src/game.rs +++ b/jong/src/riichi.rs @@ -2,27 +2,22 @@ use bevy::prelude::*; use bevy_spacetimedb::{ ReadInsertUpdateMessage, ReadStdbConnectedMessage, ReadStdbDisconnectedMessage, StdbPlugin, }; -use spacetimedb_sdk::{DbContext, Table}; -use crate::{ - SpacetimeDB, creds_store, - game::hand::{Drawn, Hand, Pond}, -}; use jong_db::{self, DbConnection, LobbyTableAccess, PlayerTableAccess, RemoteTables}; use jong_db::{add_bot, draw_tile, set_ready, shuffle_deal, skip_call, start_game}; use jong_types::*; -pub mod hand; pub mod player; -pub mod round; -pub mod wall; +use crate::riichi::player::*; +use crate::{SpacetimeDB, creds_store}; +// pub mod round; pub struct Riichi; impl Plugin for Riichi { fn build(&self, app: &mut App) { let plugins = StdbPlugin::default() .with_uri("http://localhost:3000") - .with_module_name("jongline") + .with_module_name("jong-line") .with_run_fn(DbConnection::run_threaded) // TODO why don't I need to call add_reducer? @@ -41,8 +36,8 @@ impl Plugin for Riichi { }; app.add_plugins(plugins) - .init_state::() - .add_sub_state::() + .init_state::() + .add_sub_state::() // .init_resource::() // .init_resource::() // .add_systems(Startup, tile::init_tiles) @@ -70,6 +65,7 @@ fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage, _comman for msg in messages.read() { 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()); @@ -91,6 +87,7 @@ fn subscriptions(stdb: SpacetimeDB) { .on_applied(|_| trace!("made all subs!")) .on_error(|_, err| error!("sub failed: {err}")) .subscribe([ + // TODO until views work format!( "SELECT * FROM player p WHERE p.identity = '{}'", stdb.identity() @@ -100,61 +97,36 @@ fn subscriptions(stdb: SpacetimeDB) { // .subscribe_to_all_tables(); } -#[derive(Component)] -pub struct TileId(pub u32); - fn on_player_insert_update( - _stdb: SpacetimeDB, mut messages: ReadInsertUpdateMessage, - mut commands: Commands, - tiles: Query<(&Tile, &TileId, Entity)>, - player: Option>, - hand_ent: Option>>, + player: Option>>, + hand: Option>>, ) { - use player::*; + let hand = if player.is_none() && hand.is_none() { + let hand = commands.spawn(Hand).id(); + commands.spawn((Player, MainPlayer)).add_child(hand); + hand + } else { + *hand.unwrap() + }; for msg in messages.read() { - // debug!("player_insert_update msg:\n{:#?}", msg.new); - if let (Some(_player), Some(hand_ent)) = (player.as_ref(), hand_ent.as_ref()) { - // if msg.old.as_ref().is_some_and(|m| !m.ready) && msg.new.ready { - // trace!("entered ready"); - // // TODO add a start game button in the future - // stdb.reducers().start_game().unwrap(); - // } - let tiles: Vec<_> = msg - .new - .hand - .iter() - .map(|dbt| { - // TODO this seems a lil expensive - if let Some(ent) = tiles - .iter() - .find(|(_, id, _)| id.0 == dbt.id) - .map(|(_, _, e)| e) - { - ent - } else { - commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id() - } - }) - .collect(); - commands.entity(**hand_ent).replace_children(&tiles); - if let Some(dbt) = &msg.new.drawn_tile { - commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id), Drawn)); - } - } else { - let player = Player { - name: msg - .new - .name - .as_ref() - .unwrap_or(&"nameless".to_string()) - .clone(), - }; - let bundle = (player, Hand, Pond, MainPlayer, CurrentPlayer); - commands.spawn(bundle); + let tiles: Vec<_> = msg + .new + .hand + .iter() + .map(|dbt| { + // drawn tiles will always be new entities to us, until wall isn't fake + commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id))).id() + }) + .collect(); + + commands.entity(hand).replace_children(&tiles); + + if let Some(dbt) = &msg.new.drawn_tile { + commands.spawn((Tile::from(&dbt.tile), TileId(dbt.id), Drawn)); } } } @@ -163,9 +135,9 @@ fn on_lobby_insert_update( stdb: SpacetimeDB, mut messages: ReadInsertUpdateMessage, - _commands: Commands, - mut next_gamestate: ResMut>, - mut next_turnstate: ResMut>, + commands: Commands, + mut next_gamestate: ResMut>, + mut next_turnstate: ResMut>, ) { for msg in messages.read() { // trace!("on_lobby_insert_update msg:\n{:#?}", msg.new); @@ -212,7 +184,6 @@ fn on_lobby_insert_update( stdb.reducers().skip_call().unwrap(); } jong_db::TurnState::End => todo!(), - // _ => todo!(), } next_turnstate.set(msg.new.turn_state.into()); } diff --git a/jong/src/riichi/player.rs b/jong/src/riichi/player.rs new file mode 100644 index 0000000..da22ed3 --- /dev/null +++ b/jong/src/riichi/player.rs @@ -0,0 +1,25 @@ +use bevy::prelude::*; + +#[derive(Component)] +pub struct Player; + +#[derive(Component)] +pub struct MainPlayer; + +#[derive(Component)] +pub struct CurrentPlayer; + +#[derive(Component)] +pub struct TileId(pub u32); + +#[derive(Component)] +pub struct Hand; + +#[derive(Component)] +pub struct Pond; + +#[derive(Component)] +pub struct Drawn; + +#[derive(Component)] +pub struct Discarded; diff --git a/jong/src/riichi/round.rs b/jong/src/riichi/round.rs new file mode 100644 index 0000000..a538679 --- /dev/null +++ b/jong/src/riichi/round.rs @@ -0,0 +1,100 @@ +use bevy::{platform::collections::HashMap, prelude::*}; +use strum::{EnumCount, FromRepr}; + +use crate::EnumNextCycle; +use jong_types::states::TurnState; + +// #[derive(Resource)] +// pub struct CurrentPlayer(pub Entity); + +#[derive(Resource)] +pub(crate) struct MatchSettings { + pub(crate) starting_points: isize, + pub(crate) player_count: u8, +} + +#[derive(Component)] +pub(crate) struct Dice(u8, u8); + +#[derive(Resource)] +pub(crate) struct Compass { + pub(crate) prevalent_wind: Wind, + pub(crate) round: u8, + pub(crate) dealer_wind: Wind, + pub(crate) riichi: usize, + pub(crate) honba: usize, +} + +pub enum WindRelation { + Shimocha, + Toimen, + Kamicha, +} + +#[derive(Component, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub(crate) enum CallType { + Skip, + Ron, + Chii, + Pon, + Kan, +} + +impl Default for MatchSettings { + fn default() -> Self { + Self { + starting_points: 25000, + player_count: 4, + } + } +} + +impl Default for Compass { + fn default() -> Self { + Self { + prevalent_wind: Wind::Ton, + round: 1, + dealer_wind: Wind::Ton, + riichi: 0, + honba: 0, + } + } +} + +impl EnumNextCycle for Wind { + fn next(&self) -> Self { + if (*self as usize + 1) >= Self::COUNT { + Self::from_repr(0).unwrap() + } else { + Self::from_repr(*self as usize + 1).unwrap() + } + } +} + +impl Wind { + pub fn relate(&self, other: &Self) -> WindRelation { + if self.next() == *other { + WindRelation::Shimocha + } else if other.next() == *self { + WindRelation::Kamicha + } else { + WindRelation::Toimen + } + } +} + +impl EnumNextCycle for TurnState { + fn next(&self) -> Self { + if (*self as usize + 1) >= Self::COUNT { + Self::from_repr(0).unwrap() + } else { + Self::from_repr(*self as usize + 1).unwrap() + } + } +} + +#[derive(Resource)] +pub struct PendingCalls { + eligible: Vec, + calls: HashMap, +} diff --git a/jong/src/tile.rs b/jong/src/tile.rs deleted file mode 100644 index 3c4267c..0000000 --- a/jong/src/tile.rs +++ /dev/null @@ -1,11 +0,0 @@ -use bevy::prelude::*; - -use jong_types::*; - -#[derive(Component)] -pub struct Dora; - -pub fn init_tiles(mut commands: Commands) { - let tiles = tiles(); - commands.spawn_batch(tiles); -} diff --git a/jong/src/tui.rs b/jong/src/tui.rs index f58fb51..7c619e7 100644 --- a/jong/src/tui.rs +++ b/jong/src/tui.rs @@ -4,35 +4,17 @@ use std::time::Duration; use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin}; use bevy_ratatui::RatatuiPlugins; -use jong::game::TileId; -use jong::game::player::MainPlayer; use tui_logger::TuiWidgetState; -use crate::tui::{input::ConfirmSelect, states::ConsoleWidget}; -use jong::{ - SpacetimeDB, - game::{ - hand::{Drawn, Hand}, - player::{CurrentPlayer, Player}, - }, -}; +use jong::{SpacetimeDB, riichi::player::*}; use jong_db::{self, discard_tile as _}; -use jong_types::{GameState, TurnState}; +use jong_types::states::{GameState, TurnState}; mod input; mod layout; mod render; - -#[derive(Default)] -pub struct TuiPlugin; - -#[derive(Clone, Debug, Eq, Hash, PartialEq, SystemSet)] -pub enum TuiSet { - Input, - Layout, - Render, -} - +use input::ConfirmSelect; +use states::ConsoleWidget; mod states { use bevy::prelude::*; use tui_logger::TuiWidgetState; @@ -59,6 +41,16 @@ mod states { // } } +#[derive(Default)] +pub struct TuiPlugin; + +#[derive(Clone, Debug, Eq, Hash, PartialEq, SystemSet)] +pub enum TuiSet { + Input, + Layout, + Render, +} + impl Plugin for TuiPlugin { fn build(&self, app: &mut App) { app.add_plugins(( @@ -93,7 +85,7 @@ impl Plugin for TuiPlugin { .add_systems( Update, ( - render::render_hands.run_if(in_state(GameState::Play)), + render::render_hand.run_if(in_state(GameState::Play)), render::render, ) .chain() diff --git a/jong/src/tui/input/keyboard.rs b/jong/src/tui/input/keyboard.rs index 3e75e64..be09002 100644 --- a/jong/src/tui/input/keyboard.rs +++ b/jong/src/tui/input/keyboard.rs @@ -7,7 +7,6 @@ use jong_db::start_game; use tui_logger::TuiWidgetEvent; use jong::SpacetimeDB; -use jong_types::GameState; use crate::tui::layout::Overlays; use crate::tui::states::ConsoleWidget; @@ -21,9 +20,9 @@ pub(crate) fn keyboard( mut consolewidget: ResMut, mut exit: MessageWriter, - curr_gamestate: Res>, + curr_gamestate: Res>, curr_tuistate: Res>, - mut next_gamestate: ResMut>, + mut next_gamestate: ResMut>, mut next_tuistate: ResMut>, ) { 'message: for message in messages.read() { diff --git a/jong/src/tui/render.rs b/jong/src/tui/render.rs index 5fe828b..ff96ac2 100644 --- a/jong/src/tui/render.rs +++ b/jong/src/tui/render.rs @@ -6,9 +6,9 @@ use ratatui::layout::{Constraint, Flex, Layout, Offset, Rect, Size}; use ratatui::style::{Modifier, Stylize}; use ratatui::widgets::{Block, Borders, Clear, Paragraph}; -use jong::game::hand::{Drawn, Hand}; -use jong::game::player::{CurrentPlayer, MainPlayer, Player}; -use jong::game::round::Wind; +use jong::riichi::player::{CurrentPlayer, MainPlayer, Player}; +use jong::riichi::player::{Drawn, Hand}; +// use jong::riichi::round::Wind; // use jong_types::*; use crate::tui::input::Hovered; @@ -95,26 +95,9 @@ pub(crate) fn render( Ok(()) } -// pub(crate) fn render_arg_check( -// mut commands: Commands, -// mut tui: ResMut, - -// hovered: Query>, -// layouts: Res, - -// tiles: Query<&jong_types::Tile>, -// // main_player: Single<(&Player, Entity, &Wind), With>, -// curr_player: Single>, -// players: Query<(&Player, Entity, &Children)>, -// hands: Query<(&Children, Entity), (With, Without)>, -// // drawn_tile: Single>, -// ) { -// // trace!("arg!"); -// } - // FIXME we don't care about other players atm #[allow(clippy::too_many_arguments, clippy::type_complexity)] -pub(crate) fn render_hands( +pub(crate) fn render_hand( mut commands: Commands, mut tui: ResMut, @@ -123,79 +106,66 @@ pub(crate) fn render_hands( tiles: Query<&jong_types::Tile>, main_player: Single<(&Player, Entity /* , &Wind */), With>, - curr_player: Single>, - players: Query<(&Player, Entity, &Children)>, - hands: Query<(&Children, Entity), With>, - drawn_tile: Single>, + hand: Single<(&Children, Entity), With>, + drawn_tile: Option>>, ) -> Result { 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 hand: Vec<_> = hand - .iter() - .map(|entity| -> Result<_> { - let tile = tiles.get(entity).unwrap_or_else(|_| panic!("{entity:?}")); - let hovered = hovered.contains(entity); - let widget = render_tile(tile, hovered); + let hand: Vec<_> = hand + .0 + .iter() + .map(|entity| -> Result<_> { + let tile = tiles.get(entity).unwrap_or_else(|_| panic!("{entity:?}")); + let hovered = hovered.contains(entity); + let widget = render_tile(tile, hovered); - Ok((entity, widget, hovered)) - }) - .collect::>()?; + Ok((entity, widget, hovered)) + }) + .collect::>()?; - 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); + let (player, player_ent) = *main_player; + // split main box into thirds + let mut this_hand = layouts.this_hand; + let tile_drawn = if drawn_tile.is_some() { 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 }); - } - frame.render_widget(widget, 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); + } - // tsumo tile - // if this_drawer { - // // trace!("this_drawer"); + // tsumo tile + if let Some(drawn_tile) = drawn_tile { let mut area = drawn_area.resize(Size { width: 5, height: 4, @@ -214,16 +184,16 @@ pub(crate) fn render_hands( 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!(), - // } - // } } + // 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(()) } diff --git a/jong/src/yakus.rs b/jong/src/yakus.rs deleted file mode 100644 index 5a84fab..0000000 --- a/jong/src/yakus.rs +++ /dev/null @@ -1 +0,0 @@ -// const TSUMO; diff --git a/justfile b/justfile index 1e14034..6b3823b 100644 --- a/justfile +++ b/justfile @@ -8,7 +8,7 @@ default: just --list run-tui: - spacetime call jong-line "clear_all" + spacetime call jong-line clear_all cargo run -- run-tui update: @@ -19,7 +19,7 @@ spacetime: devenv up spacetime_dev: - spacetime dev --module-bindings-path jong-db/src/db jong-line --delete-data=always + spacetime dev --module-project-path jong-line --module-bindings-path jong-db/src/db jong-line --delete-data=always spacetime_generate-bindings: spacetime generate --lang rust --out-dir jong-db/src/db --project-path jong-line