jong/jong-line/src/tables.rs

177 lines
3.8 KiB
Rust
Raw Normal View History

2026-02-22 00:39:51 -08:00
use spacetimedb::{SpacetimeType, ViewContext, table, view};
use jong_types::{
2026-02-24 00:56:34 -08:00
PlayerOrBot,
states::{GameState, TurnState},
2026-02-20 03:20:29 -08:00
tiles::Tile,
};
2026-02-20 15:36:04 -08:00
use crate::reducers::advance_game;
#[derive(Debug, Clone)]
#[table(name = lobby, public)]
pub struct Lobby {
#[primary_key]
#[auto_inc]
pub id: u32,
pub players: Vec<PlayerOrBot>,
2026-02-13 08:16:41 -08:00
pub dealer_idx: u8,
pub current_idx: u8,
pub game_state: GameState,
2026-02-24 00:56:34 -08:00
// pub open_hands: bool,
}
#[table(name = wall)]
2026-02-12 17:06:28 -08:00
pub struct DbWall {
#[primary_key]
pub lobby_id: u32,
2026-02-12 17:06:28 -08:00
pub tiles: Vec<DbTile>,
}
#[table(name = tile)]
2026-02-13 07:49:09 -08:00
#[derive(Debug, Clone, Copy)]
2026-02-12 17:06:28 -08:00
pub struct DbTile {
#[primary_key]
#[auto_inc]
pub id: u32,
pub tile: Tile,
}
2026-02-20 03:20:29 -08:00
#[table(name = player, public)]
2026-02-20 15:36:04 -08:00
#[table(name = logged_out_player)]
2026-02-20 03:20:29 -08:00
#[derive(Debug)]
pub struct Player {
#[unique]
#[auto_inc]
pub id: u32,
2026-02-20 15:36:04 -08:00
#[primary_key]
pub identity: spacetimedb::Identity,
2026-02-20 03:20:29 -08:00
pub name: Option<String>,
#[index(btree)]
pub lobby_id: u32,
pub ready: bool,
pub sort: bool,
2026-02-20 15:36:04 -08:00
}
#[table(name = player_clock, public)]
pub struct PlayerClock {
#[primary_key]
pub id: u32,
#[unique]
pub player_id: u32,
pub renewable: u16,
pub total: u16,
}
#[table(name = player_hand)]
pub struct PlayerHand {
#[primary_key]
#[auto_inc]
pub id: u32,
#[unique]
pub player_id: u32,
pub turn_state: TurnState,
2026-02-20 03:20:29 -08:00
pub pond: Vec<DbTile>,
2026-02-20 15:36:04 -08:00
pub hand: Vec<DbTile>,
2026-02-20 03:20:29 -08:00
2026-02-20 15:36:04 -08:00
/// drawn or callable tile
pub working_tile: Option<DbTile>,
2026-02-20 03:20:29 -08:00
}
2026-02-22 00:39:51 -08:00
#[table(name = bot, public)]
2026-02-20 03:20:29 -08:00
pub struct Bot {
#[primary_key]
#[auto_inc]
pub id: u32,
#[index(btree)]
pub lobby_id: u32,
2026-02-20 15:36:04 -08:00
pub turn_state: TurnState,
2026-02-20 03:20:29 -08:00
pub hand: Vec<DbTile>,
pub pond: Vec<DbTile>,
2026-02-20 15:36:04 -08:00
pub working_tile: Option<DbTile>,
}
#[table(name = game_timer, scheduled(advance_game))]
pub struct GameTimer {
#[primary_key]
#[auto_inc]
pub id: u64,
#[unique]
pub lobby_id: u32,
pub scheduled_at: spacetimedb::ScheduleAt,
2026-02-20 03:20:29 -08:00
}
2026-02-22 00:39:51 -08:00
#[view(name = view_hand, public)]
fn view_hand(ctx: &ViewContext) -> Option<PlayerHand> {
ctx.db
.player()
.identity()
.find(ctx.sender)
.and_then(|p| ctx.db.player_hand().player_id().find(p.id))
}
2026-02-24 00:56:34 -08:00
#[derive(SpacetimeType, Clone, Copy)]
pub struct HandView {
pub player: PlayerOrBot,
pub hand_length: u8,
// pub melds: u8,
pub drawn: bool,
}
#[view(name = view_closed_hands, public)]
fn view_closed_hands(ctx: &ViewContext) -> Vec<HandView> {
let this_player = ctx.db.player().identity().find(ctx.sender).unwrap();
if let Some(lobby) = ctx.db.lobby().id().find(this_player.lobby_id) {
lobby
.players
.iter()
.filter_map(|&player| match player {
2026-02-24 00:56:34 -08:00
PlayerOrBot::Player { id } => {
if let Some(player_hand) = ctx.db.player_hand().player_id().find(id) {
Some(HandView {
player,
hand_length: player_hand.hand.len() as u8,
drawn: player_hand.turn_state == TurnState::Tsumo
&& player_hand.working_tile.is_some(),
})
} else {
None
}
2026-02-24 00:56:34 -08:00
}
PlayerOrBot::Bot { id } => {
if let Some(bot) = ctx.db.bot().id().find(id) {
Some(HandView {
player,
hand_length: bot.hand.len() as u8,
drawn: bot.turn_state == TurnState::Tsumo && bot.working_tile.is_some(),
})
} else {
None
}
2026-02-24 00:56:34 -08:00
}
})
.collect()
} else {
vec![]
}
2026-02-24 00:56:34 -08:00
}