hack for player-lobby and Res<Player> race?
This commit is contained in:
parent
9f6a5b6423
commit
c13400165b
34 changed files with 519 additions and 1330 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -10,3 +10,5 @@ devenv.local.yaml
|
||||||
|
|
||||||
# pre-commit
|
# pre-commit
|
||||||
.pre-commit-config.yaml
|
.pre-commit-config.yaml
|
||||||
|
|
||||||
|
mprocs.log
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
"devenv": {
|
"devenv": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"dir": "src/modules",
|
"dir": "src/modules",
|
||||||
"lastModified": 1770399425,
|
"lastModified": 1770666213,
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "devenv",
|
"repo": "devenv",
|
||||||
"rev": "0f006b2e9f591cc44cf219048b5e33793530403b",
|
"rev": "d4ffee46c9088df6e000470b998a2d2c16517f62",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -125,10 +125,10 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1770520253,
|
"lastModified": 1770606655,
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "ebb8a141f60bb0ec33836333e0ca7928a072217f",
|
"rev": "11a396520bf911e4ed01e78e11633d3fc63b350e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
23
devenv.nix
23
devenv.nix
|
|
@ -1,17 +1,29 @@
|
||||||
{
|
{
|
||||||
pkgs,
|
pkgs,
|
||||||
lib,
|
lib,
|
||||||
config,
|
|
||||||
inputs,
|
|
||||||
...
|
...
|
||||||
}: rec {
|
}: rec {
|
||||||
|
# https://devenv.sh/processes/
|
||||||
|
processes.spacetimedb_start.exec = "spacetime start";
|
||||||
|
processes.spacetimedb_generate_bindings = {
|
||||||
|
exec = "spacetime dev --module-bindings-path jong/src/stdb jongline --delete-data=always";
|
||||||
|
# notify.enable = true;
|
||||||
|
# TODO features not yet supp???
|
||||||
|
# restart = "always";
|
||||||
|
# watch = {
|
||||||
|
# paths = [./jong];
|
||||||
|
# };
|
||||||
|
};
|
||||||
|
|
||||||
# https://devenv.sh/packages/
|
# https://devenv.sh/packages/
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
|
# process-compose
|
||||||
pkg-config
|
pkg-config
|
||||||
|
|
||||||
# spacetimedb
|
# spacetimedb
|
||||||
openssl
|
openssl
|
||||||
binaryen
|
binaryen
|
||||||
|
spacetimedb
|
||||||
|
|
||||||
# bevy Linux
|
# bevy Linux
|
||||||
# Audio (Linux only)
|
# Audio (Linux only)
|
||||||
|
|
@ -41,10 +53,9 @@
|
||||||
components = ["rust-src" "rust-docs" "rustc-codegen-cranelift" "rust-analyzer" "rustfmt"];
|
components = ["rust-src" "rust-docs" "rustc-codegen-cranelift" "rust-analyzer" "rustfmt"];
|
||||||
};
|
};
|
||||||
|
|
||||||
# https://devenv.sh/processes/
|
process.manager.implementation = "mprocs";
|
||||||
processes.spacetimedb_start.exec = "spacetime start";
|
process.managers.mprocs.settings = {
|
||||||
processes.spacetimedb_generate_bindings = {
|
server = "127.0.0.1:4050";
|
||||||
exec = "spacetime dev --module-bindings-path jong/src/stdb jongline --delete-data=always";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# https://devenv.sh/services/
|
# https://devenv.sh/services/
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
allowUnfree: true
|
||||||
inputs:
|
inputs:
|
||||||
nixpkgs:
|
nixpkgs:
|
||||||
url: github:cachix/devenv-nixpkgs/rolling
|
url: github:cachix/devenv-nixpkgs/rolling
|
||||||
|
|
|
||||||
125
jong/src/game.rs
125
jong/src/game.rs
|
|
@ -6,13 +6,14 @@ use bevy_spacetimedb::{
|
||||||
TableMessages,
|
TableMessages,
|
||||||
};
|
};
|
||||||
use spacetimedb::Identity;
|
use spacetimedb::Identity;
|
||||||
use spacetimedb_sdk::{DbContext, credentials};
|
use spacetimedb_sdk::{DbContext, Table, credentials};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
SpacetimeDB, creds_store,
|
SpacetimeDB, creds_store, game,
|
||||||
stdb::{
|
stdb::{
|
||||||
self, DbConnection, HandTableAccess, LobbyTableAccess, PlayerTableAccess, RemoteTables,
|
self, DbConnection, HandTableAccess, LobbyTableAccess, PlayerTableAccess, RemoteTables,
|
||||||
add_bot, join_or_create_lobby, login_or_add_player, setup_game,
|
ViewPlayerHandTableAccess, add_bot, join_or_create_lobby, login_or_add_player,
|
||||||
|
shuffle_deal,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -24,7 +25,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
tile::{self},
|
tile::{self},
|
||||||
};
|
};
|
||||||
use jong_types::GameState;
|
use jong_types::*;
|
||||||
|
|
||||||
pub mod hand;
|
pub mod hand;
|
||||||
pub mod player;
|
pub mod player;
|
||||||
|
|
@ -68,8 +69,6 @@ impl Plugin for Riichi {
|
||||||
// .init_resource::<round::Compass>()
|
// .init_resource::<round::Compass>()
|
||||||
.add_message::<GameMessage>()
|
.add_message::<GameMessage>()
|
||||||
.add_systems(Startup, tile::init_tiles)
|
.add_systems(Startup, tile::init_tiles)
|
||||||
// .add_systems(OnEnter(GameState::Setup), setup)
|
|
||||||
// .add_systems(OnEnter(GameState::Deal), hand::shuffle_deal)
|
|
||||||
// .add_systems(Update, hand::sort_hands.run_if(in_state(GameState::Play)))
|
// .add_systems(Update, hand::sort_hands.run_if(in_state(GameState::Play)))
|
||||||
// .add_systems(OnEnter(TurnState::Tsumo), round::tsumo)
|
// .add_systems(OnEnter(TurnState::Tsumo), round::tsumo)
|
||||||
// .add_systems(OnEnter(TurnState::Menzen), round::menzen)
|
// .add_systems(OnEnter(TurnState::Menzen), round::menzen)
|
||||||
|
|
@ -82,19 +81,36 @@ impl Plugin for Riichi {
|
||||||
.add_systems(Startup, sub_to_all)
|
.add_systems(Startup, sub_to_all)
|
||||||
.add_systems(Update, on_connect)
|
.add_systems(Update, on_connect)
|
||||||
.add_systems(Update, on_disconnect)
|
.add_systems(Update, on_disconnect)
|
||||||
.add_systems(Update, (on_player_insert_update, on_lobby_insert_update).chain())
|
.add_systems(Update, on_player_insert_update)
|
||||||
|
.add_systems(Update, on_lobby_insert_update)
|
||||||
.add_systems(OnEnter(GameState::Setup), join_or_create_lobby)
|
.add_systems(OnEnter(GameState::Setup), join_or_create_lobby)
|
||||||
|
.add_systems(Update, view_hand.run_if(in_state(GameState::Play)))
|
||||||
// .add_systems(Update, (view_hand).run_if(in_state(GameState::Play)))
|
// .add_systems(Update, (view_hand).run_if(in_state(GameState::Play)))
|
||||||
// semicolon stopper
|
// semicolon stopper
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn view_hand(stdb: SpacetimeDB, mut commands: Commands) {
|
||||||
|
if let Some(hand) = stdb.db().view_player_hand().iter().next() {}
|
||||||
|
}
|
||||||
|
|
||||||
fn sub_to_all(stdb: SpacetimeDB) {
|
fn sub_to_all(stdb: SpacetimeDB) {
|
||||||
stdb.subscription_builder()
|
stdb.subscription_builder()
|
||||||
.on_applied(|_| trace!("made all subs!"))
|
.on_applied(|_| trace!("made all subs!"))
|
||||||
.on_error(|_, err| error!("sub failed: {err}"))
|
.on_error(|_, err| error!("sub failed: {err}"))
|
||||||
.subscribe_to_all_tables();
|
.subscribe([
|
||||||
|
format!(
|
||||||
|
"SELECT * FROM player p WHERE p.identity = '{}'",
|
||||||
|
stdb.identity()
|
||||||
|
),
|
||||||
|
"SELECT l.* FROM lobby l JOIN player p ON l.host_player_id = p.id".into(),
|
||||||
|
format!(
|
||||||
|
"SELECT * FROM view_player_hand vph WHERE vph.identity = {}",
|
||||||
|
stdb.identity()
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
// .subscribe_to_all_tables();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage, mut commands: Commands) {
|
fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage, mut commands: Commands) {
|
||||||
|
|
@ -124,21 +140,8 @@ fn on_player_insert_update(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
) {
|
) {
|
||||||
for msg in messages.read() {
|
for msg in messages.read() {
|
||||||
debug!(
|
debug!("player_insert_update msg:\n{:#?}", msg.new);
|
||||||
"player_insert_update msg:\n{:#?} -> \n{:#?}",
|
commands.insert_resource(Player(msg.new.clone()));
|
||||||
msg.old, msg.new
|
|
||||||
);
|
|
||||||
|
|
||||||
if msg.new.identity == stdb.identity() {
|
|
||||||
commands.insert_resource(Player(msg.new.clone()));
|
|
||||||
// TODO add bots elsewhere
|
|
||||||
if msg.new.lobby_id != 0 {
|
|
||||||
info!("joined lobby {}", msg.new.lobby_id);
|
|
||||||
for _ in 0..3 {
|
|
||||||
stdb.reducers().add_bot(msg.new.lobby_id).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,52 +155,60 @@ fn join_or_create_lobby(stdb: SpacetimeDB, player: Res<Player>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<stdb::GameState> for GameState {
|
|
||||||
fn from(value: stdb::GameState) -> Self {
|
|
||||||
match value {
|
|
||||||
stdb::GameState::None => Self::None,
|
|
||||||
stdb::GameState::Setup => Self::Setup,
|
|
||||||
stdb::GameState::Deal => Self::Deal,
|
|
||||||
stdb::GameState::Play => Self::Play,
|
|
||||||
stdb::GameState::Exit => Self::Exit,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_lobby_insert_update(
|
fn on_lobby_insert_update(
|
||||||
stdb: SpacetimeDB,
|
stdb: SpacetimeDB,
|
||||||
mut messages: ReadInsertUpdateMessage<stdb::Lobby>,
|
mut messages: ReadInsertUpdateMessage<stdb::Lobby>,
|
||||||
|
|
||||||
player: Option<Res<Player>>,
|
|
||||||
|
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut next_gamestate: ResMut<NextState<GameState>>,
|
mut next_gamestate: ResMut<NextState<GameState>>,
|
||||||
) {
|
) {
|
||||||
for msg in messages.read() {
|
for msg in messages.read() {
|
||||||
if let Some(player) = player.as_ref()
|
trace!("on_lobby_insert_update msg:\n{:#?}", msg.new);
|
||||||
&& player.lobby_id == msg.new.id
|
|
||||||
{
|
|
||||||
debug!("on_lobby_insert_update: {:#?}", msg.new);
|
|
||||||
next_gamestate.set(msg.new.game_state.into());
|
|
||||||
|
|
||||||
match msg.new.game_state {
|
next_gamestate.set(msg.new.game_state.into());
|
||||||
stdb::GameState::None => {
|
match msg.new.game_state {
|
||||||
trace!("setup game");
|
stdb::GameState::None => {
|
||||||
stdb.reducers().setup_game(player.lobby_id).unwrap();
|
trace!("game entered none");
|
||||||
|
}
|
||||||
|
stdb::GameState::Setup => {
|
||||||
|
trace!("game entered setup");
|
||||||
|
|
||||||
|
let player = stdb
|
||||||
|
.db()
|
||||||
|
.player()
|
||||||
|
.identity()
|
||||||
|
.find(&stdb.identity())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if player.lobby_id == msg.new.id {
|
||||||
|
stdb.reducers().shuffle_deal(player.lobby_id).unwrap();
|
||||||
|
for _ in 0..3 {
|
||||||
|
stdb.reducers().add_bot(player.lobby_id).unwrap();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error!("no player but game in setup")
|
||||||
}
|
}
|
||||||
stdb::GameState::Setup => {
|
}
|
||||||
trace!("game entered setup");
|
stdb::GameState::Deal => {
|
||||||
}
|
trace!("game entered deal");
|
||||||
stdb::GameState::Deal => {
|
}
|
||||||
trace!("game entered deal")
|
stdb::GameState::Play => {
|
||||||
}
|
trace!("game entered play");
|
||||||
stdb::GameState::Play => {
|
if let Some(hand) = stdb.db().view_player_hand().iter().next() {
|
||||||
trace!("game entered play")
|
let tiles = hand
|
||||||
}
|
.tiles
|
||||||
stdb::GameState::Exit => {
|
.iter()
|
||||||
trace!("game enetered exit")
|
.map(Into::into)
|
||||||
|
.map(|t: Tile| commands.spawn(t).id())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
commands.spawn(Hand).add_children(&tiles);
|
||||||
|
} else {
|
||||||
|
error!("entered play without a hand")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stdb::GameState::Exit => {
|
||||||
|
trace!("game enetered exit");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,45 +25,6 @@ pub struct Discarded;
|
||||||
// Manual,
|
// Manual,
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub(crate) fn sort_hands(
|
|
||||||
tiles: Query<&Tile>,
|
|
||||||
hands: Query<&mut Children, (Changed<Children>, With<Hand>, Without<Player>)>,
|
|
||||||
) -> Result {
|
|
||||||
for mut hand in hands {
|
|
||||||
hand.sort_unstable_by_key(|e| tiles.get(*e).unwrap().suit);
|
|
||||||
debug!("sorted: {hand:?}");
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn shuffle_deal(
|
|
||||||
mut commands: Commands,
|
|
||||||
tiles: Populated<Entity, With<Tile>>,
|
|
||||||
players: Populated<Entity, With<Player>>,
|
|
||||||
wall_ent: Single<Entity, With<Wall>>,
|
|
||||||
mut next_gamestate: ResMut<NextState<GameState>>,
|
|
||||||
) {
|
|
||||||
use rand::seq::SliceRandom;
|
|
||||||
|
|
||||||
let mut rng = rand::rng();
|
|
||||||
let mut walltiles: Vec<_> = tiles.iter().collect();
|
|
||||||
walltiles.shuffle(&mut rng);
|
|
||||||
|
|
||||||
for player_ent in players {
|
|
||||||
let handtiles = walltiles.split_off(walltiles.len() - 13);
|
|
||||||
let hand_ent = commands.spawn(Hand).add_children(&handtiles).id();
|
|
||||||
commands.entity(player_ent).add_child(hand_ent);
|
|
||||||
debug!("deal to player_ent {player_ent:?} {hand_ent:?}");
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't need to remove hands from wall if we don't insert to wall to begin with
|
|
||||||
// TODO probably do this later on when animating the draw
|
|
||||||
debug!("shuffled: {walltiles:?}");
|
|
||||||
commands.entity(*wall_ent).replace_children(&walltiles);
|
|
||||||
|
|
||||||
next_gamestate.set(GameState::Play);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// assumes hand is sorted
|
/// assumes hand is sorted
|
||||||
pub(crate) fn check_wincon(hand: &[Tile; 14], melds: &[&[Tile]]) -> bool {
|
pub(crate) fn check_wincon(hand: &[Tile; 14], melds: &[&[Tile]]) -> bool {
|
||||||
// 4x3 + pair
|
// 4x3 + pair
|
||||||
|
|
|
||||||
|
|
@ -19,3 +19,55 @@ pub type SpacetimeDB<'a> = Res<'a, StdbConnection<stdb::DbConnection>>;
|
||||||
fn creds_store() -> credentials::File {
|
fn creds_store() -> credentials::File {
|
||||||
credentials::File::new("jongline")
|
credentials::File::new("jongline")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<stdb::GameState> for jong_types::GameState {
|
||||||
|
fn from(value: stdb::GameState) -> Self {
|
||||||
|
match value {
|
||||||
|
stdb::GameState::None => Self::None,
|
||||||
|
stdb::GameState::Setup => Self::Setup,
|
||||||
|
stdb::GameState::Deal => Self::Deal,
|
||||||
|
stdb::GameState::Play => Self::Play,
|
||||||
|
stdb::GameState::Exit => Self::Exit,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&stdb::Tile> for jong_types::Tile {
|
||||||
|
fn from(value: &stdb::tile_type::Tile) -> Self {
|
||||||
|
Self {
|
||||||
|
suit: value.suit.clone().into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<stdb::Suit> for jong_types::Suit {
|
||||||
|
fn from(value: stdb::Suit) -> Self {
|
||||||
|
match value {
|
||||||
|
stdb::Suit::Man(rank) => Self::Man(rank.into()),
|
||||||
|
stdb::Suit::Pin(rank) => Self::Pin(rank.into()),
|
||||||
|
stdb::Suit::Sou(rank) => Self::Sou(rank.into()),
|
||||||
|
stdb::Suit::Wind(wind) => Self::Wind(wind.into()),
|
||||||
|
stdb::Suit::Dragon(dragon) => Self::Dragon(dragon.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<stdb::Rank> for jong_types::Rank {
|
||||||
|
fn from(value: stdb::Rank) -> Self {
|
||||||
|
Self {
|
||||||
|
number: value.number,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<stdb::Wind> for jong_types::Wind {
|
||||||
|
fn from(value: stdb::Wind) -> Self {
|
||||||
|
Self::from_repr(value as usize).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<stdb::Dragon> for jong_types::Dragon {
|
||||||
|
fn from(value: stdb::Dragon) -> Self {
|
||||||
|
Self::from_repr(value as usize).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
||||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
|
||||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
|
||||||
#[sats(crate = __lib)]
|
|
||||||
pub(super) struct AddPlayerArgs {
|
|
||||||
pub name: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<AddPlayerArgs> for super::Reducer {
|
|
||||||
fn from(args: AddPlayerArgs) -> Self {
|
|
||||||
Self::AddPlayer { name: args.name }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::InModule for AddPlayerArgs {
|
|
||||||
type Module = super::RemoteModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AddPlayerCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the reducer `add_player`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteReducers`].
|
|
||||||
pub trait add_player {
|
|
||||||
/// Request that the remote module invoke the reducer `add_player` to run as soon as possible.
|
|
||||||
///
|
|
||||||
/// This method returns immediately, and errors only if we are unable to send the request.
|
|
||||||
/// The reducer will run asynchronously in the future,
|
|
||||||
/// and its status can be observed by listening for [`Self::on_add_player`] callbacks.
|
|
||||||
fn add_player(&self, name: Option<String>) -> __sdk::Result<()>;
|
|
||||||
/// Register a callback to run whenever we are notified of an invocation of the reducer `add_player`.
|
|
||||||
///
|
|
||||||
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
|
|
||||||
/// to determine the reducer's status.
|
|
||||||
///
|
|
||||||
/// The returned [`AddPlayerCallbackId`] can be passed to [`Self::remove_on_add_player`]
|
|
||||||
/// to cancel the callback.
|
|
||||||
fn on_add_player(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&super::ReducerEventContext, &Option<String>) + Send + 'static,
|
|
||||||
) -> AddPlayerCallbackId;
|
|
||||||
/// Cancel a callback previously registered by [`Self::on_add_player`],
|
|
||||||
/// causing it not to run in the future.
|
|
||||||
fn remove_on_add_player(&self, callback: AddPlayerCallbackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl add_player for super::RemoteReducers {
|
|
||||||
fn add_player(&self, name: Option<String>) -> __sdk::Result<()> {
|
|
||||||
self.imp.call_reducer("add_player", AddPlayerArgs { name })
|
|
||||||
}
|
|
||||||
fn on_add_player(
|
|
||||||
&self,
|
|
||||||
mut callback: impl FnMut(&super::ReducerEventContext, &Option<String>) + Send + 'static,
|
|
||||||
) -> AddPlayerCallbackId {
|
|
||||||
AddPlayerCallbackId(self.imp.on_reducer(
|
|
||||||
"add_player",
|
|
||||||
Box::new(move |ctx: &super::ReducerEventContext| {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
let super::ReducerEventContext {
|
|
||||||
event:
|
|
||||||
__sdk::ReducerEvent {
|
|
||||||
reducer: super::Reducer::AddPlayer { name },
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} = ctx
|
|
||||||
else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
callback(ctx, name)
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
fn remove_on_add_player(&self, callback: AddPlayerCallbackId) {
|
|
||||||
self.imp.remove_on_reducer("add_player", callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[doc(hidden)]
|
|
||||||
/// Extension trait for setting the call-flags for the reducer `add_player`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::SetReducerFlags`].
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
pub trait set_flags_for_add_player {
|
|
||||||
/// Set the call-reducer flags for the reducer `add_player` to `flags`.
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
fn add_player(&self, flags: __ws::CallReducerFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl set_flags_for_add_player for super::SetReducerFlags {
|
|
||||||
fn add_player(&self, flags: __ws::CallReducerFlags) {
|
|
||||||
self.imp.set_call_reducer_flags("add_player", flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -9,6 +9,8 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
pub struct Bot {
|
pub struct Bot {
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub lobby_id: u32,
|
pub lobby_id: u32,
|
||||||
|
pub hand_id: u32,
|
||||||
|
pub pond_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for Bot {
|
impl __sdk::InModule for Bot {
|
||||||
|
|
|
||||||
|
|
@ -1,143 +0,0 @@
|
||||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
|
||||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
|
||||||
use super::bot_hand_type::BotHand;
|
|
||||||
use super::tile_type::Tile;
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
/// Table handle for the table `bothand`.
|
|
||||||
///
|
|
||||||
/// Obtain a handle from the [`BothandTableAccess::bothand`] method on [`super::RemoteTables`],
|
|
||||||
/// like `ctx.db.bothand()`.
|
|
||||||
///
|
|
||||||
/// Users are encouraged not to explicitly reference this type,
|
|
||||||
/// but to directly chain method calls,
|
|
||||||
/// like `ctx.db.bothand().on_insert(...)`.
|
|
||||||
pub struct BothandTableHandle<'ctx> {
|
|
||||||
imp: __sdk::TableHandle<BotHand>,
|
|
||||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the table `bothand`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteTables`].
|
|
||||||
pub trait BothandTableAccess {
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
/// Obtain a [`BothandTableHandle`], which mediates access to the table `bothand`.
|
|
||||||
fn bothand(&self) -> BothandTableHandle<'_>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BothandTableAccess for super::RemoteTables {
|
|
||||||
fn bothand(&self) -> BothandTableHandle<'_> {
|
|
||||||
BothandTableHandle {
|
|
||||||
imp: self.imp.get_table::<BotHand>("bothand"),
|
|
||||||
ctx: std::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct BothandInsertCallbackId(__sdk::CallbackId);
|
|
||||||
pub struct BothandDeleteCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
impl<'ctx> __sdk::Table for BothandTableHandle<'ctx> {
|
|
||||||
type Row = BotHand;
|
|
||||||
type EventContext = super::EventContext;
|
|
||||||
|
|
||||||
fn count(&self) -> u64 {
|
|
||||||
self.imp.count()
|
|
||||||
}
|
|
||||||
fn iter(&self) -> impl Iterator<Item = BotHand> + '_ {
|
|
||||||
self.imp.iter()
|
|
||||||
}
|
|
||||||
|
|
||||||
type InsertCallbackId = BothandInsertCallbackId;
|
|
||||||
|
|
||||||
fn on_insert(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> BothandInsertCallbackId {
|
|
||||||
BothandInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_insert(&self, callback: BothandInsertCallbackId) {
|
|
||||||
self.imp.remove_on_insert(callback.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteCallbackId = BothandDeleteCallbackId;
|
|
||||||
|
|
||||||
fn on_delete(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> BothandDeleteCallbackId {
|
|
||||||
BothandDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_delete(&self, callback: BothandDeleteCallbackId) {
|
|
||||||
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::<BotHand>("bothand");
|
|
||||||
_table.add_unique_constraint::<u32>("bot_id", |row| &row.bot_id);
|
|
||||||
}
|
|
||||||
pub struct BothandUpdateCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
impl<'ctx> __sdk::TableWithPrimaryKey for BothandTableHandle<'ctx> {
|
|
||||||
type UpdateCallbackId = BothandUpdateCallbackId;
|
|
||||||
|
|
||||||
fn on_update(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
|
||||||
) -> BothandUpdateCallbackId {
|
|
||||||
BothandUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_update(&self, callback: BothandUpdateCallbackId) {
|
|
||||||
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<BotHand>> {
|
|
||||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
|
||||||
__sdk::InternalError::failed_parse("TableUpdate<BotHand>", "TableUpdate")
|
|
||||||
.with_cause(e)
|
|
||||||
.into()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Access to the `bot_id` unique index on the table `bothand`,
|
|
||||||
/// which allows point queries on the field of the same name
|
|
||||||
/// via the [`BothandBotIdUnique::find`] method.
|
|
||||||
///
|
|
||||||
/// Users are encouraged not to explicitly reference this type,
|
|
||||||
/// but to directly chain method calls,
|
|
||||||
/// like `ctx.db.bothand().bot_id().find(...)`.
|
|
||||||
pub struct BothandBotIdUnique<'ctx> {
|
|
||||||
imp: __sdk::UniqueConstraintHandle<BotHand, u32>,
|
|
||||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ctx> BothandTableHandle<'ctx> {
|
|
||||||
/// Get a handle on the `bot_id` unique index on the table `bothand`.
|
|
||||||
pub fn bot_id(&self) -> BothandBotIdUnique<'ctx> {
|
|
||||||
BothandBotIdUnique {
|
|
||||||
imp: self.imp.get_unique_constraint::<u32>("bot_id"),
|
|
||||||
phantom: std::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ctx> BothandBotIdUnique<'ctx> {
|
|
||||||
/// Find the subscribed row whose `bot_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<BotHand> {
|
|
||||||
self.imp.find(col_val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
|
||||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
|
||||||
#[sats(crate = __lib)]
|
|
||||||
pub(super) struct DealHandsArgs {}
|
|
||||||
|
|
||||||
impl From<DealHandsArgs> for super::Reducer {
|
|
||||||
fn from(args: DealHandsArgs) -> Self {
|
|
||||||
Self::DealHands
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::InModule for DealHandsArgs {
|
|
||||||
type Module = super::RemoteModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DealHandsCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the reducer `deal_hands`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteReducers`].
|
|
||||||
pub trait deal_hands {
|
|
||||||
/// Request that the remote module invoke the reducer `deal_hands` to run as soon as possible.
|
|
||||||
///
|
|
||||||
/// This method returns immediately, and errors only if we are unable to send the request.
|
|
||||||
/// The reducer will run asynchronously in the future,
|
|
||||||
/// and its status can be observed by listening for [`Self::on_deal_hands`] callbacks.
|
|
||||||
fn deal_hands(&self) -> __sdk::Result<()>;
|
|
||||||
/// Register a callback to run whenever we are notified of an invocation of the reducer `deal_hands`.
|
|
||||||
///
|
|
||||||
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
|
|
||||||
/// to determine the reducer's status.
|
|
||||||
///
|
|
||||||
/// The returned [`DealHandsCallbackId`] can be passed to [`Self::remove_on_deal_hands`]
|
|
||||||
/// to cancel the callback.
|
|
||||||
fn on_deal_hands(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
|
||||||
) -> DealHandsCallbackId;
|
|
||||||
/// Cancel a callback previously registered by [`Self::on_deal_hands`],
|
|
||||||
/// causing it not to run in the future.
|
|
||||||
fn remove_on_deal_hands(&self, callback: DealHandsCallbackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl deal_hands for super::RemoteReducers {
|
|
||||||
fn deal_hands(&self) -> __sdk::Result<()> {
|
|
||||||
self.imp.call_reducer("deal_hands", DealHandsArgs {})
|
|
||||||
}
|
|
||||||
fn on_deal_hands(
|
|
||||||
&self,
|
|
||||||
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
|
||||||
) -> DealHandsCallbackId {
|
|
||||||
DealHandsCallbackId(self.imp.on_reducer(
|
|
||||||
"deal_hands",
|
|
||||||
Box::new(move |ctx: &super::ReducerEventContext| {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
let super::ReducerEventContext {
|
|
||||||
event:
|
|
||||||
__sdk::ReducerEvent {
|
|
||||||
reducer: super::Reducer::DealHands {},
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} = ctx
|
|
||||||
else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
callback(ctx)
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
fn remove_on_deal_hands(&self, callback: DealHandsCallbackId) {
|
|
||||||
self.imp.remove_on_reducer("deal_hands", callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[doc(hidden)]
|
|
||||||
/// Extension trait for setting the call-flags for the reducer `deal_hands`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::SetReducerFlags`].
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
pub trait set_flags_for_deal_hands {
|
|
||||||
/// Set the call-reducer flags for the reducer `deal_hands` to `flags`.
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
fn deal_hands(&self, flags: __ws::CallReducerFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl set_flags_for_deal_hands for super::SetReducerFlags {
|
|
||||||
fn deal_hands(&self, flags: __ws::CallReducerFlags) {
|
|
||||||
self.imp.set_call_reducer_flags("deal_hands", flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
#![allow(unused, clippy::all)]
|
||||||
use super::hand_type::Hand;
|
use super::hand_type::Hand;
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
use super::tile_type::Tile;
|
use super::tile_type::Tile;
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
|
@ -82,7 +83,7 @@ impl<'ctx> __sdk::Table for HandTableHandle<'ctx> {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||||
let _table = client_cache.get_or_make_table::<Hand>("hand");
|
let _table = client_cache.get_or_make_table::<Hand>("hand");
|
||||||
_table.add_unique_constraint::<__sdk::Identity>("player_identity", |row| &row.player_identity);
|
_table.add_unique_constraint::<u32>("id", |row| &row.id);
|
||||||
}
|
}
|
||||||
pub struct HandUpdateCallbackId(__sdk::CallbackId);
|
pub struct HandUpdateCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
|
@ -112,34 +113,32 @@ pub(super) fn parse_table_update(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Access to the `player_identity` unique index on the table `hand`,
|
/// Access to the `id` unique index on the table `hand`,
|
||||||
/// which allows point queries on the field of the same name
|
/// which allows point queries on the field of the same name
|
||||||
/// via the [`HandPlayerIdentityUnique::find`] method.
|
/// via the [`HandIdUnique::find`] method.
|
||||||
///
|
///
|
||||||
/// Users are encouraged not to explicitly reference this type,
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
/// but to directly chain method calls,
|
/// but to directly chain method calls,
|
||||||
/// like `ctx.db.hand().player_identity().find(...)`.
|
/// like `ctx.db.hand().id().find(...)`.
|
||||||
pub struct HandPlayerIdentityUnique<'ctx> {
|
pub struct HandIdUnique<'ctx> {
|
||||||
imp: __sdk::UniqueConstraintHandle<Hand, __sdk::Identity>,
|
imp: __sdk::UniqueConstraintHandle<Hand, u32>,
|
||||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> HandTableHandle<'ctx> {
|
impl<'ctx> HandTableHandle<'ctx> {
|
||||||
/// Get a handle on the `player_identity` unique index on the table `hand`.
|
/// Get a handle on the `id` unique index on the table `hand`.
|
||||||
pub fn player_identity(&self) -> HandPlayerIdentityUnique<'ctx> {
|
pub fn id(&self) -> HandIdUnique<'ctx> {
|
||||||
HandPlayerIdentityUnique {
|
HandIdUnique {
|
||||||
imp: self
|
imp: self.imp.get_unique_constraint::<u32>("id"),
|
||||||
.imp
|
|
||||||
.get_unique_constraint::<__sdk::Identity>("player_identity"),
|
|
||||||
phantom: std::marker::PhantomData,
|
phantom: std::marker::PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> HandPlayerIdentityUnique<'ctx> {
|
impl<'ctx> HandIdUnique<'ctx> {
|
||||||
/// Find the subscribed row whose `player_identity` column value is equal to `col_val`,
|
/// Find the subscribed row whose `id` column value is equal to `col_val`,
|
||||||
/// if such a row is present in the client cache.
|
/// if such a row is present in the client cache.
|
||||||
pub fn find(&self, col_val: &__sdk::Identity) -> Option<Hand> {
|
pub fn find(&self, col_val: &u32) -> Option<Hand> {
|
||||||
self.imp.find(col_val)
|
self.imp.find(col_val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,15 @@
|
||||||
#![allow(unused, clippy::all)]
|
#![allow(unused, clippy::all)]
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
use super::tile_type::Tile;
|
use super::tile_type::Tile;
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
#[sats(crate = __lib)]
|
#[sats(crate = __lib)]
|
||||||
pub struct Hand {
|
pub struct Hand {
|
||||||
pub player_identity: __sdk::Identity,
|
pub id: u32,
|
||||||
|
pub owner: PlayerOrBot,
|
||||||
|
pub sort: bool,
|
||||||
pub tiles: Vec<Tile>,
|
pub tiles: Vec<Tile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,105 +0,0 @@
|
||||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
|
||||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
|
||||||
#[sats(crate = __lib)]
|
|
||||||
pub(super) struct InsertWallArgs {
|
|
||||||
pub player_ids: Vec<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<InsertWallArgs> for super::Reducer {
|
|
||||||
fn from(args: InsertWallArgs) -> Self {
|
|
||||||
Self::InsertWall {
|
|
||||||
player_ids: args.player_ids,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::InModule for InsertWallArgs {
|
|
||||||
type Module = super::RemoteModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct InsertWallCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the reducer `insert_wall`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteReducers`].
|
|
||||||
pub trait insert_wall {
|
|
||||||
/// Request that the remote module invoke the reducer `insert_wall` to run as soon as possible.
|
|
||||||
///
|
|
||||||
/// This method returns immediately, and errors only if we are unable to send the request.
|
|
||||||
/// The reducer will run asynchronously in the future,
|
|
||||||
/// and its status can be observed by listening for [`Self::on_insert_wall`] callbacks.
|
|
||||||
fn insert_wall(&self, player_ids: Vec<u32>) -> __sdk::Result<()>;
|
|
||||||
/// Register a callback to run whenever we are notified of an invocation of the reducer `insert_wall`.
|
|
||||||
///
|
|
||||||
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
|
|
||||||
/// to determine the reducer's status.
|
|
||||||
///
|
|
||||||
/// The returned [`InsertWallCallbackId`] can be passed to [`Self::remove_on_insert_wall`]
|
|
||||||
/// to cancel the callback.
|
|
||||||
fn on_insert_wall(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&super::ReducerEventContext, &Vec<u32>) + Send + 'static,
|
|
||||||
) -> InsertWallCallbackId;
|
|
||||||
/// Cancel a callback previously registered by [`Self::on_insert_wall`],
|
|
||||||
/// causing it not to run in the future.
|
|
||||||
fn remove_on_insert_wall(&self, callback: InsertWallCallbackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl insert_wall for super::RemoteReducers {
|
|
||||||
fn insert_wall(&self, player_ids: Vec<u32>) -> __sdk::Result<()> {
|
|
||||||
self.imp
|
|
||||||
.call_reducer("insert_wall", InsertWallArgs { player_ids })
|
|
||||||
}
|
|
||||||
fn on_insert_wall(
|
|
||||||
&self,
|
|
||||||
mut callback: impl FnMut(&super::ReducerEventContext, &Vec<u32>) + Send + 'static,
|
|
||||||
) -> InsertWallCallbackId {
|
|
||||||
InsertWallCallbackId(self.imp.on_reducer(
|
|
||||||
"insert_wall",
|
|
||||||
Box::new(move |ctx: &super::ReducerEventContext| {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
let super::ReducerEventContext {
|
|
||||||
event:
|
|
||||||
__sdk::ReducerEvent {
|
|
||||||
reducer: super::Reducer::InsertWall { player_ids },
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} = ctx
|
|
||||||
else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
callback(ctx, player_ids)
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
fn remove_on_insert_wall(&self, callback: InsertWallCallbackId) {
|
|
||||||
self.imp.remove_on_reducer("insert_wall", callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[doc(hidden)]
|
|
||||||
/// Extension trait for setting the call-flags for the reducer `insert_wall`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::SetReducerFlags`].
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
pub trait set_flags_for_insert_wall {
|
|
||||||
/// Set the call-reducer flags for the reducer `insert_wall` to `flags`.
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
fn insert_wall(&self, flags: __ws::CallReducerFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl set_flags_for_insert_wall for super::SetReducerFlags {
|
|
||||||
fn insert_wall(&self, flags: __ws::CallReducerFlags) {
|
|
||||||
self.imp.set_call_reducer_flags("insert_wall", flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
|
||||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
|
||||||
#[sats(crate = __lib)]
|
|
||||||
pub(super) struct LobbySetupArgs {}
|
|
||||||
|
|
||||||
impl From<LobbySetupArgs> for super::Reducer {
|
|
||||||
fn from(args: LobbySetupArgs) -> Self {
|
|
||||||
Self::LobbySetup
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::InModule for LobbySetupArgs {
|
|
||||||
type Module = super::RemoteModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct LobbySetupCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the reducer `lobby_setup`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteReducers`].
|
|
||||||
pub trait lobby_setup {
|
|
||||||
/// Request that the remote module invoke the reducer `lobby_setup` to run as soon as possible.
|
|
||||||
///
|
|
||||||
/// This method returns immediately, and errors only if we are unable to send the request.
|
|
||||||
/// The reducer will run asynchronously in the future,
|
|
||||||
/// and its status can be observed by listening for [`Self::on_lobby_setup`] callbacks.
|
|
||||||
fn lobby_setup(&self) -> __sdk::Result<()>;
|
|
||||||
/// Register a callback to run whenever we are notified of an invocation of the reducer `lobby_setup`.
|
|
||||||
///
|
|
||||||
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
|
|
||||||
/// to determine the reducer's status.
|
|
||||||
///
|
|
||||||
/// The returned [`LobbySetupCallbackId`] can be passed to [`Self::remove_on_lobby_setup`]
|
|
||||||
/// to cancel the callback.
|
|
||||||
fn on_lobby_setup(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
|
||||||
) -> LobbySetupCallbackId;
|
|
||||||
/// Cancel a callback previously registered by [`Self::on_lobby_setup`],
|
|
||||||
/// causing it not to run in the future.
|
|
||||||
fn remove_on_lobby_setup(&self, callback: LobbySetupCallbackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl lobby_setup for super::RemoteReducers {
|
|
||||||
fn lobby_setup(&self) -> __sdk::Result<()> {
|
|
||||||
self.imp.call_reducer("lobby_setup", LobbySetupArgs {})
|
|
||||||
}
|
|
||||||
fn on_lobby_setup(
|
|
||||||
&self,
|
|
||||||
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
|
||||||
) -> LobbySetupCallbackId {
|
|
||||||
LobbySetupCallbackId(self.imp.on_reducer(
|
|
||||||
"lobby_setup",
|
|
||||||
Box::new(move |ctx: &super::ReducerEventContext| {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
let super::ReducerEventContext {
|
|
||||||
event:
|
|
||||||
__sdk::ReducerEvent {
|
|
||||||
reducer: super::Reducer::LobbySetup {},
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} = ctx
|
|
||||||
else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
callback(ctx)
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
fn remove_on_lobby_setup(&self, callback: LobbySetupCallbackId) {
|
|
||||||
self.imp.remove_on_reducer("lobby_setup", callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[doc(hidden)]
|
|
||||||
/// Extension trait for setting the call-flags for the reducer `lobby_setup`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::SetReducerFlags`].
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
pub trait set_flags_for_lobby_setup {
|
|
||||||
/// Set the call-reducer flags for the reducer `lobby_setup` to `flags`.
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
fn lobby_setup(&self, flags: __ws::CallReducerFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl set_flags_for_lobby_setup for super::SetReducerFlags {
|
|
||||||
fn lobby_setup(&self, flags: __ws::CallReducerFlags) {
|
|
||||||
self.imp.set_call_reducer_flags("lobby_setup", flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#![allow(unused, clippy::all)]
|
#![allow(unused, clippy::all)]
|
||||||
use super::game_state_type::GameState;
|
use super::game_state_type::GameState;
|
||||||
use super::lobby_type::Lobby;
|
use super::lobby_type::Lobby;
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
/// Table handle for the table `lobby`.
|
/// Table handle for the table `lobby`.
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,14 @@
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
use super::game_state_type::GameState;
|
use super::game_state_type::GameState;
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
#[sats(crate = __lib)]
|
#[sats(crate = __lib)]
|
||||||
pub struct Lobby {
|
pub struct Lobby {
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub host_player_id: u32,
|
pub host_player_id: u32,
|
||||||
|
pub players: Vec<PlayerOrBot>,
|
||||||
pub game_state: GameState,
|
pub game_state: GameState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,8 @@
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
pub mod add_bot_reducer;
|
pub mod add_bot_reducer;
|
||||||
pub mod bot_hand_type;
|
|
||||||
pub mod bot_table;
|
pub mod bot_table;
|
||||||
pub mod bot_type;
|
pub mod bot_type;
|
||||||
pub mod bothand_table;
|
|
||||||
pub mod dragon_type;
|
pub mod dragon_type;
|
||||||
pub mod game_state_type;
|
pub mod game_state_type;
|
||||||
pub mod hand_table;
|
pub mod hand_table;
|
||||||
|
|
@ -19,13 +17,13 @@ pub mod join_or_create_lobby_reducer;
|
||||||
pub mod lobby_table;
|
pub mod lobby_table;
|
||||||
pub mod lobby_type;
|
pub mod lobby_type;
|
||||||
pub mod login_or_add_player_reducer;
|
pub mod login_or_add_player_reducer;
|
||||||
|
pub mod player_or_bot_type;
|
||||||
pub mod player_table;
|
pub mod player_table;
|
||||||
pub mod player_type;
|
pub mod player_type;
|
||||||
pub mod pond_table;
|
pub mod pond_table;
|
||||||
pub mod pond_type;
|
pub mod pond_type;
|
||||||
pub mod rank_type;
|
pub mod rank_type;
|
||||||
pub mod setup_game_reducer;
|
pub mod shuffle_deal_reducer;
|
||||||
pub mod sort_hand_reducer;
|
|
||||||
pub mod suit_type;
|
pub mod suit_type;
|
||||||
pub mod tile_type;
|
pub mod tile_type;
|
||||||
pub mod view_player_hand_table;
|
pub mod view_player_hand_table;
|
||||||
|
|
@ -34,10 +32,8 @@ pub mod wall_type;
|
||||||
pub mod wind_type;
|
pub mod wind_type;
|
||||||
|
|
||||||
pub use add_bot_reducer::{add_bot, set_flags_for_add_bot, AddBotCallbackId};
|
pub use add_bot_reducer::{add_bot, set_flags_for_add_bot, AddBotCallbackId};
|
||||||
pub use bot_hand_type::BotHand;
|
|
||||||
pub use bot_table::*;
|
pub use bot_table::*;
|
||||||
pub use bot_type::Bot;
|
pub use bot_type::Bot;
|
||||||
pub use bothand_table::*;
|
|
||||||
pub use dragon_type::Dragon;
|
pub use dragon_type::Dragon;
|
||||||
pub use game_state_type::GameState;
|
pub use game_state_type::GameState;
|
||||||
pub use hand_table::*;
|
pub use hand_table::*;
|
||||||
|
|
@ -50,13 +46,13 @@ pub use lobby_type::Lobby;
|
||||||
pub use login_or_add_player_reducer::{
|
pub use login_or_add_player_reducer::{
|
||||||
login_or_add_player, set_flags_for_login_or_add_player, LoginOrAddPlayerCallbackId,
|
login_or_add_player, set_flags_for_login_or_add_player, LoginOrAddPlayerCallbackId,
|
||||||
};
|
};
|
||||||
|
pub use player_or_bot_type::PlayerOrBot;
|
||||||
pub use player_table::*;
|
pub use player_table::*;
|
||||||
pub use player_type::Player;
|
pub use player_type::Player;
|
||||||
pub use pond_table::*;
|
pub use pond_table::*;
|
||||||
pub use pond_type::Pond;
|
pub use pond_type::Pond;
|
||||||
pub use rank_type::Rank;
|
pub use rank_type::Rank;
|
||||||
pub use setup_game_reducer::{set_flags_for_setup_game, setup_game, SetupGameCallbackId};
|
pub use shuffle_deal_reducer::{set_flags_for_shuffle_deal, shuffle_deal, ShuffleDealCallbackId};
|
||||||
pub use sort_hand_reducer::{set_flags_for_sort_hand, sort_hand, SortHandCallbackId};
|
|
||||||
pub use suit_type::Suit;
|
pub use suit_type::Suit;
|
||||||
pub use tile_type::Tile;
|
pub use tile_type::Tile;
|
||||||
pub use view_player_hand_table::*;
|
pub use view_player_hand_table::*;
|
||||||
|
|
@ -75,8 +71,7 @@ pub enum Reducer {
|
||||||
AddBot { lobby_id: u32 },
|
AddBot { lobby_id: u32 },
|
||||||
JoinOrCreateLobby { lobby_id: u32 },
|
JoinOrCreateLobby { lobby_id: u32 },
|
||||||
LoginOrAddPlayer,
|
LoginOrAddPlayer,
|
||||||
SetupGame { lobby_id: u32 },
|
ShuffleDeal { lobby_id: u32 },
|
||||||
SortHand,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for Reducer {
|
impl __sdk::InModule for Reducer {
|
||||||
|
|
@ -89,8 +84,7 @@ impl __sdk::Reducer for Reducer {
|
||||||
Reducer::AddBot { .. } => "add_bot",
|
Reducer::AddBot { .. } => "add_bot",
|
||||||
Reducer::JoinOrCreateLobby { .. } => "join_or_create_lobby",
|
Reducer::JoinOrCreateLobby { .. } => "join_or_create_lobby",
|
||||||
Reducer::LoginOrAddPlayer => "login_or_add_player",
|
Reducer::LoginOrAddPlayer => "login_or_add_player",
|
||||||
Reducer::SetupGame { .. } => "setup_game",
|
Reducer::ShuffleDeal { .. } => "shuffle_deal",
|
||||||
Reducer::SortHand => "sort_hand",
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -112,16 +106,9 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer {
|
||||||
login_or_add_player_reducer::LoginOrAddPlayerArgs,
|
login_or_add_player_reducer::LoginOrAddPlayerArgs,
|
||||||
>("login_or_add_player", &value.args)?
|
>("login_or_add_player", &value.args)?
|
||||||
.into()),
|
.into()),
|
||||||
"setup_game" => Ok(
|
"shuffle_deal" => Ok(
|
||||||
__sdk::parse_reducer_args::<setup_game_reducer::SetupGameArgs>(
|
__sdk::parse_reducer_args::<shuffle_deal_reducer::ShuffleDealArgs>(
|
||||||
"setup_game",
|
"shuffle_deal",
|
||||||
&value.args,
|
|
||||||
)?
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
"sort_hand" => Ok(
|
|
||||||
__sdk::parse_reducer_args::<sort_hand_reducer::SortHandArgs>(
|
|
||||||
"sort_hand",
|
|
||||||
&value.args,
|
&value.args,
|
||||||
)?
|
)?
|
||||||
.into(),
|
.into(),
|
||||||
|
|
@ -141,7 +128,6 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct DbUpdate {
|
pub struct DbUpdate {
|
||||||
bot: __sdk::TableUpdate<Bot>,
|
bot: __sdk::TableUpdate<Bot>,
|
||||||
bothand: __sdk::TableUpdate<BotHand>,
|
|
||||||
hand: __sdk::TableUpdate<Hand>,
|
hand: __sdk::TableUpdate<Hand>,
|
||||||
lobby: __sdk::TableUpdate<Lobby>,
|
lobby: __sdk::TableUpdate<Lobby>,
|
||||||
player: __sdk::TableUpdate<Player>,
|
player: __sdk::TableUpdate<Player>,
|
||||||
|
|
@ -159,9 +145,6 @@ impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate {
|
||||||
"bot" => db_update
|
"bot" => db_update
|
||||||
.bot
|
.bot
|
||||||
.append(bot_table::parse_table_update(table_update)?),
|
.append(bot_table::parse_table_update(table_update)?),
|
||||||
"bothand" => db_update
|
|
||||||
.bothand
|
|
||||||
.append(bothand_table::parse_table_update(table_update)?),
|
|
||||||
"hand" => db_update
|
"hand" => db_update
|
||||||
.hand
|
.hand
|
||||||
.append(hand_table::parse_table_update(table_update)?),
|
.append(hand_table::parse_table_update(table_update)?),
|
||||||
|
|
@ -209,19 +192,18 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||||
diff.bot = cache
|
diff.bot = cache
|
||||||
.apply_diff_to_table::<Bot>("bot", &self.bot)
|
.apply_diff_to_table::<Bot>("bot", &self.bot)
|
||||||
.with_updates_by_pk(|row| &row.id);
|
.with_updates_by_pk(|row| &row.id);
|
||||||
diff.bothand = cache
|
|
||||||
.apply_diff_to_table::<BotHand>("bothand", &self.bothand)
|
|
||||||
.with_updates_by_pk(|row| &row.bot_id);
|
|
||||||
diff.hand = cache
|
diff.hand = cache
|
||||||
.apply_diff_to_table::<Hand>("hand", &self.hand)
|
.apply_diff_to_table::<Hand>("hand", &self.hand)
|
||||||
.with_updates_by_pk(|row| &row.player_identity);
|
.with_updates_by_pk(|row| &row.id);
|
||||||
diff.lobby = cache
|
diff.lobby = cache
|
||||||
.apply_diff_to_table::<Lobby>("lobby", &self.lobby)
|
.apply_diff_to_table::<Lobby>("lobby", &self.lobby)
|
||||||
.with_updates_by_pk(|row| &row.id);
|
.with_updates_by_pk(|row| &row.id);
|
||||||
diff.player = cache
|
diff.player = cache
|
||||||
.apply_diff_to_table::<Player>("player", &self.player)
|
.apply_diff_to_table::<Player>("player", &self.player)
|
||||||
.with_updates_by_pk(|row| &row.identity);
|
.with_updates_by_pk(|row| &row.identity);
|
||||||
diff.pond = cache.apply_diff_to_table::<Pond>("pond", &self.pond);
|
diff.pond = cache
|
||||||
|
.apply_diff_to_table::<Pond>("pond", &self.pond)
|
||||||
|
.with_updates_by_pk(|row| &row.id);
|
||||||
diff.wall = cache
|
diff.wall = cache
|
||||||
.apply_diff_to_table::<Wall>("wall", &self.wall)
|
.apply_diff_to_table::<Wall>("wall", &self.wall)
|
||||||
.with_updates_by_pk(|row| &row.lobby_id);
|
.with_updates_by_pk(|row| &row.lobby_id);
|
||||||
|
|
@ -237,7 +219,6 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct AppliedDiff<'r> {
|
pub struct AppliedDiff<'r> {
|
||||||
bot: __sdk::TableAppliedDiff<'r, Bot>,
|
bot: __sdk::TableAppliedDiff<'r, Bot>,
|
||||||
bothand: __sdk::TableAppliedDiff<'r, BotHand>,
|
|
||||||
hand: __sdk::TableAppliedDiff<'r, Hand>,
|
hand: __sdk::TableAppliedDiff<'r, Hand>,
|
||||||
lobby: __sdk::TableAppliedDiff<'r, Lobby>,
|
lobby: __sdk::TableAppliedDiff<'r, Lobby>,
|
||||||
player: __sdk::TableAppliedDiff<'r, Player>,
|
player: __sdk::TableAppliedDiff<'r, Player>,
|
||||||
|
|
@ -258,7 +239,6 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
|
||||||
callbacks: &mut __sdk::DbCallbacks<RemoteModule>,
|
callbacks: &mut __sdk::DbCallbacks<RemoteModule>,
|
||||||
) {
|
) {
|
||||||
callbacks.invoke_table_row_callbacks::<Bot>("bot", &self.bot, event);
|
callbacks.invoke_table_row_callbacks::<Bot>("bot", &self.bot, event);
|
||||||
callbacks.invoke_table_row_callbacks::<BotHand>("bothand", &self.bothand, event);
|
|
||||||
callbacks.invoke_table_row_callbacks::<Hand>("hand", &self.hand, 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::<Lobby>("lobby", &self.lobby, event);
|
||||||
callbacks.invoke_table_row_callbacks::<Player>("player", &self.player, event);
|
callbacks.invoke_table_row_callbacks::<Player>("player", &self.player, event);
|
||||||
|
|
@ -989,7 +969,6 @@ impl __sdk::SpacetimeModule for RemoteModule {
|
||||||
|
|
||||||
fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
|
fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
|
||||||
bot_table::register_table(client_cache);
|
bot_table::register_table(client_cache);
|
||||||
bothand_table::register_table(client_cache);
|
|
||||||
hand_table::register_table(client_cache);
|
hand_table::register_table(client_cache);
|
||||||
lobby_table::register_table(client_cache);
|
lobby_table::register_table(client_cache);
|
||||||
player_table::register_table(client_cache);
|
player_table::register_table(client_cache);
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,14 @@
|
||||||
#![allow(unused, clippy::all)]
|
#![allow(unused, clippy::all)]
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
use super::tile_type::Tile;
|
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
#[sats(crate = __lib)]
|
#[sats(crate = __lib)]
|
||||||
pub struct BotHand {
|
pub enum PlayerOrBot {
|
||||||
pub bot_id: u32,
|
Player(u32),
|
||||||
pub tiles: Vec<Tile>,
|
|
||||||
|
Bot(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for BotHand {
|
impl __sdk::InModule for PlayerOrBot {
|
||||||
type Module = super::RemoteModule;
|
type Module = super::RemoteModule;
|
||||||
}
|
}
|
||||||
|
|
@ -11,6 +11,8 @@ pub struct Player {
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub lobby_id: u32,
|
pub lobby_id: u32,
|
||||||
|
pub hand_id: u32,
|
||||||
|
pub pond_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for Player {
|
impl __sdk::InModule for Player {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
#![allow(unused, clippy::all)]
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
use super::pond_type::Pond;
|
use super::pond_type::Pond;
|
||||||
use super::tile_type::Tile;
|
use super::tile_type::Tile;
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
@ -82,6 +83,23 @@ impl<'ctx> __sdk::Table for PondTableHandle<'ctx> {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||||
let _table = client_cache.get_or_make_table::<Pond>("pond");
|
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)]
|
#[doc(hidden)]
|
||||||
|
|
@ -94,3 +112,33 @@ pub(super) fn parse_table_update(
|
||||||
.into()
|
.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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,14 @@
|
||||||
#![allow(unused, clippy::all)]
|
#![allow(unused, clippy::all)]
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
use super::tile_type::Tile;
|
use super::tile_type::Tile;
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
#[sats(crate = __lib)]
|
#[sats(crate = __lib)]
|
||||||
pub struct Pond {
|
pub struct Pond {
|
||||||
|
pub id: u32,
|
||||||
|
pub owner: PlayerOrBot,
|
||||||
pub tiles: Vec<Tile>,
|
pub tiles: Vec<Tile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
||||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
|
||||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
|
||||||
#[sats(crate = __lib)]
|
|
||||||
pub(super) struct SetNameArgs {
|
|
||||||
pub name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<SetNameArgs> for super::Reducer {
|
|
||||||
fn from(args: SetNameArgs) -> Self {
|
|
||||||
Self::SetName { name: args.name }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::InModule for SetNameArgs {
|
|
||||||
type Module = super::RemoteModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SetNameCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the reducer `set_name`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteReducers`].
|
|
||||||
pub trait set_name {
|
|
||||||
/// Request that the remote module invoke the reducer `set_name` to run as soon as possible.
|
|
||||||
///
|
|
||||||
/// This method returns immediately, and errors only if we are unable to send the request.
|
|
||||||
/// The reducer will run asynchronously in the future,
|
|
||||||
/// and its status can be observed by listening for [`Self::on_set_name`] callbacks.
|
|
||||||
fn set_name(&self, name: String) -> __sdk::Result<()>;
|
|
||||||
/// Register a callback to run whenever we are notified of an invocation of the reducer `set_name`.
|
|
||||||
///
|
|
||||||
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
|
|
||||||
/// to determine the reducer's status.
|
|
||||||
///
|
|
||||||
/// The returned [`SetNameCallbackId`] can be passed to [`Self::remove_on_set_name`]
|
|
||||||
/// to cancel the callback.
|
|
||||||
fn on_set_name(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static,
|
|
||||||
) -> SetNameCallbackId;
|
|
||||||
/// Cancel a callback previously registered by [`Self::on_set_name`],
|
|
||||||
/// causing it not to run in the future.
|
|
||||||
fn remove_on_set_name(&self, callback: SetNameCallbackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl set_name for super::RemoteReducers {
|
|
||||||
fn set_name(&self, name: String) -> __sdk::Result<()> {
|
|
||||||
self.imp.call_reducer("set_name", SetNameArgs { name })
|
|
||||||
}
|
|
||||||
fn on_set_name(
|
|
||||||
&self,
|
|
||||||
mut callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static,
|
|
||||||
) -> SetNameCallbackId {
|
|
||||||
SetNameCallbackId(self.imp.on_reducer(
|
|
||||||
"set_name",
|
|
||||||
Box::new(move |ctx: &super::ReducerEventContext| {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
let super::ReducerEventContext {
|
|
||||||
event:
|
|
||||||
__sdk::ReducerEvent {
|
|
||||||
reducer: super::Reducer::SetName { name },
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} = ctx
|
|
||||||
else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
callback(ctx, name)
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
fn remove_on_set_name(&self, callback: SetNameCallbackId) {
|
|
||||||
self.imp.remove_on_reducer("set_name", callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[doc(hidden)]
|
|
||||||
/// Extension trait for setting the call-flags for the reducer `set_name`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::SetReducerFlags`].
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
pub trait set_flags_for_set_name {
|
|
||||||
/// Set the call-reducer flags for the reducer `set_name` to `flags`.
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
fn set_name(&self, flags: __ws::CallReducerFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl set_flags_for_set_name for super::SetReducerFlags {
|
|
||||||
fn set_name(&self, flags: __ws::CallReducerFlags) {
|
|
||||||
self.imp.set_call_reducer_flags("set_name", flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -6,68 +6,68 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
#[sats(crate = __lib)]
|
#[sats(crate = __lib)]
|
||||||
pub(super) struct SetupGameArgs {
|
pub(super) struct ShuffleDealArgs {
|
||||||
pub lobby_id: u32,
|
pub lobby_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SetupGameArgs> for super::Reducer {
|
impl From<ShuffleDealArgs> for super::Reducer {
|
||||||
fn from(args: SetupGameArgs) -> Self {
|
fn from(args: ShuffleDealArgs) -> Self {
|
||||||
Self::SetupGame {
|
Self::ShuffleDeal {
|
||||||
lobby_id: args.lobby_id,
|
lobby_id: args.lobby_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for SetupGameArgs {
|
impl __sdk::InModule for ShuffleDealArgs {
|
||||||
type Module = super::RemoteModule;
|
type Module = super::RemoteModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SetupGameCallbackId(__sdk::CallbackId);
|
pub struct ShuffleDealCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
/// Extension trait for access to the reducer `setup_game`.
|
/// Extension trait for access to the reducer `shuffle_deal`.
|
||||||
///
|
///
|
||||||
/// Implemented for [`super::RemoteReducers`].
|
/// Implemented for [`super::RemoteReducers`].
|
||||||
pub trait setup_game {
|
pub trait shuffle_deal {
|
||||||
/// Request that the remote module invoke the reducer `setup_game` to run as soon as possible.
|
/// Request that the remote module invoke the reducer `shuffle_deal` to run as soon as possible.
|
||||||
///
|
///
|
||||||
/// This method returns immediately, and errors only if we are unable to send the request.
|
/// This method returns immediately, and errors only if we are unable to send the request.
|
||||||
/// The reducer will run asynchronously in the future,
|
/// The reducer will run asynchronously in the future,
|
||||||
/// and its status can be observed by listening for [`Self::on_setup_game`] callbacks.
|
/// and its status can be observed by listening for [`Self::on_shuffle_deal`] callbacks.
|
||||||
fn setup_game(&self, lobby_id: u32) -> __sdk::Result<()>;
|
fn shuffle_deal(&self, lobby_id: u32) -> __sdk::Result<()>;
|
||||||
/// Register a callback to run whenever we are notified of an invocation of the reducer `setup_game`.
|
/// Register a callback to run whenever we are notified of an invocation of the reducer `shuffle_deal`.
|
||||||
///
|
///
|
||||||
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
|
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
|
||||||
/// to determine the reducer's status.
|
/// to determine the reducer's status.
|
||||||
///
|
///
|
||||||
/// The returned [`SetupGameCallbackId`] can be passed to [`Self::remove_on_setup_game`]
|
/// The returned [`ShuffleDealCallbackId`] can be passed to [`Self::remove_on_shuffle_deal`]
|
||||||
/// to cancel the callback.
|
/// to cancel the callback.
|
||||||
fn on_setup_game(
|
fn on_shuffle_deal(
|
||||||
&self,
|
&self,
|
||||||
callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static,
|
callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static,
|
||||||
) -> SetupGameCallbackId;
|
) -> ShuffleDealCallbackId;
|
||||||
/// Cancel a callback previously registered by [`Self::on_setup_game`],
|
/// Cancel a callback previously registered by [`Self::on_shuffle_deal`],
|
||||||
/// causing it not to run in the future.
|
/// causing it not to run in the future.
|
||||||
fn remove_on_setup_game(&self, callback: SetupGameCallbackId);
|
fn remove_on_shuffle_deal(&self, callback: ShuffleDealCallbackId);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl setup_game for super::RemoteReducers {
|
impl shuffle_deal for super::RemoteReducers {
|
||||||
fn setup_game(&self, lobby_id: u32) -> __sdk::Result<()> {
|
fn shuffle_deal(&self, lobby_id: u32) -> __sdk::Result<()> {
|
||||||
self.imp
|
self.imp
|
||||||
.call_reducer("setup_game", SetupGameArgs { lobby_id })
|
.call_reducer("shuffle_deal", ShuffleDealArgs { lobby_id })
|
||||||
}
|
}
|
||||||
fn on_setup_game(
|
fn on_shuffle_deal(
|
||||||
&self,
|
&self,
|
||||||
mut callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static,
|
mut callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static,
|
||||||
) -> SetupGameCallbackId {
|
) -> ShuffleDealCallbackId {
|
||||||
SetupGameCallbackId(self.imp.on_reducer(
|
ShuffleDealCallbackId(self.imp.on_reducer(
|
||||||
"setup_game",
|
"shuffle_deal",
|
||||||
Box::new(move |ctx: &super::ReducerEventContext| {
|
Box::new(move |ctx: &super::ReducerEventContext| {
|
||||||
#[allow(irrefutable_let_patterns)]
|
#[allow(irrefutable_let_patterns)]
|
||||||
let super::ReducerEventContext {
|
let super::ReducerEventContext {
|
||||||
event:
|
event:
|
||||||
__sdk::ReducerEvent {
|
__sdk::ReducerEvent {
|
||||||
reducer: super::Reducer::SetupGame { lobby_id },
|
reducer: super::Reducer::ShuffleDeal { lobby_id },
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
..
|
..
|
||||||
|
|
@ -79,27 +79,27 @@ impl setup_game for super::RemoteReducers {
|
||||||
}),
|
}),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn remove_on_setup_game(&self, callback: SetupGameCallbackId) {
|
fn remove_on_shuffle_deal(&self, callback: ShuffleDealCallbackId) {
|
||||||
self.imp.remove_on_reducer("setup_game", callback.0)
|
self.imp.remove_on_reducer("shuffle_deal", callback.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
/// Extension trait for setting the call-flags for the reducer `setup_game`.
|
/// Extension trait for setting the call-flags for the reducer `shuffle_deal`.
|
||||||
///
|
///
|
||||||
/// Implemented for [`super::SetReducerFlags`].
|
/// Implemented for [`super::SetReducerFlags`].
|
||||||
///
|
///
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
/// This type is currently unstable and may be removed without a major version bump.
|
||||||
pub trait set_flags_for_setup_game {
|
pub trait set_flags_for_shuffle_deal {
|
||||||
/// Set the call-reducer flags for the reducer `setup_game` to `flags`.
|
/// Set the call-reducer flags for the reducer `shuffle_deal` to `flags`.
|
||||||
///
|
///
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
/// This type is currently unstable and may be removed without a major version bump.
|
||||||
fn setup_game(&self, flags: __ws::CallReducerFlags);
|
fn shuffle_deal(&self, flags: __ws::CallReducerFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl set_flags_for_setup_game for super::SetReducerFlags {
|
impl set_flags_for_shuffle_deal for super::SetReducerFlags {
|
||||||
fn setup_game(&self, flags: __ws::CallReducerFlags) {
|
fn shuffle_deal(&self, flags: __ws::CallReducerFlags) {
|
||||||
self.imp.set_call_reducer_flags("setup_game", flags);
|
self.imp.set_call_reducer_flags("shuffle_deal", flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
|
||||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
|
||||||
#[sats(crate = __lib)]
|
|
||||||
pub(super) struct ShuffleWallArgs {}
|
|
||||||
|
|
||||||
impl From<ShuffleWallArgs> for super::Reducer {
|
|
||||||
fn from(args: ShuffleWallArgs) -> Self {
|
|
||||||
Self::ShuffleWall
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::InModule for ShuffleWallArgs {
|
|
||||||
type Module = super::RemoteModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ShuffleWallCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the reducer `shuffle_wall`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteReducers`].
|
|
||||||
pub trait shuffle_wall {
|
|
||||||
/// Request that the remote module invoke the reducer `shuffle_wall` to run as soon as possible.
|
|
||||||
///
|
|
||||||
/// This method returns immediately, and errors only if we are unable to send the request.
|
|
||||||
/// The reducer will run asynchronously in the future,
|
|
||||||
/// and its status can be observed by listening for [`Self::on_shuffle_wall`] callbacks.
|
|
||||||
fn shuffle_wall(&self) -> __sdk::Result<()>;
|
|
||||||
/// Register a callback to run whenever we are notified of an invocation of the reducer `shuffle_wall`.
|
|
||||||
///
|
|
||||||
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
|
|
||||||
/// to determine the reducer's status.
|
|
||||||
///
|
|
||||||
/// The returned [`ShuffleWallCallbackId`] can be passed to [`Self::remove_on_shuffle_wall`]
|
|
||||||
/// to cancel the callback.
|
|
||||||
fn on_shuffle_wall(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
|
||||||
) -> ShuffleWallCallbackId;
|
|
||||||
/// Cancel a callback previously registered by [`Self::on_shuffle_wall`],
|
|
||||||
/// causing it not to run in the future.
|
|
||||||
fn remove_on_shuffle_wall(&self, callback: ShuffleWallCallbackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl shuffle_wall for super::RemoteReducers {
|
|
||||||
fn shuffle_wall(&self) -> __sdk::Result<()> {
|
|
||||||
self.imp.call_reducer("shuffle_wall", ShuffleWallArgs {})
|
|
||||||
}
|
|
||||||
fn on_shuffle_wall(
|
|
||||||
&self,
|
|
||||||
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
|
||||||
) -> ShuffleWallCallbackId {
|
|
||||||
ShuffleWallCallbackId(self.imp.on_reducer(
|
|
||||||
"shuffle_wall",
|
|
||||||
Box::new(move |ctx: &super::ReducerEventContext| {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
let super::ReducerEventContext {
|
|
||||||
event:
|
|
||||||
__sdk::ReducerEvent {
|
|
||||||
reducer: super::Reducer::ShuffleWall {},
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} = ctx
|
|
||||||
else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
callback(ctx)
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
fn remove_on_shuffle_wall(&self, callback: ShuffleWallCallbackId) {
|
|
||||||
self.imp.remove_on_reducer("shuffle_wall", callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[doc(hidden)]
|
|
||||||
/// Extension trait for setting the call-flags for the reducer `shuffle_wall`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::SetReducerFlags`].
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
pub trait set_flags_for_shuffle_wall {
|
|
||||||
/// Set the call-reducer flags for the reducer `shuffle_wall` to `flags`.
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
fn shuffle_wall(&self, flags: __ws::CallReducerFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl set_flags_for_shuffle_wall for super::SetReducerFlags {
|
|
||||||
fn shuffle_wall(&self, flags: __ws::CallReducerFlags) {
|
|
||||||
self.imp.set_call_reducer_flags("shuffle_wall", flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
|
||||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
|
||||||
#[sats(crate = __lib)]
|
|
||||||
pub(super) struct SortHandArgs {}
|
|
||||||
|
|
||||||
impl From<SortHandArgs> for super::Reducer {
|
|
||||||
fn from(args: SortHandArgs) -> Self {
|
|
||||||
Self::SortHand
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::InModule for SortHandArgs {
|
|
||||||
type Module = super::RemoteModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SortHandCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the reducer `sort_hand`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteReducers`].
|
|
||||||
pub trait sort_hand {
|
|
||||||
/// Request that the remote module invoke the reducer `sort_hand` to run as soon as possible.
|
|
||||||
///
|
|
||||||
/// This method returns immediately, and errors only if we are unable to send the request.
|
|
||||||
/// The reducer will run asynchronously in the future,
|
|
||||||
/// and its status can be observed by listening for [`Self::on_sort_hand`] callbacks.
|
|
||||||
fn sort_hand(&self) -> __sdk::Result<()>;
|
|
||||||
/// Register a callback to run whenever we are notified of an invocation of the reducer `sort_hand`.
|
|
||||||
///
|
|
||||||
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
|
|
||||||
/// to determine the reducer's status.
|
|
||||||
///
|
|
||||||
/// The returned [`SortHandCallbackId`] can be passed to [`Self::remove_on_sort_hand`]
|
|
||||||
/// to cancel the callback.
|
|
||||||
fn on_sort_hand(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
|
||||||
) -> SortHandCallbackId;
|
|
||||||
/// Cancel a callback previously registered by [`Self::on_sort_hand`],
|
|
||||||
/// causing it not to run in the future.
|
|
||||||
fn remove_on_sort_hand(&self, callback: SortHandCallbackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl sort_hand for super::RemoteReducers {
|
|
||||||
fn sort_hand(&self) -> __sdk::Result<()> {
|
|
||||||
self.imp.call_reducer("sort_hand", SortHandArgs {})
|
|
||||||
}
|
|
||||||
fn on_sort_hand(
|
|
||||||
&self,
|
|
||||||
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
|
||||||
) -> SortHandCallbackId {
|
|
||||||
SortHandCallbackId(self.imp.on_reducer(
|
|
||||||
"sort_hand",
|
|
||||||
Box::new(move |ctx: &super::ReducerEventContext| {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
let super::ReducerEventContext {
|
|
||||||
event:
|
|
||||||
__sdk::ReducerEvent {
|
|
||||||
reducer: super::Reducer::SortHand {},
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} = ctx
|
|
||||||
else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
callback(ctx)
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
fn remove_on_sort_hand(&self, callback: SortHandCallbackId) {
|
|
||||||
self.imp.remove_on_reducer("sort_hand", callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[doc(hidden)]
|
|
||||||
/// Extension trait for setting the call-flags for the reducer `sort_hand`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::SetReducerFlags`].
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
pub trait set_flags_for_sort_hand {
|
|
||||||
/// Set the call-reducer flags for the reducer `sort_hand` to `flags`.
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
fn sort_hand(&self, flags: __ws::CallReducerFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl set_flags_for_sort_hand for super::SetReducerFlags {
|
|
||||||
fn sort_hand(&self, flags: __ws::CallReducerFlags) {
|
|
||||||
self.imp.set_call_reducer_flags("sort_hand", flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
|
||||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
|
||||||
use super::hand_type::Hand;
|
|
||||||
use super::tile_type::Tile;
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
/// Table handle for the table `view_hand`.
|
|
||||||
///
|
|
||||||
/// Obtain a handle from the [`ViewHandTableAccess::view_hand`] method on [`super::RemoteTables`],
|
|
||||||
/// like `ctx.db.view_hand()`.
|
|
||||||
///
|
|
||||||
/// Users are encouraged not to explicitly reference this type,
|
|
||||||
/// but to directly chain method calls,
|
|
||||||
/// like `ctx.db.view_hand().on_insert(...)`.
|
|
||||||
pub struct ViewHandTableHandle<'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_hand`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteTables`].
|
|
||||||
pub trait ViewHandTableAccess {
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
/// Obtain a [`ViewHandTableHandle`], which mediates access to the table `view_hand`.
|
|
||||||
fn view_hand(&self) -> ViewHandTableHandle<'_>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ViewHandTableAccess for super::RemoteTables {
|
|
||||||
fn view_hand(&self) -> ViewHandTableHandle<'_> {
|
|
||||||
ViewHandTableHandle {
|
|
||||||
imp: self.imp.get_table::<Hand>("view_hand"),
|
|
||||||
ctx: std::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ViewHandInsertCallbackId(__sdk::CallbackId);
|
|
||||||
pub struct ViewHandDeleteCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
impl<'ctx> __sdk::Table for ViewHandTableHandle<'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 = ViewHandInsertCallbackId;
|
|
||||||
|
|
||||||
fn on_insert(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> ViewHandInsertCallbackId {
|
|
||||||
ViewHandInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_insert(&self, callback: ViewHandInsertCallbackId) {
|
|
||||||
self.imp.remove_on_insert(callback.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteCallbackId = ViewHandDeleteCallbackId;
|
|
||||||
|
|
||||||
fn on_delete(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> ViewHandDeleteCallbackId {
|
|
||||||
ViewHandDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_delete(&self, callback: ViewHandDeleteCallbackId) {
|
|
||||||
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_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()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#![allow(unused, clippy::all)]
|
#![allow(unused, clippy::all)]
|
||||||
use super::hand_type::Hand;
|
use super::hand_type::Hand;
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
use super::tile_type::Tile;
|
use super::tile_type::Tile;
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
|
|
||||||
8
justfile
8
justfile
|
|
@ -2,11 +2,14 @@ set shell := ["nu", "-c"]
|
||||||
|
|
||||||
alias rt := run-tui
|
alias rt := run-tui
|
||||||
alias s := spacetime
|
alias s := spacetime
|
||||||
|
alias g := spacetime_generate-bindings
|
||||||
|
|
||||||
default:
|
default:
|
||||||
just --list
|
just --list
|
||||||
|
|
||||||
run-tui:
|
run-tui:
|
||||||
|
mprocs -s localhost:4050 --ctl $"({c: restart-proc, name: spacetimedb_generate_bindings} | to yaml)"
|
||||||
|
sleep 3sec
|
||||||
cargo run -- run-tui
|
cargo run -- run-tui
|
||||||
|
|
||||||
update:
|
update:
|
||||||
|
|
@ -16,5 +19,8 @@ update:
|
||||||
spacetime:
|
spacetime:
|
||||||
devenv up
|
devenv up
|
||||||
|
|
||||||
generate-bindings:
|
spacetime_dev:
|
||||||
|
spacetime dev --module-bindings-path jong/src/stdb jongline --delete-data=always
|
||||||
|
|
||||||
|
spacetime_generate-bindings:
|
||||||
spacetime generate --lang rust --out-dir jong/src/stdb --project-path spacetimedb
|
spacetime generate --lang rust --out-dir jong/src/stdb --project-path spacetimedb
|
||||||
|
|
|
||||||
60
spacetimedb/src/game.rs
Normal file
60
spacetimedb/src/game.rs
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
use log::info;
|
||||||
|
use spacetimedb::{ReducerContext, Table, rand::seq::SliceRandom, reducer};
|
||||||
|
|
||||||
|
use crate::tables::*;
|
||||||
|
use jong_types::*;
|
||||||
|
|
||||||
|
mod hand;
|
||||||
|
mod wall;
|
||||||
|
|
||||||
|
#[reducer]
|
||||||
|
pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<(), String> {
|
||||||
|
let ok_or = ctx
|
||||||
|
.db
|
||||||
|
.player()
|
||||||
|
.identity()
|
||||||
|
.find(ctx.sender)
|
||||||
|
.ok_or(format!("cannot find player {}", ctx.sender))?;
|
||||||
|
let mut player = ok_or;
|
||||||
|
|
||||||
|
if lobby_id == 0 {
|
||||||
|
let lobby = ctx.db.lobby().insert(Lobby {
|
||||||
|
id: 0,
|
||||||
|
host_player_id: player.id,
|
||||||
|
players: vec![PlayerOrBot::Player { id: player.id }],
|
||||||
|
game_state: GameState::Setup,
|
||||||
|
});
|
||||||
|
info!("created lobby: {:?}", lobby);
|
||||||
|
|
||||||
|
lobby_id = lobby.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.lobby_id = lobby_id;
|
||||||
|
|
||||||
|
let player = ctx.db.player().identity().update(player);
|
||||||
|
|
||||||
|
info!("player {} joined lobby {}", player.id, lobby_id);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[reducer]
|
||||||
|
pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> {
|
||||||
|
if lobby_id == 0 {
|
||||||
|
Err("cannot add a bot without a lobby".into())
|
||||||
|
} else if let Some(lobby) = ctx.db.lobby().id().find(lobby_id)
|
||||||
|
&& (ctx.db.player().lobby_id().filter(lobby_id).count()
|
||||||
|
+ ctx.db.bot().lobby_id().filter(lobby_id).count()
|
||||||
|
<= 4)
|
||||||
|
{
|
||||||
|
let bot = ctx.db.bot().insert(Bot {
|
||||||
|
id: 0,
|
||||||
|
lobby_id,
|
||||||
|
hand_id: 0,
|
||||||
|
pond_id: 0,
|
||||||
|
});
|
||||||
|
info!("added bot {} to lobby {}", bot.id, lobby_id);
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err("lobby doesn't exist".into())
|
||||||
|
}
|
||||||
|
}
|
||||||
53
spacetimedb/src/game/hand.rs
Normal file
53
spacetimedb/src/game/hand.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
use spacetimedb::{ReducerContext, Table, ViewContext, reducer, view};
|
||||||
|
|
||||||
|
use crate::tables::*;
|
||||||
|
use jong_types::*;
|
||||||
|
|
||||||
|
pub fn deal_hands(ctx: &ReducerContext, lobby_id: u32) {
|
||||||
|
let players = ctx.db.player().lobby_id().filter(lobby_id);
|
||||||
|
let bots = ctx.db.bot().lobby_id().filter(lobby_id);
|
||||||
|
|
||||||
|
let mut wall = ctx.db.wall().lobby_id().find(lobby_id).unwrap();
|
||||||
|
|
||||||
|
// FIXME rectify deal orders
|
||||||
|
for mut player in players {
|
||||||
|
let mut tiles = wall.tiles.split_off(wall.tiles.len() - 13);
|
||||||
|
tiles.sort();
|
||||||
|
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);
|
||||||
|
tiles.sort();
|
||||||
|
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))?
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[reducer]
|
||||||
|
// pub fn sort_hand(ctx: &ReducerContext) {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
36
spacetimedb/src/game/wall.rs
Normal file
36
spacetimedb/src/game/wall.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
use log::debug;
|
||||||
|
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();
|
||||||
|
|
||||||
|
lobby.game_state = GameState::Deal;
|
||||||
|
let mut lobby = ctx.db.lobby().id().update(lobby);
|
||||||
|
|
||||||
|
|
||||||
|
let tiles = new_shuffled_wall(ctx);
|
||||||
|
ctx.db.wall().insert(Wall {
|
||||||
|
// id: 0,
|
||||||
|
lobby_id,
|
||||||
|
tiles,
|
||||||
|
});
|
||||||
|
|
||||||
|
deal_hands(ctx, lobby_id);
|
||||||
|
|
||||||
|
lobby.game_state = GameState::Play;
|
||||||
|
ctx.db.lobby().id().update(lobby);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_shuffled_wall(ctx: &ReducerContext) -> Vec<Tile> {
|
||||||
|
let mut rng = ctx.rng();
|
||||||
|
let mut wall = tiles();
|
||||||
|
wall.shuffle(&mut rng);
|
||||||
|
|
||||||
|
wall
|
||||||
|
}
|
||||||
|
|
@ -1,83 +1,13 @@
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use spacetimedb::{
|
use spacetimedb::{
|
||||||
Identity, ReducerContext, Table, ViewContext, rand::seq::SliceRandom, reducer, table, view,
|
ReducerContext, Table, ViewContext, rand::seq::SliceRandom, reducer, table, view,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::tables::*;
|
||||||
use jong_types::*;
|
use jong_types::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
mod game;
|
||||||
#[table(name = player, public)]
|
mod tables;
|
||||||
pub struct Player {
|
|
||||||
#[primary_key]
|
|
||||||
identity: Identity,
|
|
||||||
|
|
||||||
#[auto_inc]
|
|
||||||
#[index(direct)]
|
|
||||||
#[unique]
|
|
||||||
id: u32,
|
|
||||||
|
|
||||||
name: Option<String>,
|
|
||||||
|
|
||||||
#[index(btree)]
|
|
||||||
lobby_id: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[table(name = bot)]
|
|
||||||
pub struct Bot {
|
|
||||||
#[primary_key]
|
|
||||||
#[auto_inc]
|
|
||||||
id: u32,
|
|
||||||
|
|
||||||
#[index(btree)]
|
|
||||||
lobby_id: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
#[table(name = lobby, public)]
|
|
||||||
pub struct Lobby {
|
|
||||||
#[primary_key]
|
|
||||||
#[auto_inc]
|
|
||||||
id: u32,
|
|
||||||
|
|
||||||
#[index(direct)]
|
|
||||||
#[unique]
|
|
||||||
host_player_id: u32,
|
|
||||||
|
|
||||||
game_state: GameState,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[table(name = wall)]
|
|
||||||
pub struct Wall {
|
|
||||||
// #[auto_inc]
|
|
||||||
// id: u32,
|
|
||||||
#[primary_key]
|
|
||||||
// #[index(direct)]
|
|
||||||
// #[unique]
|
|
||||||
lobby_id: u32,
|
|
||||||
|
|
||||||
tiles: Vec<Tile>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[table(name = hand)]
|
|
||||||
pub struct Hand {
|
|
||||||
#[primary_key]
|
|
||||||
player_identity: Identity,
|
|
||||||
|
|
||||||
tiles: Vec<Tile>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[table(name = bothand)]
|
|
||||||
pub struct BotHand {
|
|
||||||
#[primary_key]
|
|
||||||
bot_id: u32,
|
|
||||||
|
|
||||||
tiles: Vec<Tile>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[table(name = pond, public)]
|
|
||||||
pub struct Pond {
|
|
||||||
tiles: Vec<Tile>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[reducer(client_connected)]
|
#[reducer(client_connected)]
|
||||||
pub fn login_or_add_player(ctx: &ReducerContext) {
|
pub fn login_or_add_player(ctx: &ReducerContext) {
|
||||||
|
|
@ -89,6 +19,8 @@ pub fn login_or_add_player(ctx: &ReducerContext) {
|
||||||
id: 0,
|
id: 0,
|
||||||
name: None,
|
name: None,
|
||||||
lobby_id: 0,
|
lobby_id: 0,
|
||||||
|
hand_id: 0,
|
||||||
|
pond_id: 0,
|
||||||
}) {
|
}) {
|
||||||
info!("added player: {:?}", player);
|
info!("added player: {:?}", player);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -97,117 +29,6 @@ pub fn login_or_add_player(ctx: &ReducerContext) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[reducer]
|
|
||||||
pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<(), String> {
|
|
||||||
let mut player = ctx
|
|
||||||
.db
|
|
||||||
.player()
|
|
||||||
.identity()
|
|
||||||
.find(ctx.sender)
|
|
||||||
.ok_or(format!("cannot find player {}", ctx.sender))?;
|
|
||||||
|
|
||||||
if lobby_id == 0 {
|
|
||||||
let lobby = ctx.db.lobby().insert(Lobby {
|
|
||||||
id: 0,
|
|
||||||
host_player_id: player.id,
|
|
||||||
game_state: GameState::None,
|
|
||||||
});
|
|
||||||
info!("created lobby: {:?}", lobby);
|
|
||||||
|
|
||||||
lobby_id = lobby.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
player.lobby_id = lobby_id;
|
|
||||||
|
|
||||||
let player = ctx.db.player().identity().update(player);
|
|
||||||
|
|
||||||
info!("player {} joined lobby {}", player.id, lobby_id);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[reducer]
|
|
||||||
pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> {
|
|
||||||
if lobby_id == 0 {
|
|
||||||
Err("cannot add a bot without a lobby".into())
|
|
||||||
} else if let Some(lobby) = ctx.db.lobby().id().find(lobby_id)
|
|
||||||
&& (ctx.db.player().lobby_id().filter(lobby_id).count()
|
|
||||||
+ ctx.db.bot().lobby_id().filter(lobby_id).count()
|
|
||||||
<= 4)
|
|
||||||
{
|
|
||||||
let bot = ctx.db.bot().insert(Bot { id: 0, lobby_id });
|
|
||||||
info!("added bot {} to lobby {}", bot.id, lobby_id);
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err("lobby doesn't exist".into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[reducer]
|
|
||||||
pub fn setup_game(ctx: &ReducerContext, lobby_id: u32) {
|
|
||||||
debug!("lobby_id: {lobby_id}");
|
|
||||||
let mut lobby = ctx.db.lobby().id().find(lobby_id).unwrap();
|
|
||||||
lobby.game_state = GameState::Setup;
|
|
||||||
|
|
||||||
ctx.db.lobby().id().update(lobby);
|
|
||||||
|
|
||||||
let tiles = new_shuffled_wall(ctx);
|
|
||||||
ctx.db.wall().insert(Wall {
|
|
||||||
// id: 0,
|
|
||||||
lobby_id,
|
|
||||||
tiles,
|
|
||||||
});
|
|
||||||
|
|
||||||
lobby.game_state = GameState::Deal;
|
|
||||||
ctx.db.lobby().id().update(lobby);
|
|
||||||
|
|
||||||
deal_hands(ctx, lobby_id);
|
|
||||||
lobby.game_state = GameState::Play;
|
|
||||||
ctx.db.lobby().id().update(lobby);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_shuffled_wall(ctx: &ReducerContext) -> Vec<Tile> {
|
|
||||||
let mut rng = ctx.rng();
|
|
||||||
let mut wall = tiles();
|
|
||||||
wall.shuffle(&mut rng);
|
|
||||||
|
|
||||||
wall
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deal_hands(ctx: &ReducerContext, lobby_id: u32) {
|
|
||||||
let players = ctx.db.player().lobby_id().filter(lobby_id);
|
|
||||||
let bots = ctx.db.bot().lobby_id().filter(lobby_id);
|
|
||||||
|
|
||||||
let mut wall = ctx.db.wall().lobby_id().find(lobby_id).unwrap();
|
|
||||||
|
|
||||||
// FIXME rectify deal orders
|
|
||||||
for player in players {
|
|
||||||
let tiles = wall.tiles.split_off(wall.tiles.len() - 13);
|
|
||||||
wall = ctx.db.wall().lobby_id().update(wall);
|
|
||||||
ctx.db.hand().insert(Hand {
|
|
||||||
player_identity: player.identity,
|
|
||||||
tiles,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for bot in bots {
|
|
||||||
let tiles = wall.tiles.split_off(wall.tiles.len() - 13);
|
|
||||||
wall = ctx.db.wall().lobby_id().update(wall);
|
|
||||||
ctx.db.bothand().insert(BotHand {
|
|
||||||
bot_id: bot.id,
|
|
||||||
tiles,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[view(name = view_player_hand, public)]
|
|
||||||
pub fn view_player_hand(ctx: &ViewContext) -> Option<Hand> {
|
|
||||||
ctx.db.hand().player_identity().find(ctx.sender)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[reducer]
|
|
||||||
pub fn sort_hand(ctx: &ReducerContext) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[reducer(init)]
|
// #[reducer(init)]
|
||||||
// pub fn init(_ctx: &ReducerContext) {
|
// pub fn init(_ctx: &ReducerContext) {
|
||||||
// // Called when the module is initially published
|
// // Called when the module is initially published
|
||||||
|
|
|
||||||
84
spacetimedb/src/tables.rs
Normal file
84
spacetimedb/src/tables.rs
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
use spacetimedb::{Identity, 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 hand_id: u32,
|
||||||
|
pub pond_id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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)]
|
||||||
|
pub struct Lobby {
|
||||||
|
#[primary_key]
|
||||||
|
#[auto_inc]
|
||||||
|
pub id: u32,
|
||||||
|
|
||||||
|
#[unique]
|
||||||
|
pub host_player_id: u32,
|
||||||
|
pub players: Vec<PlayerOrBot>,
|
||||||
|
|
||||||
|
pub game_state: GameState,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[table(name = wall)]
|
||||||
|
pub struct Wall {
|
||||||
|
#[primary_key]
|
||||||
|
pub lobby_id: u32,
|
||||||
|
|
||||||
|
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>,
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue