Compare commits
11 commits
bcbaab6909
...
ce84478376
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce84478376 | ||
|
|
9f6a5b6423 | ||
|
|
d0c79377aa | ||
|
|
6cd10329df | ||
|
|
78c199b61e | ||
|
|
655123b055 | ||
|
|
004aafd4ba | ||
|
|
c86f8d93f1 | ||
|
|
d7d567b0e6 | ||
|
|
3ca8574a6e | ||
|
|
d52a1c4d8e |
62 changed files with 2528 additions and 926 deletions
17
.envrc
17
.envrc
|
|
@ -1,9 +1,12 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# the shebang is ignored, but nice for editors
|
|
||||||
|
|
||||||
if type -P lorri &>/dev/null; then
|
export DIRENV_WARN_TIMEOUT=20s
|
||||||
eval "$(lorri direnv)"
|
|
||||||
else
|
eval "$(devenv direnvrc)"
|
||||||
echo 'while direnv evaluated .envrc, could not find the command "lorri" [https://github.com/nix-community/lorri]'
|
|
||||||
use nix
|
# `use devenv` supports the same options as the `devenv shell` command.
|
||||||
fi
|
#
|
||||||
|
# To silence all output, use `--quiet`.
|
||||||
|
#
|
||||||
|
# Example usage: use devenv --quiet --impure --option services.postgres.enable:bool true
|
||||||
|
use devenv
|
||||||
|
|
|
||||||
11
.gitignore
vendored
11
.gitignore
vendored
|
|
@ -1 +1,12 @@
|
||||||
target
|
target
|
||||||
|
|
||||||
|
# Devenv
|
||||||
|
.devenv*
|
||||||
|
devenv.local.nix
|
||||||
|
devenv.local.yaml
|
||||||
|
|
||||||
|
# direnv
|
||||||
|
.direnv
|
||||||
|
|
||||||
|
# pre-commit
|
||||||
|
.pre-commit-config.yaml
|
||||||
|
|
|
||||||
195
Cargo.lock
generated
195
Cargo.lock
generated
|
|
@ -249,9 +249,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.100"
|
version = "1.0.101"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anymap"
|
name = "anymap"
|
||||||
|
|
@ -1229,7 +1229,6 @@ dependencies = [
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
"smol_str",
|
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1695,7 +1694,7 @@ dependencies = [
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
"cexpr",
|
"cexpr",
|
||||||
"clang-sys",
|
"clang-sys",
|
||||||
"itertools 0.13.0",
|
"itertools 0.12.1",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
|
|
@ -1839,9 +1838,9 @@ checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.24.0"
|
version = "1.25.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4"
|
checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck_derive",
|
"bytemuck_derive",
|
||||||
]
|
]
|
||||||
|
|
@ -1871,9 +1870,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.11.0"
|
version = "1.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
|
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytestring"
|
name = "bytestring"
|
||||||
|
|
@ -1922,9 +1921,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.53"
|
version = "1.2.55"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932"
|
checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"find-msvc-tools",
|
"find-msvc-tools",
|
||||||
"jobserver",
|
"jobserver",
|
||||||
|
|
@ -1984,9 +1983,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.54"
|
version = "4.5.57"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394"
|
checksum = "6899ea499e3fb9305a65d5ebf6e3d2248c5fab291f300ad0a704fbe142eae31a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
|
|
@ -1994,9 +1993,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.54"
|
version = "4.5.57"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00"
|
checksum = "7b12c8b680195a62a8364d16b8447b01b6c2c8f9aaf68bee653be34d4245e238"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
|
|
@ -2006,9 +2005,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "4.5.49"
|
version = "4.5.55"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671"
|
checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|
@ -2532,6 +2531,21 @@ dependencies = [
|
||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_aliases"
|
||||||
|
version = "0.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a42564b20fdeb062b38ad78d567d0479b2b318ff679b20895d9a1de3b6896002"
|
||||||
|
dependencies = [
|
||||||
|
"derive_aliases_proc_macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_aliases_proc_macro"
|
||||||
|
version = "0.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e81edf3b0f0a7d68f2113aee7cedffa73d1fadea46fc85e468786a7f7aac998c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_more"
|
name = "derive_more"
|
||||||
version = "0.99.20"
|
version = "0.99.20"
|
||||||
|
|
@ -2829,9 +2843,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "find-msvc-tools"
|
name = "find-msvc-tools"
|
||||||
version = "0.1.8"
|
version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db"
|
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "finl_unicode"
|
name = "finl_unicode"
|
||||||
|
|
@ -2853,9 +2867,9 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.1.8"
|
version = "1.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369"
|
checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
|
|
@ -3437,9 +3451,9 @@ checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.64"
|
version = "0.1.65"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
|
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android_system_properties",
|
"android_system_properties",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
|
|
@ -3681,15 +3695,6 @@ dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itertools"
|
|
||||||
version = "0.13.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
|
||||||
dependencies = [
|
|
||||||
"either",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
|
|
@ -3745,20 +3750,33 @@ dependencies = [
|
||||||
"bevy_ratatui",
|
"bevy_ratatui",
|
||||||
"bevy_spacetimedb",
|
"bevy_spacetimedb",
|
||||||
"clap",
|
"clap",
|
||||||
"jongline",
|
"jong-types",
|
||||||
"log",
|
"log",
|
||||||
"rand 0.9.2",
|
"rand 0.9.2",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
|
"spacetimedb",
|
||||||
|
"spacetimedb-sdk",
|
||||||
"strum 0.27.2",
|
"strum 0.27.2",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"tui-logger",
|
"tui-logger",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jong-types"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bevy",
|
||||||
|
"derive_aliases",
|
||||||
|
"spacetimedb",
|
||||||
|
"strum 0.27.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jongline"
|
name = "jongline"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"jong-types",
|
||||||
"log",
|
"log",
|
||||||
"spacetimedb",
|
"spacetimedb",
|
||||||
]
|
]
|
||||||
|
|
@ -3860,9 +3878,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
version = "0.2.15"
|
version = "0.2.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
|
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libredox"
|
name = "libredox"
|
||||||
|
|
@ -3981,9 +3999,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.6"
|
version = "2.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memmap2"
|
name = "memmap2"
|
||||||
|
|
@ -4243,9 +4261,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-conv"
|
name = "num-conv"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-derive"
|
name = "num-derive"
|
||||||
|
|
@ -4666,15 +4684,6 @@ dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ordered-float"
|
|
||||||
version = "5.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e2c1f9f56e534ac6a9b8a4600bdf0f530fb393b5f393e7b4d03489c3cf0c3f01"
|
|
||||||
dependencies = [
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "owned_ttf_parser"
|
name = "owned_ttf_parser"
|
||||||
version = "0.25.1"
|
version = "0.25.1"
|
||||||
|
|
@ -4733,9 +4742,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest"
|
name = "pest"
|
||||||
version = "2.8.5"
|
version = "2.8.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7"
|
checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
"ucd-trie",
|
"ucd-trie",
|
||||||
|
|
@ -4743,9 +4752,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest_derive"
|
name = "pest_derive"
|
||||||
version = "2.8.5"
|
version = "2.8.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68f9dbced329c441fa79d80472764b1a2c7e57123553b8519b36663a2fb234ed"
|
checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pest",
|
"pest",
|
||||||
"pest_generator",
|
"pest_generator",
|
||||||
|
|
@ -4753,9 +4762,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest_generator"
|
name = "pest_generator"
|
||||||
version = "2.8.5"
|
version = "2.8.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3bb96d5051a78f44f43c8f712d8e810adb0ebf923fc9ed2655a7f66f63ba8ee5"
|
checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pest",
|
"pest",
|
||||||
"pest_meta",
|
"pest_meta",
|
||||||
|
|
@ -4766,9 +4775,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest_meta"
|
name = "pest_meta"
|
||||||
version = "2.8.5"
|
version = "2.8.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "602113b5b5e8621770cfd490cfd90b9f84ab29bd2b0e49ad83eb6d186cef2365"
|
checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pest",
|
"pest",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
|
@ -4917,15 +4926,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "portable-atomic"
|
name = "portable-atomic"
|
||||||
version = "1.13.0"
|
version = "1.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950"
|
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "portable-atomic-util"
|
name = "portable-atomic-util"
|
||||||
version = "0.2.4"
|
version = "0.2.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
|
checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
]
|
]
|
||||||
|
|
@ -5310,9 +5319,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.12.2"
|
version = "1.12.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
|
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
|
@ -5322,9 +5331,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.4.13"
|
version = "0.4.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
|
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
|
@ -5333,9 +5342,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.8.8"
|
version = "0.8.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
|
checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "renderdoc-sys"
|
name = "renderdoc-sys"
|
||||||
|
|
@ -5495,9 +5504,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "schemars"
|
name = "schemars"
|
||||||
version = "1.2.0"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "54e910108742c57a770f492731f99be216a52fadd361b06c8fb59d74ccc267d2"
|
checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
"ref-cast",
|
"ref-cast",
|
||||||
|
|
@ -5632,7 +5641,7 @@ dependencies = [
|
||||||
"indexmap 1.9.3",
|
"indexmap 1.9.3",
|
||||||
"indexmap 2.13.0",
|
"indexmap 2.13.0",
|
||||||
"schemars 0.9.0",
|
"schemars 0.9.0",
|
||||||
"schemars 1.2.0",
|
"schemars 1.2.1",
|
||||||
"serde_core",
|
"serde_core",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with_macros",
|
"serde_with_macros",
|
||||||
|
|
@ -5737,9 +5746,9 @@ checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "siphasher"
|
name = "siphasher"
|
||||||
version = "1.0.1"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "skrifa"
|
name = "skrifa"
|
||||||
|
|
@ -5753,9 +5762,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.11"
|
version = "0.4.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
|
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slotmap"
|
name = "slotmap"
|
||||||
|
|
@ -5808,9 +5817,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.6.1"
|
version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
|
checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.60.2",
|
"windows-sys 0.60.2",
|
||||||
|
|
@ -6248,7 +6257,7 @@ dependencies = [
|
||||||
"nix 0.29.0",
|
"nix 0.29.0",
|
||||||
"num-derive",
|
"num-derive",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"ordered-float 4.6.0",
|
"ordered-float",
|
||||||
"pest",
|
"pest",
|
||||||
"pest_derive",
|
"pest_derive",
|
||||||
"phf",
|
"phf",
|
||||||
|
|
@ -6320,9 +6329,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.45"
|
version = "0.3.47"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd"
|
checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deranged",
|
"deranged",
|
||||||
"itoa",
|
"itoa",
|
||||||
|
|
@ -6337,15 +6346,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time-core"
|
name = "time-core"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca"
|
checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time-macros"
|
name = "time-macros"
|
||||||
version = "0.2.25"
|
version = "0.2.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd"
|
checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-conv",
|
"num-conv",
|
||||||
"time-core",
|
"time-core",
|
||||||
|
|
@ -6722,9 +6731,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.2.2"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
|
|
@ -6764,9 +6773,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.19.0"
|
version = "1.20.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a"
|
checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atomic",
|
"atomic",
|
||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
|
|
@ -7073,7 +7082,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f2ab60e120fd6eaa68d9567f3226e876684639d22a4219b313ff69ec0ccd5ac"
|
checksum = "5f2ab60e120fd6eaa68d9567f3226e876684639d22a4219b313ff69ec0ccd5ac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ordered-float 4.6.0",
|
"ordered-float",
|
||||||
"strsim",
|
"strsim",
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
"wezterm-dynamic-derive",
|
"wezterm-dynamic-derive",
|
||||||
|
|
@ -7219,7 +7228,7 @@ dependencies = [
|
||||||
"naga",
|
"naga",
|
||||||
"ndk-sys 0.6.0+11769913",
|
"ndk-sys 0.6.0+11769913",
|
||||||
"objc",
|
"objc",
|
||||||
"ordered-float 5.0.0",
|
"ordered-float",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
"portable-atomic-util",
|
"portable-atomic-util",
|
||||||
|
|
@ -7978,18 +7987,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.8.33"
|
version = "0.8.39"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd"
|
checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy-derive",
|
"zerocopy-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy-derive"
|
name = "zerocopy-derive"
|
||||||
version = "0.8.33"
|
version = "0.8.39"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1"
|
checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -8052,6 +8061,6 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zmij"
|
name = "zmij"
|
||||||
version = "1.0.16"
|
version = "1.0.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dfcd145825aace48cff44a8844de64bf75feec3080e0aa5cdbde72961ae51a65"
|
checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445"
|
||||||
|
|
|
||||||
30
Cargo.toml
30
Cargo.toml
|
|
@ -1,9 +1,37 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
members = ["jong", "jongline"]
|
members = ["jong", "jong-types", "spacetimedb"]
|
||||||
|
|
||||||
|
[workspace.dependencies]
|
||||||
|
jong = { version = "0.1.0", path = "jong" }
|
||||||
|
jong-types = { version = "0.1.0", path = "jong-types" }
|
||||||
|
|
||||||
|
bevy.version = "0.17.3"
|
||||||
|
bevy.default-features = false
|
||||||
|
|
||||||
|
bevy_ratatui = "0.10.0"
|
||||||
|
bevy_spacetimedb = "0.7"
|
||||||
|
|
||||||
|
spacetimedb = "1.11.*"
|
||||||
|
spacetimedb-sdk = "1.11.*"
|
||||||
|
|
||||||
|
strum.version = "0.27.2"
|
||||||
|
strum.features = ["derive"]
|
||||||
|
|
||||||
|
clap = "4.5.54"
|
||||||
|
log = "0.4.29"
|
||||||
|
rand = "0.9.2"
|
||||||
|
ratatui = "0.30.0"
|
||||||
|
tracing = "0.1.44"
|
||||||
|
tracing-subscriber = "0.3.22"
|
||||||
|
tui-logger = "0.18.0"
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 1
|
opt-level = 1
|
||||||
|
|
||||||
[profile.dev.package."*"]
|
[profile.dev.package."*"]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
bevy_ratatui = { path = "/home/tao/clones/bevy_ratatui" }
|
||||||
|
# bevy_spacetimedb = { path = "/home/tao/clones/bevy_spacetimedb/bevy_spacetimedb" }
|
||||||
|
|
|
||||||
143
devenv.lock
Normal file
143
devenv.lock
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"devenv": {
|
||||||
|
"locked": {
|
||||||
|
"dir": "src/modules",
|
||||||
|
"lastModified": 1770666213,
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "devenv",
|
||||||
|
"rev": "d4ffee46c9088df6e000470b998a2d2c16517f62",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"dir": "src/modules",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "devenv",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-compat": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1767039857,
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"git-hooks": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"gitignore": "gitignore",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1769939035,
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"rev": "a8ca480175326551d6c4121498316261cbb5b260",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gitignore": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"git-hooks",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1762808025,
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "gitignore.nix",
|
||||||
|
"rev": "cb5e3fdca1de58ccbc3ef53de65bd372b48f567c",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "gitignore.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-src": "nixpkgs-src"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1770434727,
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "devenv-nixpkgs",
|
||||||
|
"rev": "8430f16a39c27bdeef236f1eeb56f0b51b33d348",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"ref": "rolling",
|
||||||
|
"repo": "devenv-nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-src": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1769922788,
|
||||||
|
"narHash": "sha256-H3AfG4ObMDTkTJYkd8cz1/RbY9LatN5Mk4UF48VuSXc=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "207d15f1a6603226e1e223dc79ac29c7846da32e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"devenv": "devenv",
|
||||||
|
"git-hooks": "git-hooks",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"pre-commit-hooks": [
|
||||||
|
"git-hooks"
|
||||||
|
],
|
||||||
|
"rust-overlay": "rust-overlay"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-overlay": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1770606655,
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"rev": "11a396520bf911e4ed01e78e11633d3fc63b350e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
68
devenv.nix
Normal file
68
devenv.nix
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: 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/
|
||||||
|
packages = with pkgs; [
|
||||||
|
# process-compose
|
||||||
|
pkg-config
|
||||||
|
|
||||||
|
# spacetimedb
|
||||||
|
openssl
|
||||||
|
binaryen
|
||||||
|
spacetimedb
|
||||||
|
|
||||||
|
# bevy Linux
|
||||||
|
# Audio (Linux only)
|
||||||
|
alsa-lib
|
||||||
|
# Cross Platform 3D Graphics API
|
||||||
|
vulkan-loader
|
||||||
|
# For debugging around vulkan
|
||||||
|
vulkan-tools
|
||||||
|
# Other dependencies
|
||||||
|
libudev-zero
|
||||||
|
xorg.libX11
|
||||||
|
xorg.libXcursor
|
||||||
|
xorg.libXi
|
||||||
|
xorg.libXrandr
|
||||||
|
libxkbcommon
|
||||||
|
wayland
|
||||||
|
];
|
||||||
|
env.LD_LIBRARY_PATH = lib.makeLibraryPath packages;
|
||||||
|
env.RUST_LOG = "jong=trace";
|
||||||
|
|
||||||
|
# https://devenv.sh/languages/
|
||||||
|
languages.rust = {
|
||||||
|
enable = true;
|
||||||
|
channel = "nightly";
|
||||||
|
version = "latest";
|
||||||
|
targets = ["x86_64-unknown-linux-gnu" "wasm32-unknown-unknown"];
|
||||||
|
components = ["rust-src" "rust-docs" "rustc-codegen-cranelift" "rust-analyzer" "rustfmt"];
|
||||||
|
};
|
||||||
|
|
||||||
|
process.manager.implementation = "mprocs";
|
||||||
|
process.managers.mprocs.settings = {
|
||||||
|
server = "127.0.0.1:4050";
|
||||||
|
};
|
||||||
|
|
||||||
|
# https://devenv.sh/services/
|
||||||
|
# https://devenv.sh/scripts/
|
||||||
|
# https://devenv.sh/basics/
|
||||||
|
# https://devenv.sh/tasks/
|
||||||
|
# https://devenv.sh/tests/
|
||||||
|
# https://devenv.sh/git-hooks/
|
||||||
|
# See full reference at https://devenv.sh/reference/options/
|
||||||
|
}
|
||||||
9
devenv.yaml
Normal file
9
devenv.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
allowUnfree: true
|
||||||
|
inputs:
|
||||||
|
nixpkgs:
|
||||||
|
url: github:cachix/devenv-nixpkgs/rolling
|
||||||
|
rust-overlay:
|
||||||
|
url: github:oxalica/rust-overlay
|
||||||
|
inputs:
|
||||||
|
nixpkgs:
|
||||||
|
follows: nixpkgs
|
||||||
12
flake.lock
generated
12
flake.lock
generated
|
|
@ -20,11 +20,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1768564909,
|
"lastModified": 1770197578,
|
||||||
"narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=",
|
"narHash": "sha256-AYqlWrX09+HvGs8zM6ebZ1pwUqjkfpnv8mewYwAo+iM=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f",
|
"rev": "00c21e4c93d963c50d4c0c89bfa84ed6e0694df2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -62,11 +62,11 @@
|
||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1768617670,
|
"lastModified": 1770433312,
|
||||||
"narHash": "sha256-Z3+6dxoWZn+QFwjxAt5ZGXkiuCvCLgQP6pTS5eSWXqk=",
|
"narHash": "sha256-IaiqGwmLBrR0z67t/oaS6GIFxv9V8mDY7dBTuYVTbKY=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "56d0fbdd732f3686e8414b857cf885038fc17d57",
|
"rev": "9922ff9f99a6436756cbe6f5d11f9c3630e58cf0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
21
flake.nix
21
flake.nix
|
|
@ -21,7 +21,13 @@
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
devShells.default = with pkgs;
|
devShells.default = with pkgs;
|
||||||
mkShell {
|
mkShell rec {
|
||||||
|
nativeBuildInputs = [
|
||||||
|
pkg-config
|
||||||
|
# spacetimedb
|
||||||
|
openssl
|
||||||
|
binaryen
|
||||||
|
];
|
||||||
buildInputs =
|
buildInputs =
|
||||||
[
|
[
|
||||||
# Rust dependencies
|
# Rust dependencies
|
||||||
|
|
@ -29,7 +35,6 @@
|
||||||
extensions = ["rust-src" "rust-docs" "rustc-codegen-cranelift" "rust-analyzer" "rustfmt"];
|
extensions = ["rust-src" "rust-docs" "rustc-codegen-cranelift" "rust-analyzer" "rustfmt"];
|
||||||
targets = ["x86_64-unknown-linux-gnu" "wasm32-unknown-unknown"];
|
targets = ["x86_64-unknown-linux-gnu" "wasm32-unknown-unknown"];
|
||||||
})
|
})
|
||||||
pkg-config
|
|
||||||
]
|
]
|
||||||
++ lib.optionals (lib.strings.hasInfix "linux" system) [
|
++ lib.optionals (lib.strings.hasInfix "linux" system) [
|
||||||
# for Linux
|
# for Linux
|
||||||
|
|
@ -47,19 +52,9 @@
|
||||||
xorg.libXrandr
|
xorg.libXrandr
|
||||||
libxkbcommon
|
libxkbcommon
|
||||||
wayland
|
wayland
|
||||||
|
|
||||||
# spacetimedb
|
|
||||||
openssl
|
|
||||||
binaryen
|
|
||||||
];
|
];
|
||||||
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
|
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
|
||||||
LD_LIBRARY_PATH = lib.makeLibraryPath [
|
LD_LIBRARY_PATH = lib.makeLibraryPath buildInputs;
|
||||||
vulkan-loader
|
|
||||||
xorg.libX11
|
|
||||||
xorg.libXi
|
|
||||||
xorg.libXcursor
|
|
||||||
libxkbcommon
|
|
||||||
];
|
|
||||||
RUST_LOG = "jong=trace";
|
RUST_LOG = "jong=trace";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
jong-types/Cargo.toml
Normal file
13
jong-types/Cargo.toml
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "jong-types"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bevy.workspace = true
|
||||||
|
bevy.features = ["bevy_state"]
|
||||||
|
derive_aliases = "0.4.7"
|
||||||
|
spacetimedb.workspace = true
|
||||||
|
strum.workspace = true
|
||||||
2
jong-types/rustfmt.toml
Normal file
2
jong-types/rustfmt.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
unstable_features = true
|
||||||
|
merge_derives = false
|
||||||
114
jong-types/src/lib.rs
Normal file
114
jong-types/src/lib.rs
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
mod derive_alias {
|
||||||
|
derive_aliases::define! {
|
||||||
|
Copy = ::core::clone::Clone, ::core::marker::Copy;
|
||||||
|
Eq = ::core::cmp::PartialEq, ::core::cmp::Eq;
|
||||||
|
Ord = ..Eq, ::core::cmp::PartialOrd, ::core::cmp::PartialEq, ::core::cmp::Ord;
|
||||||
|
|
||||||
|
Base = ::core::fmt::Debug, ..Copy, ..Ord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
use derive_aliases::derive;
|
||||||
|
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use spacetimedb::SpacetimeType;
|
||||||
|
use strum::FromRepr;
|
||||||
|
|
||||||
|
#[derive(..Base, Hash, Default)]
|
||||||
|
#[derive(States, SpacetimeType)]
|
||||||
|
pub enum GameState {
|
||||||
|
#[default]
|
||||||
|
None,
|
||||||
|
Setup,
|
||||||
|
Deal,
|
||||||
|
Play,
|
||||||
|
Exit,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(..Base)]
|
||||||
|
#[derive(Component, SpacetimeType)]
|
||||||
|
pub struct Tile {
|
||||||
|
pub suit: Suit,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(..Base)]
|
||||||
|
#[derive(SpacetimeType)]
|
||||||
|
pub enum Suit {
|
||||||
|
Man(Rank),
|
||||||
|
Pin(Rank),
|
||||||
|
Sou(Rank),
|
||||||
|
Wind(Wind),
|
||||||
|
Dragon(Dragon),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Suit {
|
||||||
|
pub fn rank(&self) -> Option<Rank> {
|
||||||
|
match self {
|
||||||
|
Suit::Man(rank) => Some(*rank),
|
||||||
|
Suit::Pin(rank) => Some(*rank),
|
||||||
|
Suit::Sou(rank) => Some(*rank),
|
||||||
|
// Suit::Wind(wind) | Suit::Dragon(dragon) => None,
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
..Base,
|
||||||
|
Deref,
|
||||||
|
DerefMut,
|
||||||
|
)]
|
||||||
|
#[derive(SpacetimeType)]
|
||||||
|
pub struct Rank {
|
||||||
|
pub number: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
..Base,
|
||||||
|
FromRepr,
|
||||||
|
)]
|
||||||
|
#[derive(SpacetimeType)]
|
||||||
|
pub enum Wind {
|
||||||
|
Ton,
|
||||||
|
Nan,
|
||||||
|
Shaa,
|
||||||
|
Pei,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
..Base,
|
||||||
|
FromRepr,
|
||||||
|
)]
|
||||||
|
#[derive(SpacetimeType)]
|
||||||
|
pub enum Dragon {
|
||||||
|
Haku,
|
||||||
|
Hatsu,
|
||||||
|
Chun,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tiles() -> Vec<Tile> {
|
||||||
|
let mut tiles = vec![];
|
||||||
|
for _ in 0..4 {
|
||||||
|
for i in 1..=9 {
|
||||||
|
tiles.push(Tile {
|
||||||
|
suit: Suit::Pin(Rank { number: i }),
|
||||||
|
});
|
||||||
|
tiles.push(Tile {
|
||||||
|
suit: Suit::Sou(Rank { number: i }),
|
||||||
|
});
|
||||||
|
tiles.push(Tile {
|
||||||
|
suit: Suit::Man(Rank { number: i }),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for i in 0..4 {
|
||||||
|
tiles.push(Tile {
|
||||||
|
suit: Suit::Wind(Wind::from_repr(i).unwrap()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for i in 0..3 {
|
||||||
|
tiles.push(Tile {
|
||||||
|
suit: Suit::Dragon(Dragon::from_repr(i).unwrap()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tiles
|
||||||
|
}
|
||||||
|
|
@ -10,19 +10,21 @@ readme = false
|
||||||
[lib]
|
[lib]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = { version = "0.17.3", features = ["dynamic_linking"] }
|
jong-types.workspace = true
|
||||||
# bevy_ratatui = { git = "https://github.com/kenianbei/bevy_ratatui.git", rev = "e4b022308e08ab360ef89eca8e9f8b1c969e9a56" }
|
|
||||||
bevy_ratatui = { path = "/home/tao/clones/bevy_ratatui" }
|
bevy = { workspace = true, features = ["default", "dynamic_linking"] }
|
||||||
bevy_spacetimedb = "0.7"
|
bevy_ratatui.workspace = true
|
||||||
clap = { version = "4.5.54", features = ["derive"] }
|
bevy_spacetimedb.workspace = true
|
||||||
jongline = { version = "0.1.0", path = "../jongline" }
|
clap = { workspace = true, features = ["derive"] }
|
||||||
log = { version = "0.4.29", features = [
|
log = { workspace = true, features = [
|
||||||
"release_max_level_error",
|
"release_max_level_error",
|
||||||
"max_level_trace",
|
"max_level_trace",
|
||||||
] }
|
] }
|
||||||
rand = "0.9.2"
|
rand.workspace = true
|
||||||
ratatui = "0.30.0"
|
ratatui.workspace = true
|
||||||
strum = { version = "0.27.2", features = ["derive"] }
|
spacetimedb-sdk.workspace = true
|
||||||
tracing = "0.1.44"
|
spacetimedb.workspace = true
|
||||||
tracing-subscriber = "0.3.22"
|
strum.workspace = true
|
||||||
tui-logger = { version = "0.18.0", features = ["tracing-support", "crossterm"] }
|
tracing.workspace = true
|
||||||
|
tracing-subscriber.workspace = true
|
||||||
|
tui-logger = { workspace = true, features = ["tracing-support", "crossterm"] }
|
||||||
|
|
|
||||||
225
jong/src/game.rs
225
jong/src/game.rs
|
|
@ -1,5 +1,21 @@
|
||||||
use bevy::prelude::*;
|
#![allow(unused)]
|
||||||
|
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy_spacetimedb::{
|
||||||
|
ReadInsertUpdateMessage, ReadStdbConnectedMessage, ReadStdbDisconnectedMessage, StdbPlugin,
|
||||||
|
TableMessages,
|
||||||
|
};
|
||||||
|
use spacetimedb::Identity;
|
||||||
|
use spacetimedb_sdk::{DbContext, Table, credentials};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
SpacetimeDB, creds_store, game,
|
||||||
|
stdb::{
|
||||||
|
self, DbConnection, HandTableAccess, LobbyTableAccess, PlayerTableAccess, RemoteTables,
|
||||||
|
ViewPlayerHandTableAccess, add_bot, join_or_create_lobby, login_or_add_player,
|
||||||
|
shuffle_deal,
|
||||||
|
},
|
||||||
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
game::{
|
game::{
|
||||||
hand::{Hand, Pond},
|
hand::{Hand, Pond},
|
||||||
|
|
@ -9,21 +25,13 @@ use crate::{
|
||||||
},
|
},
|
||||||
tile::{self},
|
tile::{self},
|
||||||
};
|
};
|
||||||
|
use jong_types::*;
|
||||||
|
|
||||||
pub mod hand;
|
pub mod hand;
|
||||||
pub mod player;
|
pub mod player;
|
||||||
pub mod round;
|
pub mod round;
|
||||||
pub mod wall;
|
pub mod wall;
|
||||||
|
|
||||||
#[derive(States, Default, Hash, Clone, Eq, Debug, PartialEq, Copy)]
|
|
||||||
pub enum GameState {
|
|
||||||
#[default]
|
|
||||||
None,
|
|
||||||
Setup,
|
|
||||||
Deal,
|
|
||||||
Play,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Message)]
|
#[derive(Message)]
|
||||||
pub enum GameMessage {
|
pub enum GameMessage {
|
||||||
Discarded(Entity),
|
Discarded(Entity),
|
||||||
|
|
@ -31,71 +39,170 @@ pub enum GameMessage {
|
||||||
Called { player: Entity, calltype: Entity },
|
Called { player: Entity, calltype: Entity },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameMessage {
|
|
||||||
pub(crate) fn is_called(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
GameMessage::Called { .. } => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Riichi;
|
pub struct Riichi;
|
||||||
impl Plugin for Riichi {
|
impl Plugin for Riichi {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app
|
let mut plugins = StdbPlugin::default()
|
||||||
// start stopper
|
.with_uri("http://localhost:3000")
|
||||||
|
.with_module_name("jongline")
|
||||||
|
.with_run_fn(DbConnection::run_threaded)
|
||||||
|
|
||||||
|
// TODO do these need to be subscription & vice-versa?
|
||||||
|
.add_table(RemoteTables::player)
|
||||||
|
.add_table(RemoteTables::lobby)
|
||||||
|
.add_table(RemoteTables::hand)
|
||||||
|
|
||||||
|
// semicolon stopper
|
||||||
|
;
|
||||||
|
let plugins =
|
||||||
|
if let Some(token) = creds_store().load().expect("i/o error loading credentials") {
|
||||||
|
// FIXME patch plugin so this takes Option?
|
||||||
|
plugins.with_token(&token)
|
||||||
|
} else {
|
||||||
|
plugins
|
||||||
|
};
|
||||||
|
|
||||||
|
app.add_plugins(plugins)
|
||||||
.init_state::<GameState>()
|
.init_state::<GameState>()
|
||||||
.add_sub_state::<TurnState>()
|
// .add_sub_state::<TurnState>()
|
||||||
.init_resource::<round::MatchSettings>()
|
// .init_resource::<round::MatchSettings>()
|
||||||
.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(Update, hand::sort_hands.run_if(in_state(GameState::Play)))
|
||||||
.add_systems(OnEnter(GameState::Deal), hand::shuffle_deal)
|
// .add_systems(OnEnter(TurnState::Tsumo), round::tsumo)
|
||||||
.add_systems(Update, hand::sort_hands.run_if(in_state(GameState::Play)))
|
// .add_systems(OnEnter(TurnState::Menzen), round::menzen)
|
||||||
.add_systems(OnEnter(TurnState::Tsumo), round::tsumo)
|
// .add_systems(Update, round::riichi_kan.run_if(in_state(TurnState::RiichiKan)))
|
||||||
.add_systems(OnEnter(TurnState::Menzen), round::menzen)
|
// .add_systems(Update, round::discard.run_if(in_state(TurnState::Discard)))
|
||||||
.add_systems(Update, round::riichi_kan.run_if(in_state(TurnState::RiichiKan)))
|
// .add_systems(OnEnter(TurnState::RonChiiPonKan), round::notify_callable)
|
||||||
.add_systems(Update, round::discard.run_if(in_state(TurnState::Discard)))
|
// .add_systems(Update, round::ron_chi_pon_kan.run_if(in_state(TurnState::RonChiiPonKan)).after(round::notify_callable))
|
||||||
.add_systems(OnEnter(TurnState::RonChiiPonKan), round::notify_callable)
|
// .add_systems(OnEnter(TurnState::End), round::end)
|
||||||
.add_systems(Update, round::ron_chi_pon_kan.run_if(in_state(TurnState::RonChiiPonKan)).after(round::notify_callable))
|
// stdb
|
||||||
.add_systems(OnEnter(TurnState::End), round::end)
|
.add_systems(Startup, sub_to_all)
|
||||||
|
.add_systems(Update, on_connect)
|
||||||
|
.add_systems(Update, on_disconnect)
|
||||||
|
.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(Update, view_hand.run_if(in_state(GameState::Play)))
|
||||||
|
// .add_systems(Update, (view_hand).run_if(in_state(GameState::Play)))
|
||||||
// semicolon stopper
|
// semicolon stopper
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn setup(
|
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) {
|
||||||
|
stdb.subscription_builder()
|
||||||
|
.on_applied(|_| trace!("made all subs!"))
|
||||||
|
.on_error(|_, err| error!("sub failed: {err}"))
|
||||||
|
.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(),
|
||||||
|
]);
|
||||||
|
// .subscribe_to_all_tables();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage, mut commands: Commands) {
|
||||||
|
for msg in messages.read() {
|
||||||
|
info!("you're now jongline");
|
||||||
|
debug!("with identity: {}", stdb.identity());
|
||||||
|
creds_store()
|
||||||
|
.save(&msg.access_token)
|
||||||
|
.expect("i/o error saving token");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO how reconnect?
|
||||||
|
fn on_disconnect(stdb: SpacetimeDB, mut messages: ReadStdbDisconnectedMessage) {
|
||||||
|
for msg in messages.read() {
|
||||||
|
warn!("lost connection: {:#?}", msg.err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Resource, Deref)]
|
||||||
|
struct Player(stdb::Player);
|
||||||
|
|
||||||
|
fn on_player_insert_update(
|
||||||
|
stdb: SpacetimeDB,
|
||||||
|
mut messages: ReadInsertUpdateMessage<stdb::Player>,
|
||||||
|
|
||||||
|
mut commands: Commands,
|
||||||
|
) {
|
||||||
|
for msg in messages.read() {
|
||||||
|
debug!("player_insert_update msg:\n{:#?}", msg.new);
|
||||||
|
commands.insert_resource(Player(msg.new.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join_or_create_lobby(stdb: SpacetimeDB, player: Res<Player>) {
|
||||||
|
let mut player = player.clone();
|
||||||
|
|
||||||
|
if player.lobby_id == 0 {
|
||||||
|
stdb.reducers().join_or_create_lobby(0).unwrap();
|
||||||
|
} else {
|
||||||
|
info!("in lobby: {}", player.lobby_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_lobby_insert_update(
|
||||||
|
stdb: SpacetimeDB,
|
||||||
|
mut messages: ReadInsertUpdateMessage<stdb::Lobby>,
|
||||||
|
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
matchsettings: Res<round::MatchSettings>,
|
|
||||||
// mut compass: ResMut<Compass>
|
|
||||||
// tiles: Query<Entity, With<Tile>>,
|
|
||||||
mut next_gamestate: ResMut<NextState<GameState>>,
|
mut next_gamestate: ResMut<NextState<GameState>>,
|
||||||
) {
|
) {
|
||||||
for i in 1..=matchsettings.player_count {
|
for msg in messages.read() {
|
||||||
let player = player::Player {
|
trace!("on_lobby_insert_update msg:\n{:#?}", msg.new);
|
||||||
name: format!("Player {}", i),
|
|
||||||
};
|
|
||||||
let points = player::Points(matchsettings.starting_points);
|
|
||||||
|
|
||||||
let bundle = (
|
next_gamestate.set(msg.new.game_state.into());
|
||||||
player,
|
match msg.new.game_state {
|
||||||
points,
|
stdb::GameState::None => {
|
||||||
Hand,
|
trace!("game entered none");
|
||||||
Pond,
|
}
|
||||||
Wind::from_repr((i - 1) as usize).unwrap(),
|
stdb::GameState::Setup => {
|
||||||
);
|
trace!("game entered setup");
|
||||||
|
|
||||||
if i == 1 {
|
let player = stdb
|
||||||
let player = commands.spawn((bundle, MainPlayer, CurrentPlayer)).id();
|
.db()
|
||||||
// commands.insert_resource(CurrentPlayer(player));
|
.player()
|
||||||
} else {
|
.identity()
|
||||||
commands.spawn(bundle);
|
.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 {
|
||||||
|
trace!("no player but game in setup")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stdb::GameState::Deal => {
|
||||||
|
trace!("game entered deal");
|
||||||
|
}
|
||||||
|
stdb::GameState::Play => {
|
||||||
|
trace!("game entered play");
|
||||||
|
if let Some(hand) = stdb.db().view_player_hand().iter().next() {
|
||||||
|
let tiles = hand
|
||||||
|
.tiles
|
||||||
|
.iter()
|
||||||
|
.map(Into::into)
|
||||||
|
.map(|t: Tile| commands.spawn(t).id())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
commands.spawn(Hand).add_children(&tiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stdb::GameState::Exit => {
|
||||||
|
trace!("game enetered exit");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commands.spawn(Wall);
|
|
||||||
|
|
||||||
next_gamestate.set(GameState::Deal);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,8 @@ use std::mem::discriminant;
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::game::{GameState, player::Player, wall::Wall};
|
||||||
game::{GameState, player::Player, wall::Wall},
|
use jong_types::*;
|
||||||
tile::Tile,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Hand;
|
pub struct Hand;
|
||||||
|
|
@ -27,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
|
||||||
|
|
|
||||||
|
|
@ -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 CreatePlayerArgs {
|
|
||||||
pub username: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<CreatePlayerArgs> for super::Reducer {
|
|
||||||
fn from(args: CreatePlayerArgs) -> Self {
|
|
||||||
Self::CreatePlayer {
|
|
||||||
username: args.username,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::InModule for CreatePlayerArgs {
|
|
||||||
type Module = super::RemoteModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CreatePlayerCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the reducer `create_player`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteReducers`].
|
|
||||||
pub trait create_player {
|
|
||||||
/// Request that the remote module invoke the reducer `create_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_create_player`] callbacks.
|
|
||||||
fn create_player(&self, username: String) -> __sdk::Result<()>;
|
|
||||||
/// Register a callback to run whenever we are notified of an invocation of the reducer `create_player`.
|
|
||||||
///
|
|
||||||
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
|
|
||||||
/// to determine the reducer's status.
|
|
||||||
///
|
|
||||||
/// The returned [`CreatePlayerCallbackId`] can be passed to [`Self::remove_on_create_player`]
|
|
||||||
/// to cancel the callback.
|
|
||||||
fn on_create_player(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static,
|
|
||||||
) -> CreatePlayerCallbackId;
|
|
||||||
/// Cancel a callback previously registered by [`Self::on_create_player`],
|
|
||||||
/// causing it not to run in the future.
|
|
||||||
fn remove_on_create_player(&self, callback: CreatePlayerCallbackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl create_player for super::RemoteReducers {
|
|
||||||
fn create_player(&self, username: String) -> __sdk::Result<()> {
|
|
||||||
self.imp
|
|
||||||
.call_reducer("create_player", CreatePlayerArgs { username })
|
|
||||||
}
|
|
||||||
fn on_create_player(
|
|
||||||
&self,
|
|
||||||
mut callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static,
|
|
||||||
) -> CreatePlayerCallbackId {
|
|
||||||
CreatePlayerCallbackId(self.imp.on_reducer(
|
|
||||||
"create_player",
|
|
||||||
Box::new(move |ctx: &super::ReducerEventContext| {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
let super::ReducerEventContext {
|
|
||||||
event:
|
|
||||||
__sdk::ReducerEvent {
|
|
||||||
reducer: super::Reducer::CreatePlayer { username },
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} = ctx
|
|
||||||
else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
callback(ctx, username)
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
fn remove_on_create_player(&self, callback: CreatePlayerCallbackId) {
|
|
||||||
self.imp.remove_on_reducer("create_player", callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[doc(hidden)]
|
|
||||||
/// Extension trait for setting the call-flags for the reducer `create_player`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::SetReducerFlags`].
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
pub trait set_flags_for_create_player {
|
|
||||||
/// Set the call-reducer flags for the reducer `create_player` to `flags`.
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
fn create_player(&self, flags: __ws::CallReducerFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl set_flags_for_create_player for super::SetReducerFlags {
|
|
||||||
fn create_player(&self, flags: __ws::CallReducerFlags) {
|
|
||||||
self.imp.set_call_reducer_flags("create_player", flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,95 +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::drawn_type::Drawn;
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
/// Table handle for the table `drawn`.
|
|
||||||
///
|
|
||||||
/// Obtain a handle from the [`DrawnTableAccess::drawn`] method on [`super::RemoteTables`],
|
|
||||||
/// like `ctx.db.drawn()`.
|
|
||||||
///
|
|
||||||
/// Users are encouraged not to explicitly reference this type,
|
|
||||||
/// but to directly chain method calls,
|
|
||||||
/// like `ctx.db.drawn().on_insert(...)`.
|
|
||||||
pub struct DrawnTableHandle<'ctx> {
|
|
||||||
imp: __sdk::TableHandle<Drawn>,
|
|
||||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the table `drawn`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteTables`].
|
|
||||||
pub trait DrawnTableAccess {
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
/// Obtain a [`DrawnTableHandle`], which mediates access to the table `drawn`.
|
|
||||||
fn drawn(&self) -> DrawnTableHandle<'_>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DrawnTableAccess for super::RemoteTables {
|
|
||||||
fn drawn(&self) -> DrawnTableHandle<'_> {
|
|
||||||
DrawnTableHandle {
|
|
||||||
imp: self.imp.get_table::<Drawn>("drawn"),
|
|
||||||
ctx: std::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DrawnInsertCallbackId(__sdk::CallbackId);
|
|
||||||
pub struct DrawnDeleteCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
impl<'ctx> __sdk::Table for DrawnTableHandle<'ctx> {
|
|
||||||
type Row = Drawn;
|
|
||||||
type EventContext = super::EventContext;
|
|
||||||
|
|
||||||
fn count(&self) -> u64 {
|
|
||||||
self.imp.count()
|
|
||||||
}
|
|
||||||
fn iter(&self) -> impl Iterator<Item = Drawn> + '_ {
|
|
||||||
self.imp.iter()
|
|
||||||
}
|
|
||||||
|
|
||||||
type InsertCallbackId = DrawnInsertCallbackId;
|
|
||||||
|
|
||||||
fn on_insert(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> DrawnInsertCallbackId {
|
|
||||||
DrawnInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_insert(&self, callback: DrawnInsertCallbackId) {
|
|
||||||
self.imp.remove_on_insert(callback.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteCallbackId = DrawnDeleteCallbackId;
|
|
||||||
|
|
||||||
fn on_delete(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> DrawnDeleteCallbackId {
|
|
||||||
DrawnDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_delete(&self, callback: DrawnDeleteCallbackId) {
|
|
||||||
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::<Drawn>("drawn");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub(super) fn parse_table_update(
|
|
||||||
raw_updates: __ws::TableUpdate<__ws::BsatnFormat>,
|
|
||||||
) -> __sdk::Result<__sdk::TableUpdate<Drawn>> {
|
|
||||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
|
||||||
__sdk::InternalError::failed_parse("TableUpdate<Drawn>", "TableUpdate")
|
|
||||||
.with_cause(e)
|
|
||||||
.into()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,103 +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 IdentityDisconnectedArgs {}
|
|
||||||
|
|
||||||
impl From<IdentityDisconnectedArgs> for super::Reducer {
|
|
||||||
fn from(args: IdentityDisconnectedArgs) -> Self {
|
|
||||||
Self::IdentityDisconnected
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl __sdk::InModule for IdentityDisconnectedArgs {
|
|
||||||
type Module = super::RemoteModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct IdentityDisconnectedCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the reducer `identity_disconnected`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteReducers`].
|
|
||||||
pub trait identity_disconnected {
|
|
||||||
/// Request that the remote module invoke the reducer `identity_disconnected` 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_identity_disconnected`] callbacks.
|
|
||||||
fn identity_disconnected(&self) -> __sdk::Result<()>;
|
|
||||||
/// Register a callback to run whenever we are notified of an invocation of the reducer `identity_disconnected`.
|
|
||||||
///
|
|
||||||
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
|
|
||||||
/// to determine the reducer's status.
|
|
||||||
///
|
|
||||||
/// The returned [`IdentityDisconnectedCallbackId`] can be passed to [`Self::remove_on_identity_disconnected`]
|
|
||||||
/// to cancel the callback.
|
|
||||||
fn on_identity_disconnected(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
|
||||||
) -> IdentityDisconnectedCallbackId;
|
|
||||||
/// Cancel a callback previously registered by [`Self::on_identity_disconnected`],
|
|
||||||
/// causing it not to run in the future.
|
|
||||||
fn remove_on_identity_disconnected(&self, callback: IdentityDisconnectedCallbackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl identity_disconnected for super::RemoteReducers {
|
|
||||||
fn identity_disconnected(&self) -> __sdk::Result<()> {
|
|
||||||
self.imp
|
|
||||||
.call_reducer("identity_disconnected", IdentityDisconnectedArgs {})
|
|
||||||
}
|
|
||||||
fn on_identity_disconnected(
|
|
||||||
&self,
|
|
||||||
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
|
||||||
) -> IdentityDisconnectedCallbackId {
|
|
||||||
IdentityDisconnectedCallbackId(self.imp.on_reducer(
|
|
||||||
"identity_disconnected",
|
|
||||||
Box::new(move |ctx: &super::ReducerEventContext| {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
let super::ReducerEventContext {
|
|
||||||
event:
|
|
||||||
__sdk::ReducerEvent {
|
|
||||||
reducer: super::Reducer::IdentityDisconnected {},
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} = ctx
|
|
||||||
else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
callback(ctx)
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
fn remove_on_identity_disconnected(&self, callback: IdentityDisconnectedCallbackId) {
|
|
||||||
self.imp
|
|
||||||
.remove_on_reducer("identity_disconnected", callback.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[doc(hidden)]
|
|
||||||
/// Extension trait for setting the call-flags for the reducer `identity_disconnected`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::SetReducerFlags`].
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
pub trait set_flags_for_identity_disconnected {
|
|
||||||
/// Set the call-reducer flags for the reducer `identity_disconnected` to `flags`.
|
|
||||||
///
|
|
||||||
/// This type is currently unstable and may be removed without a major version bump.
|
|
||||||
fn identity_disconnected(&self, flags: __ws::CallReducerFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl set_flags_for_identity_disconnected for super::SetReducerFlags {
|
|
||||||
fn identity_disconnected(&self, flags: __ws::CallReducerFlags) {
|
|
||||||
self.imp
|
|
||||||
.set_call_reducer_flags("identity_disconnected", flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,97 +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::player_type::Player;
|
|
||||||
use super::table_type::Table;
|
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
|
||||||
|
|
||||||
/// Table handle for the table `table`.
|
|
||||||
///
|
|
||||||
/// Obtain a handle from the [`TableTableAccess::table`] method on [`super::RemoteTables`],
|
|
||||||
/// like `ctx.db.table()`.
|
|
||||||
///
|
|
||||||
/// Users are encouraged not to explicitly reference this type,
|
|
||||||
/// but to directly chain method calls,
|
|
||||||
/// like `ctx.db.table().on_insert(...)`.
|
|
||||||
pub struct TableTableHandle<'ctx> {
|
|
||||||
imp: __sdk::TableHandle<Table>,
|
|
||||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Extension trait for access to the table `table`.
|
|
||||||
///
|
|
||||||
/// Implemented for [`super::RemoteTables`].
|
|
||||||
pub trait TableTableAccess {
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
/// Obtain a [`TableTableHandle`], which mediates access to the table `table`.
|
|
||||||
fn table(&self) -> TableTableHandle<'_>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TableTableAccess for super::RemoteTables {
|
|
||||||
fn table(&self) -> TableTableHandle<'_> {
|
|
||||||
TableTableHandle {
|
|
||||||
imp: self.imp.get_table::<Table>("table"),
|
|
||||||
ctx: std::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TableInsertCallbackId(__sdk::CallbackId);
|
|
||||||
pub struct TableDeleteCallbackId(__sdk::CallbackId);
|
|
||||||
|
|
||||||
impl<'ctx> __sdk::Table for TableTableHandle<'ctx> {
|
|
||||||
type Row = Table;
|
|
||||||
type EventContext = super::EventContext;
|
|
||||||
|
|
||||||
fn count(&self) -> u64 {
|
|
||||||
self.imp.count()
|
|
||||||
}
|
|
||||||
fn iter(&self) -> impl Iterator<Item = Table> + '_ {
|
|
||||||
self.imp.iter()
|
|
||||||
}
|
|
||||||
|
|
||||||
type InsertCallbackId = TableInsertCallbackId;
|
|
||||||
|
|
||||||
fn on_insert(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> TableInsertCallbackId {
|
|
||||||
TableInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_insert(&self, callback: TableInsertCallbackId) {
|
|
||||||
self.imp.remove_on_insert(callback.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteCallbackId = TableDeleteCallbackId;
|
|
||||||
|
|
||||||
fn on_delete(
|
|
||||||
&self,
|
|
||||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
|
||||||
) -> TableDeleteCallbackId {
|
|
||||||
TableDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_on_delete(&self, callback: TableDeleteCallbackId) {
|
|
||||||
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::<Table>("table");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub(super) fn parse_table_update(
|
|
||||||
raw_updates: __ws::TableUpdate<__ws::BsatnFormat>,
|
|
||||||
) -> __sdk::Result<__sdk::TableUpdate<Table>> {
|
|
||||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
|
||||||
__sdk::InternalError::failed_parse("TableUpdate<Table>", "TableUpdate")
|
|
||||||
.with_cause(e)
|
|
||||||
.into()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -2,16 +2,72 @@
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_spacetimedb::StdbConnection;
|
use bevy_spacetimedb::StdbConnection;
|
||||||
|
use spacetimedb_sdk::credentials;
|
||||||
mod jongline_bindings;
|
|
||||||
use jongline_bindings::*;
|
|
||||||
|
|
||||||
pub mod game;
|
pub mod game;
|
||||||
pub mod tile;
|
pub mod tile;
|
||||||
pub mod yakus;
|
pub mod yakus;
|
||||||
|
|
||||||
|
mod stdb;
|
||||||
|
|
||||||
trait EnumNextCycle {
|
trait EnumNextCycle {
|
||||||
fn next(&self) -> Self;
|
fn next(&self) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type SpacetimeDb<'a> = Res<'a, StdbConnection<DbConnection>>;
|
pub type SpacetimeDB<'a> = Res<'a, StdbConnection<stdb::DbConnection>>;
|
||||||
|
|
||||||
|
fn creds_store() -> credentials::File {
|
||||||
|
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,5 +1,5 @@
|
||||||
use bevy::{log::LogPlugin, prelude::*};
|
use bevy::{log::LogPlugin, prelude::*};
|
||||||
use bevy_spacetimedb::{StdbConnection, StdbPlugin, TableMessages};
|
use bevy_spacetimedb::{StdbConnection, StdbPlugin};
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use tracing::Level;
|
use tracing::Level;
|
||||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
|
@ -47,14 +47,6 @@ fn main() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
app.add_plugins(
|
|
||||||
StdbPlugin::default()
|
|
||||||
.with_uri("http://localhost:3000")
|
|
||||||
.with_module_name("jongline")
|
|
||||||
.with_run_fn(DbConnection::run_threaded)
|
|
||||||
.add_partial_table(RemoteTables::players, TableMessages::no_update()),
|
|
||||||
);
|
|
||||||
|
|
||||||
app.add_plugins(jong::game::Riichi);
|
app.add_plugins(jong::game::Riichi);
|
||||||
|
|
||||||
app.run();
|
app.run();
|
||||||
|
|
|
||||||
104
jong/src/stdb/add_bot_reducer.rs
Normal file
104
jong/src/stdb/add_bot_reducer.rs
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
// 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 AddBotArgs {
|
||||||
|
pub lobby_id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AddBotArgs> for super::Reducer {
|
||||||
|
fn from(args: AddBotArgs) -> Self {
|
||||||
|
Self::AddBot {
|
||||||
|
lobby_id: args.lobby_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for AddBotArgs {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AddBotCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the reducer `add_bot`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteReducers`].
|
||||||
|
pub trait add_bot {
|
||||||
|
/// Request that the remote module invoke the reducer `add_bot` 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_bot`] callbacks.
|
||||||
|
fn add_bot(&self, lobby_id: u32) -> __sdk::Result<()>;
|
||||||
|
/// Register a callback to run whenever we are notified of an invocation of the reducer `add_bot`.
|
||||||
|
///
|
||||||
|
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
|
||||||
|
/// to determine the reducer's status.
|
||||||
|
///
|
||||||
|
/// The returned [`AddBotCallbackId`] can be passed to [`Self::remove_on_add_bot`]
|
||||||
|
/// to cancel the callback.
|
||||||
|
fn on_add_bot(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static,
|
||||||
|
) -> AddBotCallbackId;
|
||||||
|
/// Cancel a callback previously registered by [`Self::on_add_bot`],
|
||||||
|
/// causing it not to run in the future.
|
||||||
|
fn remove_on_add_bot(&self, callback: AddBotCallbackId);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl add_bot for super::RemoteReducers {
|
||||||
|
fn add_bot(&self, lobby_id: u32) -> __sdk::Result<()> {
|
||||||
|
self.imp.call_reducer("add_bot", AddBotArgs { lobby_id })
|
||||||
|
}
|
||||||
|
fn on_add_bot(
|
||||||
|
&self,
|
||||||
|
mut callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static,
|
||||||
|
) -> AddBotCallbackId {
|
||||||
|
AddBotCallbackId(self.imp.on_reducer(
|
||||||
|
"add_bot",
|
||||||
|
Box::new(move |ctx: &super::ReducerEventContext| {
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
let super::ReducerEventContext {
|
||||||
|
event:
|
||||||
|
__sdk::ReducerEvent {
|
||||||
|
reducer: super::Reducer::AddBot { lobby_id },
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} = ctx
|
||||||
|
else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
callback(ctx, lobby_id)
|
||||||
|
}),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
fn remove_on_add_bot(&self, callback: AddBotCallbackId) {
|
||||||
|
self.imp.remove_on_reducer("add_bot", callback.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[doc(hidden)]
|
||||||
|
/// Extension trait for setting the call-flags for the reducer `add_bot`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::SetReducerFlags`].
|
||||||
|
///
|
||||||
|
/// This type is currently unstable and may be removed without a major version bump.
|
||||||
|
pub trait set_flags_for_add_bot {
|
||||||
|
/// Set the call-reducer flags for the reducer `add_bot` to `flags`.
|
||||||
|
///
|
||||||
|
/// This type is currently unstable and may be removed without a major version bump.
|
||||||
|
fn add_bot(&self, flags: __ws::CallReducerFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl set_flags_for_add_bot for super::SetReducerFlags {
|
||||||
|
fn add_bot(&self, flags: __ws::CallReducerFlags) {
|
||||||
|
self.imp.set_call_reducer_flags("add_bot", flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
142
jong/src/stdb/bot_table.rs
Normal file
142
jong/src/stdb/bot_table.rs
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
// 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_type::Bot;
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
/// Table handle for the table `bot`.
|
||||||
|
///
|
||||||
|
/// Obtain a handle from the [`BotTableAccess::bot`] method on [`super::RemoteTables`],
|
||||||
|
/// like `ctx.db.bot()`.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.bot().on_insert(...)`.
|
||||||
|
pub struct BotTableHandle<'ctx> {
|
||||||
|
imp: __sdk::TableHandle<Bot>,
|
||||||
|
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the table `bot`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteTables`].
|
||||||
|
pub trait BotTableAccess {
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
/// Obtain a [`BotTableHandle`], which mediates access to the table `bot`.
|
||||||
|
fn bot(&self) -> BotTableHandle<'_>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BotTableAccess for super::RemoteTables {
|
||||||
|
fn bot(&self) -> BotTableHandle<'_> {
|
||||||
|
BotTableHandle {
|
||||||
|
imp: self.imp.get_table::<Bot>("bot"),
|
||||||
|
ctx: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BotInsertCallbackId(__sdk::CallbackId);
|
||||||
|
pub struct BotDeleteCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::Table for BotTableHandle<'ctx> {
|
||||||
|
type Row = Bot;
|
||||||
|
type EventContext = super::EventContext;
|
||||||
|
|
||||||
|
fn count(&self) -> u64 {
|
||||||
|
self.imp.count()
|
||||||
|
}
|
||||||
|
fn iter(&self) -> impl Iterator<Item = Bot> + '_ {
|
||||||
|
self.imp.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
type InsertCallbackId = BotInsertCallbackId;
|
||||||
|
|
||||||
|
fn on_insert(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||||
|
) -> BotInsertCallbackId {
|
||||||
|
BotInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_insert(&self, callback: BotInsertCallbackId) {
|
||||||
|
self.imp.remove_on_insert(callback.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteCallbackId = BotDeleteCallbackId;
|
||||||
|
|
||||||
|
fn on_delete(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||||
|
) -> BotDeleteCallbackId {
|
||||||
|
BotDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_delete(&self, callback: BotDeleteCallbackId) {
|
||||||
|
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::<Bot>("bot");
|
||||||
|
_table.add_unique_constraint::<u32>("id", |row| &row.id);
|
||||||
|
}
|
||||||
|
pub struct BotUpdateCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::TableWithPrimaryKey for BotTableHandle<'ctx> {
|
||||||
|
type UpdateCallbackId = BotUpdateCallbackId;
|
||||||
|
|
||||||
|
fn on_update(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||||
|
) -> BotUpdateCallbackId {
|
||||||
|
BotUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_update(&self, callback: BotUpdateCallbackId) {
|
||||||
|
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<Bot>> {
|
||||||
|
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||||
|
__sdk::InternalError::failed_parse("TableUpdate<Bot>", "TableUpdate")
|
||||||
|
.with_cause(e)
|
||||||
|
.into()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Access to the `id` unique index on the table `bot`,
|
||||||
|
/// which allows point queries on the field of the same name
|
||||||
|
/// via the [`BotIdUnique::find`] method.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.bot().id().find(...)`.
|
||||||
|
pub struct BotIdUnique<'ctx> {
|
||||||
|
imp: __sdk::UniqueConstraintHandle<Bot, u32>,
|
||||||
|
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> BotTableHandle<'ctx> {
|
||||||
|
/// Get a handle on the `id` unique index on the table `bot`.
|
||||||
|
pub fn id(&self) -> BotIdUnique<'ctx> {
|
||||||
|
BotIdUnique {
|
||||||
|
imp: self.imp.get_unique_constraint::<u32>("id"),
|
||||||
|
phantom: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> BotIdUnique<'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<Bot> {
|
||||||
|
self.imp.find(col_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
18
jong/src/stdb/bot_type.rs
Normal file
18
jong/src/stdb/bot_type.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
// 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 struct Bot {
|
||||||
|
pub id: u32,
|
||||||
|
pub lobby_id: u32,
|
||||||
|
pub hand_id: u32,
|
||||||
|
pub pond_id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for Bot {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
@ -4,16 +4,17 @@
|
||||||
#![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::hand_type::Hand;
|
|
||||||
use super::player_type::Player;
|
|
||||||
|
|
||||||
#[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 Table {
|
#[derive(Copy, Eq, Hash)]
|
||||||
pub players: Player,
|
pub enum Dragon {
|
||||||
pub hands: Vec<Hand>,
|
Haku,
|
||||||
|
|
||||||
|
Hatsu,
|
||||||
|
|
||||||
|
Chun,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for Table {
|
impl __sdk::InModule for Dragon {
|
||||||
type Module = super::RemoteModule;
|
type Module = super::RemoteModule;
|
||||||
}
|
}
|
||||||
24
jong/src/stdb/game_state_type.rs
Normal file
24
jong/src/stdb/game_state_type.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
// 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)]
|
||||||
|
#[derive(Copy, Eq, Hash)]
|
||||||
|
pub enum GameState {
|
||||||
|
None,
|
||||||
|
|
||||||
|
Setup,
|
||||||
|
|
||||||
|
Deal,
|
||||||
|
|
||||||
|
Play,
|
||||||
|
|
||||||
|
Exit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for GameState {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#![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 spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
/// Table handle for the table `hand`.
|
/// Table handle for the table `hand`.
|
||||||
|
|
@ -81,6 +83,23 @@ 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::<u32>("id", |row| &row.id);
|
||||||
|
}
|
||||||
|
pub struct HandUpdateCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::TableWithPrimaryKey for HandTableHandle<'ctx> {
|
||||||
|
type UpdateCallbackId = HandUpdateCallbackId;
|
||||||
|
|
||||||
|
fn on_update(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||||
|
) -> HandUpdateCallbackId {
|
||||||
|
HandUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_update(&self, callback: HandUpdateCallbackId) {
|
||||||
|
self.imp.remove_on_update(callback.0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
|
@ -93,3 +112,33 @@ pub(super) fn parse_table_update(
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Access to the `id` unique index on the table `hand`,
|
||||||
|
/// which allows point queries on the field of the same name
|
||||||
|
/// via the [`HandIdUnique::find`] method.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.hand().id().find(...)`.
|
||||||
|
pub struct HandIdUnique<'ctx> {
|
||||||
|
imp: __sdk::UniqueConstraintHandle<Hand, u32>,
|
||||||
|
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> HandTableHandle<'ctx> {
|
||||||
|
/// Get a handle on the `id` unique index on the table `hand`.
|
||||||
|
pub fn id(&self) -> HandIdUnique<'ctx> {
|
||||||
|
HandIdUnique {
|
||||||
|
imp: self.imp.get_unique_constraint::<u32>("id"),
|
||||||
|
phantom: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> HandIdUnique<'ctx> {
|
||||||
|
/// Find the subscribed row whose `id` column value is equal to `col_val`,
|
||||||
|
/// if such a row is present in the client cache.
|
||||||
|
pub fn find(&self, col_val: &u32) -> Option<Hand> {
|
||||||
|
self.imp.find(col_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
21
jong/src/stdb/hand_type.rs
Normal file
21
jong/src/stdb/hand_type.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
|
use super::tile_type::Tile;
|
||||||
|
|
||||||
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
|
#[sats(crate = __lib)]
|
||||||
|
pub struct Hand {
|
||||||
|
pub id: u32,
|
||||||
|
pub owner: PlayerOrBot,
|
||||||
|
pub sort: bool,
|
||||||
|
pub tiles: Vec<Tile>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for Hand {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
107
jong/src/stdb/join_or_create_lobby_reducer.rs
Normal file
107
jong/src/stdb/join_or_create_lobby_reducer.rs
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
// 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 JoinOrCreateLobbyArgs {
|
||||||
|
pub lobby_id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<JoinOrCreateLobbyArgs> for super::Reducer {
|
||||||
|
fn from(args: JoinOrCreateLobbyArgs) -> Self {
|
||||||
|
Self::JoinOrCreateLobby {
|
||||||
|
lobby_id: args.lobby_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for JoinOrCreateLobbyArgs {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct JoinOrCreateLobbyCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the reducer `join_or_create_lobby`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteReducers`].
|
||||||
|
pub trait join_or_create_lobby {
|
||||||
|
/// Request that the remote module invoke the reducer `join_or_create_lobby` 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_join_or_create_lobby`] callbacks.
|
||||||
|
fn join_or_create_lobby(&self, lobby_id: u32) -> __sdk::Result<()>;
|
||||||
|
/// Register a callback to run whenever we are notified of an invocation of the reducer `join_or_create_lobby`.
|
||||||
|
///
|
||||||
|
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
|
||||||
|
/// to determine the reducer's status.
|
||||||
|
///
|
||||||
|
/// The returned [`JoinOrCreateLobbyCallbackId`] can be passed to [`Self::remove_on_join_or_create_lobby`]
|
||||||
|
/// to cancel the callback.
|
||||||
|
fn on_join_or_create_lobby(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static,
|
||||||
|
) -> JoinOrCreateLobbyCallbackId;
|
||||||
|
/// Cancel a callback previously registered by [`Self::on_join_or_create_lobby`],
|
||||||
|
/// causing it not to run in the future.
|
||||||
|
fn remove_on_join_or_create_lobby(&self, callback: JoinOrCreateLobbyCallbackId);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl join_or_create_lobby for super::RemoteReducers {
|
||||||
|
fn join_or_create_lobby(&self, lobby_id: u32) -> __sdk::Result<()> {
|
||||||
|
self.imp
|
||||||
|
.call_reducer("join_or_create_lobby", JoinOrCreateLobbyArgs { lobby_id })
|
||||||
|
}
|
||||||
|
fn on_join_or_create_lobby(
|
||||||
|
&self,
|
||||||
|
mut callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static,
|
||||||
|
) -> JoinOrCreateLobbyCallbackId {
|
||||||
|
JoinOrCreateLobbyCallbackId(self.imp.on_reducer(
|
||||||
|
"join_or_create_lobby",
|
||||||
|
Box::new(move |ctx: &super::ReducerEventContext| {
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
let super::ReducerEventContext {
|
||||||
|
event:
|
||||||
|
__sdk::ReducerEvent {
|
||||||
|
reducer: super::Reducer::JoinOrCreateLobby { lobby_id },
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} = ctx
|
||||||
|
else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
callback(ctx, lobby_id)
|
||||||
|
}),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
fn remove_on_join_or_create_lobby(&self, callback: JoinOrCreateLobbyCallbackId) {
|
||||||
|
self.imp
|
||||||
|
.remove_on_reducer("join_or_create_lobby", callback.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[doc(hidden)]
|
||||||
|
/// Extension trait for setting the call-flags for the reducer `join_or_create_lobby`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::SetReducerFlags`].
|
||||||
|
///
|
||||||
|
/// This type is currently unstable and may be removed without a major version bump.
|
||||||
|
pub trait set_flags_for_join_or_create_lobby {
|
||||||
|
/// Set the call-reducer flags for the reducer `join_or_create_lobby` to `flags`.
|
||||||
|
///
|
||||||
|
/// This type is currently unstable and may be removed without a major version bump.
|
||||||
|
fn join_or_create_lobby(&self, flags: __ws::CallReducerFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl set_flags_for_join_or_create_lobby for super::SetReducerFlags {
|
||||||
|
fn join_or_create_lobby(&self, flags: __ws::CallReducerFlags) {
|
||||||
|
self.imp
|
||||||
|
.set_call_reducer_flags("join_or_create_lobby", flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
175
jong/src/stdb/lobby_table.rs
Normal file
175
jong/src/stdb/lobby_table.rs
Normal file
|
|
@ -0,0 +1,175 @@
|
||||||
|
// 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::game_state_type::GameState;
|
||||||
|
use super::lobby_type::Lobby;
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
/// Table handle for the table `lobby`.
|
||||||
|
///
|
||||||
|
/// Obtain a handle from the [`LobbyTableAccess::lobby`] method on [`super::RemoteTables`],
|
||||||
|
/// like `ctx.db.lobby()`.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.lobby().on_insert(...)`.
|
||||||
|
pub struct LobbyTableHandle<'ctx> {
|
||||||
|
imp: __sdk::TableHandle<Lobby>,
|
||||||
|
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the table `lobby`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteTables`].
|
||||||
|
pub trait LobbyTableAccess {
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
/// Obtain a [`LobbyTableHandle`], which mediates access to the table `lobby`.
|
||||||
|
fn lobby(&self) -> LobbyTableHandle<'_>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LobbyTableAccess for super::RemoteTables {
|
||||||
|
fn lobby(&self) -> LobbyTableHandle<'_> {
|
||||||
|
LobbyTableHandle {
|
||||||
|
imp: self.imp.get_table::<Lobby>("lobby"),
|
||||||
|
ctx: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LobbyInsertCallbackId(__sdk::CallbackId);
|
||||||
|
pub struct LobbyDeleteCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::Table for LobbyTableHandle<'ctx> {
|
||||||
|
type Row = Lobby;
|
||||||
|
type EventContext = super::EventContext;
|
||||||
|
|
||||||
|
fn count(&self) -> u64 {
|
||||||
|
self.imp.count()
|
||||||
|
}
|
||||||
|
fn iter(&self) -> impl Iterator<Item = Lobby> + '_ {
|
||||||
|
self.imp.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
type InsertCallbackId = LobbyInsertCallbackId;
|
||||||
|
|
||||||
|
fn on_insert(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||||
|
) -> LobbyInsertCallbackId {
|
||||||
|
LobbyInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_insert(&self, callback: LobbyInsertCallbackId) {
|
||||||
|
self.imp.remove_on_insert(callback.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteCallbackId = LobbyDeleteCallbackId;
|
||||||
|
|
||||||
|
fn on_delete(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||||
|
) -> LobbyDeleteCallbackId {
|
||||||
|
LobbyDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_delete(&self, callback: LobbyDeleteCallbackId) {
|
||||||
|
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::<Lobby>("lobby");
|
||||||
|
_table.add_unique_constraint::<u32>("id", |row| &row.id);
|
||||||
|
_table.add_unique_constraint::<u32>("host_player_id", |row| &row.host_player_id);
|
||||||
|
}
|
||||||
|
pub struct LobbyUpdateCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::TableWithPrimaryKey for LobbyTableHandle<'ctx> {
|
||||||
|
type UpdateCallbackId = LobbyUpdateCallbackId;
|
||||||
|
|
||||||
|
fn on_update(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||||
|
) -> LobbyUpdateCallbackId {
|
||||||
|
LobbyUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_update(&self, callback: LobbyUpdateCallbackId) {
|
||||||
|
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<Lobby>> {
|
||||||
|
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||||
|
__sdk::InternalError::failed_parse("TableUpdate<Lobby>", "TableUpdate")
|
||||||
|
.with_cause(e)
|
||||||
|
.into()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Access to the `id` unique index on the table `lobby`,
|
||||||
|
/// which allows point queries on the field of the same name
|
||||||
|
/// via the [`LobbyIdUnique::find`] method.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.lobby().id().find(...)`.
|
||||||
|
pub struct LobbyIdUnique<'ctx> {
|
||||||
|
imp: __sdk::UniqueConstraintHandle<Lobby, u32>,
|
||||||
|
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> LobbyTableHandle<'ctx> {
|
||||||
|
/// Get a handle on the `id` unique index on the table `lobby`.
|
||||||
|
pub fn id(&self) -> LobbyIdUnique<'ctx> {
|
||||||
|
LobbyIdUnique {
|
||||||
|
imp: self.imp.get_unique_constraint::<u32>("id"),
|
||||||
|
phantom: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> LobbyIdUnique<'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<Lobby> {
|
||||||
|
self.imp.find(col_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Access to the `host_player_id` unique index on the table `lobby`,
|
||||||
|
/// which allows point queries on the field of the same name
|
||||||
|
/// via the [`LobbyHostPlayerIdUnique::find`] method.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.lobby().host_player_id().find(...)`.
|
||||||
|
pub struct LobbyHostPlayerIdUnique<'ctx> {
|
||||||
|
imp: __sdk::UniqueConstraintHandle<Lobby, u32>,
|
||||||
|
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> LobbyTableHandle<'ctx> {
|
||||||
|
/// Get a handle on the `host_player_id` unique index on the table `lobby`.
|
||||||
|
pub fn host_player_id(&self) -> LobbyHostPlayerIdUnique<'ctx> {
|
||||||
|
LobbyHostPlayerIdUnique {
|
||||||
|
imp: self.imp.get_unique_constraint::<u32>("host_player_id"),
|
||||||
|
phantom: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> LobbyHostPlayerIdUnique<'ctx> {
|
||||||
|
/// Find the subscribed row whose `host_player_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<Lobby> {
|
||||||
|
self.imp.find(col_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
21
jong/src/stdb/lobby_type.rs
Normal file
21
jong/src/stdb/lobby_type.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
use super::game_state_type::GameState;
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
|
|
||||||
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
|
#[sats(crate = __lib)]
|
||||||
|
pub struct Lobby {
|
||||||
|
pub id: u32,
|
||||||
|
pub host_player_id: u32,
|
||||||
|
pub players: Vec<PlayerOrBot>,
|
||||||
|
pub game_state: GameState,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for Lobby {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
@ -6,64 +6,64 @@ 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 IdentityConnectedArgs {}
|
pub(super) struct LoginOrAddPlayerArgs {}
|
||||||
|
|
||||||
impl From<IdentityConnectedArgs> for super::Reducer {
|
impl From<LoginOrAddPlayerArgs> for super::Reducer {
|
||||||
fn from(args: IdentityConnectedArgs) -> Self {
|
fn from(args: LoginOrAddPlayerArgs) -> Self {
|
||||||
Self::IdentityConnected
|
Self::LoginOrAddPlayer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for IdentityConnectedArgs {
|
impl __sdk::InModule for LoginOrAddPlayerArgs {
|
||||||
type Module = super::RemoteModule;
|
type Module = super::RemoteModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IdentityConnectedCallbackId(__sdk::CallbackId);
|
pub struct LoginOrAddPlayerCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
/// Extension trait for access to the reducer `identity_connected`.
|
/// Extension trait for access to the reducer `login_or_add_player`.
|
||||||
///
|
///
|
||||||
/// Implemented for [`super::RemoteReducers`].
|
/// Implemented for [`super::RemoteReducers`].
|
||||||
pub trait identity_connected {
|
pub trait login_or_add_player {
|
||||||
/// Request that the remote module invoke the reducer `identity_connected` to run as soon as possible.
|
/// Request that the remote module invoke the reducer `login_or_add_player` 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_identity_connected`] callbacks.
|
/// and its status can be observed by listening for [`Self::on_login_or_add_player`] callbacks.
|
||||||
fn identity_connected(&self) -> __sdk::Result<()>;
|
fn login_or_add_player(&self) -> __sdk::Result<()>;
|
||||||
/// Register a callback to run whenever we are notified of an invocation of the reducer `identity_connected`.
|
/// Register a callback to run whenever we are notified of an invocation of the reducer `login_or_add_player`.
|
||||||
///
|
///
|
||||||
/// 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 [`IdentityConnectedCallbackId`] can be passed to [`Self::remove_on_identity_connected`]
|
/// The returned [`LoginOrAddPlayerCallbackId`] can be passed to [`Self::remove_on_login_or_add_player`]
|
||||||
/// to cancel the callback.
|
/// to cancel the callback.
|
||||||
fn on_identity_connected(
|
fn on_login_or_add_player(
|
||||||
&self,
|
&self,
|
||||||
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
||||||
) -> IdentityConnectedCallbackId;
|
) -> LoginOrAddPlayerCallbackId;
|
||||||
/// Cancel a callback previously registered by [`Self::on_identity_connected`],
|
/// Cancel a callback previously registered by [`Self::on_login_or_add_player`],
|
||||||
/// causing it not to run in the future.
|
/// causing it not to run in the future.
|
||||||
fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId);
|
fn remove_on_login_or_add_player(&self, callback: LoginOrAddPlayerCallbackId);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl identity_connected for super::RemoteReducers {
|
impl login_or_add_player for super::RemoteReducers {
|
||||||
fn identity_connected(&self) -> __sdk::Result<()> {
|
fn login_or_add_player(&self) -> __sdk::Result<()> {
|
||||||
self.imp
|
self.imp
|
||||||
.call_reducer("identity_connected", IdentityConnectedArgs {})
|
.call_reducer("login_or_add_player", LoginOrAddPlayerArgs {})
|
||||||
}
|
}
|
||||||
fn on_identity_connected(
|
fn on_login_or_add_player(
|
||||||
&self,
|
&self,
|
||||||
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
|
||||||
) -> IdentityConnectedCallbackId {
|
) -> LoginOrAddPlayerCallbackId {
|
||||||
IdentityConnectedCallbackId(self.imp.on_reducer(
|
LoginOrAddPlayerCallbackId(self.imp.on_reducer(
|
||||||
"identity_connected",
|
"login_or_add_player",
|
||||||
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::IdentityConnected {},
|
reducer: super::Reducer::LoginOrAddPlayer {},
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
..
|
..
|
||||||
|
|
@ -75,27 +75,29 @@ impl identity_connected for super::RemoteReducers {
|
||||||
}),
|
}),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId) {
|
fn remove_on_login_or_add_player(&self, callback: LoginOrAddPlayerCallbackId) {
|
||||||
self.imp.remove_on_reducer("identity_connected", callback.0)
|
self.imp
|
||||||
|
.remove_on_reducer("login_or_add_player", 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 `identity_connected`.
|
/// Extension trait for setting the call-flags for the reducer `login_or_add_player`.
|
||||||
///
|
///
|
||||||
/// 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_identity_connected {
|
pub trait set_flags_for_login_or_add_player {
|
||||||
/// Set the call-reducer flags for the reducer `identity_connected` to `flags`.
|
/// Set the call-reducer flags for the reducer `login_or_add_player` 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 identity_connected(&self, flags: __ws::CallReducerFlags);
|
fn login_or_add_player(&self, flags: __ws::CallReducerFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl set_flags_for_identity_connected for super::SetReducerFlags {
|
impl set_flags_for_login_or_add_player for super::SetReducerFlags {
|
||||||
fn identity_connected(&self, flags: __ws::CallReducerFlags) {
|
fn login_or_add_player(&self, flags: __ws::CallReducerFlags) {
|
||||||
self.imp.set_call_reducer_flags("identity_connected", flags);
|
self.imp
|
||||||
|
.set_call_reducer_flags("login_or_add_player", flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,39 +6,59 @@
|
||||||
#![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};
|
||||||
|
|
||||||
pub mod create_player_reducer;
|
pub mod add_bot_reducer;
|
||||||
pub mod drawn_table;
|
pub mod bot_table;
|
||||||
pub mod drawn_type;
|
pub mod bot_type;
|
||||||
|
pub mod dragon_type;
|
||||||
|
pub mod game_state_type;
|
||||||
pub mod hand_table;
|
pub mod hand_table;
|
||||||
pub mod hand_type;
|
pub mod hand_type;
|
||||||
pub mod identity_connected_reducer;
|
pub mod join_or_create_lobby_reducer;
|
||||||
pub mod identity_disconnected_reducer;
|
pub mod lobby_table;
|
||||||
|
pub mod lobby_type;
|
||||||
|
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 table_table;
|
pub mod pond_table;
|
||||||
pub mod table_type;
|
pub mod pond_type;
|
||||||
|
pub mod rank_type;
|
||||||
|
pub mod shuffle_deal_reducer;
|
||||||
|
pub mod suit_type;
|
||||||
|
pub mod tile_type;
|
||||||
|
pub mod view_player_hand_table;
|
||||||
pub mod wall_table;
|
pub mod wall_table;
|
||||||
pub mod wall_type;
|
pub mod wall_type;
|
||||||
|
pub mod wind_type;
|
||||||
|
|
||||||
pub use create_player_reducer::{
|
pub use add_bot_reducer::{add_bot, set_flags_for_add_bot, AddBotCallbackId};
|
||||||
create_player, set_flags_for_create_player, CreatePlayerCallbackId,
|
pub use bot_table::*;
|
||||||
};
|
pub use bot_type::Bot;
|
||||||
pub use drawn_table::*;
|
pub use dragon_type::Dragon;
|
||||||
pub use drawn_type::Drawn;
|
pub use game_state_type::GameState;
|
||||||
pub use hand_table::*;
|
pub use hand_table::*;
|
||||||
pub use hand_type::Hand;
|
pub use hand_type::Hand;
|
||||||
pub use identity_connected_reducer::{
|
pub use join_or_create_lobby_reducer::{
|
||||||
identity_connected, set_flags_for_identity_connected, IdentityConnectedCallbackId,
|
join_or_create_lobby, set_flags_for_join_or_create_lobby, JoinOrCreateLobbyCallbackId,
|
||||||
};
|
};
|
||||||
pub use identity_disconnected_reducer::{
|
pub use lobby_table::*;
|
||||||
identity_disconnected, set_flags_for_identity_disconnected, IdentityDisconnectedCallbackId,
|
pub use lobby_type::Lobby;
|
||||||
|
pub use login_or_add_player_reducer::{
|
||||||
|
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 table_table::*;
|
pub use pond_table::*;
|
||||||
pub use table_type::Table;
|
pub use pond_type::Pond;
|
||||||
|
pub use rank_type::Rank;
|
||||||
|
pub use shuffle_deal_reducer::{set_flags_for_shuffle_deal, shuffle_deal, ShuffleDealCallbackId};
|
||||||
|
pub use suit_type::Suit;
|
||||||
|
pub use tile_type::Tile;
|
||||||
|
pub use view_player_hand_table::*;
|
||||||
pub use wall_table::*;
|
pub use wall_table::*;
|
||||||
pub use wall_type::Wall;
|
pub use wall_type::Wall;
|
||||||
|
pub use wind_type::Wind;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
|
||||||
|
|
@ -48,9 +68,10 @@ pub use wall_type::Wall;
|
||||||
/// to indicate which reducer caused the event.
|
/// to indicate which reducer caused the event.
|
||||||
|
|
||||||
pub enum Reducer {
|
pub enum Reducer {
|
||||||
CreatePlayer { username: String },
|
AddBot { lobby_id: u32 },
|
||||||
IdentityConnected,
|
JoinOrCreateLobby { lobby_id: u32 },
|
||||||
IdentityDisconnected,
|
LoginOrAddPlayer,
|
||||||
|
ShuffleDeal { lobby_id: u32 },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for Reducer {
|
impl __sdk::InModule for Reducer {
|
||||||
|
|
@ -60,9 +81,10 @@ impl __sdk::InModule for Reducer {
|
||||||
impl __sdk::Reducer for Reducer {
|
impl __sdk::Reducer for Reducer {
|
||||||
fn reducer_name(&self) -> &'static str {
|
fn reducer_name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Reducer::CreatePlayer { .. } => "create_player",
|
Reducer::AddBot { .. } => "add_bot",
|
||||||
Reducer::IdentityConnected => "identity_connected",
|
Reducer::JoinOrCreateLobby { .. } => "join_or_create_lobby",
|
||||||
Reducer::IdentityDisconnected => "identity_disconnected",
|
Reducer::LoginOrAddPlayer => "login_or_add_player",
|
||||||
|
Reducer::ShuffleDeal { .. } => "shuffle_deal",
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -71,18 +93,26 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer {
|
||||||
type Error = __sdk::Error;
|
type Error = __sdk::Error;
|
||||||
fn try_from(value: __ws::ReducerCallInfo<__ws::BsatnFormat>) -> __sdk::Result<Self> {
|
fn try_from(value: __ws::ReducerCallInfo<__ws::BsatnFormat>) -> __sdk::Result<Self> {
|
||||||
match &value.reducer_name[..] {
|
match &value.reducer_name[..] {
|
||||||
"create_player" => Ok(__sdk::parse_reducer_args::<
|
"add_bot" => Ok(__sdk::parse_reducer_args::<add_bot_reducer::AddBotArgs>(
|
||||||
create_player_reducer::CreatePlayerArgs,
|
"add_bot",
|
||||||
>("create_player", &value.args)?
|
&value.args,
|
||||||
|
)?
|
||||||
.into()),
|
.into()),
|
||||||
"identity_connected" => Ok(__sdk::parse_reducer_args::<
|
"join_or_create_lobby" => Ok(__sdk::parse_reducer_args::<
|
||||||
identity_connected_reducer::IdentityConnectedArgs,
|
join_or_create_lobby_reducer::JoinOrCreateLobbyArgs,
|
||||||
>("identity_connected", &value.args)?
|
>("join_or_create_lobby", &value.args)?
|
||||||
.into()),
|
.into()),
|
||||||
"identity_disconnected" => Ok(__sdk::parse_reducer_args::<
|
"login_or_add_player" => Ok(__sdk::parse_reducer_args::<
|
||||||
identity_disconnected_reducer::IdentityDisconnectedArgs,
|
login_or_add_player_reducer::LoginOrAddPlayerArgs,
|
||||||
>("identity_disconnected", &value.args)?
|
>("login_or_add_player", &value.args)?
|
||||||
.into()),
|
.into()),
|
||||||
|
"shuffle_deal" => Ok(
|
||||||
|
__sdk::parse_reducer_args::<shuffle_deal_reducer::ShuffleDealArgs>(
|
||||||
|
"shuffle_deal",
|
||||||
|
&value.args,
|
||||||
|
)?
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
unknown => {
|
unknown => {
|
||||||
Err(
|
Err(
|
||||||
__sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo")
|
__sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo")
|
||||||
|
|
@ -97,10 +127,12 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct DbUpdate {
|
pub struct DbUpdate {
|
||||||
drawn: __sdk::TableUpdate<Drawn>,
|
bot: __sdk::TableUpdate<Bot>,
|
||||||
hand: __sdk::TableUpdate<Hand>,
|
hand: __sdk::TableUpdate<Hand>,
|
||||||
|
lobby: __sdk::TableUpdate<Lobby>,
|
||||||
player: __sdk::TableUpdate<Player>,
|
player: __sdk::TableUpdate<Player>,
|
||||||
table: __sdk::TableUpdate<Table>,
|
pond: __sdk::TableUpdate<Pond>,
|
||||||
|
view_player_hand: __sdk::TableUpdate<Hand>,
|
||||||
wall: __sdk::TableUpdate<Wall>,
|
wall: __sdk::TableUpdate<Wall>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,18 +142,24 @@ impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate {
|
||||||
let mut db_update = DbUpdate::default();
|
let mut db_update = DbUpdate::default();
|
||||||
for table_update in raw.tables {
|
for table_update in raw.tables {
|
||||||
match &table_update.table_name[..] {
|
match &table_update.table_name[..] {
|
||||||
"drawn" => db_update
|
"bot" => db_update
|
||||||
.drawn
|
.bot
|
||||||
.append(drawn_table::parse_table_update(table_update)?),
|
.append(bot_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)?),
|
||||||
|
"lobby" => db_update
|
||||||
|
.lobby
|
||||||
|
.append(lobby_table::parse_table_update(table_update)?),
|
||||||
"player" => db_update
|
"player" => db_update
|
||||||
.player
|
.player
|
||||||
.append(player_table::parse_table_update(table_update)?),
|
.append(player_table::parse_table_update(table_update)?),
|
||||||
"table" => db_update
|
"pond" => db_update
|
||||||
.table
|
.pond
|
||||||
.append(table_table::parse_table_update(table_update)?),
|
.append(pond_table::parse_table_update(table_update)?),
|
||||||
|
"view_player_hand" => db_update
|
||||||
|
.view_player_hand
|
||||||
|
.append(view_player_hand_table::parse_table_update(table_update)?),
|
||||||
"wall" => db_update
|
"wall" => db_update
|
||||||
.wall
|
.wall
|
||||||
.append(wall_table::parse_table_update(table_update)?),
|
.append(wall_table::parse_table_update(table_update)?),
|
||||||
|
|
@ -151,11 +189,26 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||||
) -> AppliedDiff<'_> {
|
) -> AppliedDiff<'_> {
|
||||||
let mut diff = AppliedDiff::default();
|
let mut diff = AppliedDiff::default();
|
||||||
|
|
||||||
diff.drawn = cache.apply_diff_to_table::<Drawn>("drawn", &self.drawn);
|
diff.bot = cache
|
||||||
diff.hand = cache.apply_diff_to_table::<Hand>("hand", &self.hand);
|
.apply_diff_to_table::<Bot>("bot", &self.bot)
|
||||||
diff.player = cache.apply_diff_to_table::<Player>("player", &self.player);
|
.with_updates_by_pk(|row| &row.id);
|
||||||
diff.table = cache.apply_diff_to_table::<Table>("table", &self.table);
|
diff.hand = cache
|
||||||
diff.wall = cache.apply_diff_to_table::<Wall>("wall", &self.wall);
|
.apply_diff_to_table::<Hand>("hand", &self.hand)
|
||||||
|
.with_updates_by_pk(|row| &row.id);
|
||||||
|
diff.lobby = cache
|
||||||
|
.apply_diff_to_table::<Lobby>("lobby", &self.lobby)
|
||||||
|
.with_updates_by_pk(|row| &row.id);
|
||||||
|
diff.player = cache
|
||||||
|
.apply_diff_to_table::<Player>("player", &self.player)
|
||||||
|
.with_updates_by_pk(|row| &row.identity);
|
||||||
|
diff.pond = cache
|
||||||
|
.apply_diff_to_table::<Pond>("pond", &self.pond)
|
||||||
|
.with_updates_by_pk(|row| &row.id);
|
||||||
|
diff.wall = cache
|
||||||
|
.apply_diff_to_table::<Wall>("wall", &self.wall)
|
||||||
|
.with_updates_by_pk(|row| &row.lobby_id);
|
||||||
|
diff.view_player_hand =
|
||||||
|
cache.apply_diff_to_table::<Hand>("view_player_hand", &self.view_player_hand);
|
||||||
|
|
||||||
diff
|
diff
|
||||||
}
|
}
|
||||||
|
|
@ -165,10 +218,12 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct AppliedDiff<'r> {
|
pub struct AppliedDiff<'r> {
|
||||||
drawn: __sdk::TableAppliedDiff<'r, Drawn>,
|
bot: __sdk::TableAppliedDiff<'r, Bot>,
|
||||||
hand: __sdk::TableAppliedDiff<'r, Hand>,
|
hand: __sdk::TableAppliedDiff<'r, Hand>,
|
||||||
|
lobby: __sdk::TableAppliedDiff<'r, Lobby>,
|
||||||
player: __sdk::TableAppliedDiff<'r, Player>,
|
player: __sdk::TableAppliedDiff<'r, Player>,
|
||||||
table: __sdk::TableAppliedDiff<'r, Table>,
|
pond: __sdk::TableAppliedDiff<'r, Pond>,
|
||||||
|
view_player_hand: __sdk::TableAppliedDiff<'r, Hand>,
|
||||||
wall: __sdk::TableAppliedDiff<'r, Wall>,
|
wall: __sdk::TableAppliedDiff<'r, Wall>,
|
||||||
__unused: std::marker::PhantomData<&'r ()>,
|
__unused: std::marker::PhantomData<&'r ()>,
|
||||||
}
|
}
|
||||||
|
|
@ -183,10 +238,16 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
|
||||||
event: &EventContext,
|
event: &EventContext,
|
||||||
callbacks: &mut __sdk::DbCallbacks<RemoteModule>,
|
callbacks: &mut __sdk::DbCallbacks<RemoteModule>,
|
||||||
) {
|
) {
|
||||||
callbacks.invoke_table_row_callbacks::<Drawn>("drawn", &self.drawn, event);
|
callbacks.invoke_table_row_callbacks::<Bot>("bot", &self.bot, event);
|
||||||
callbacks.invoke_table_row_callbacks::<Hand>("hand", &self.hand, event);
|
callbacks.invoke_table_row_callbacks::<Hand>("hand", &self.hand, event);
|
||||||
|
callbacks.invoke_table_row_callbacks::<Lobby>("lobby", &self.lobby, event);
|
||||||
callbacks.invoke_table_row_callbacks::<Player>("player", &self.player, event);
|
callbacks.invoke_table_row_callbacks::<Player>("player", &self.player, event);
|
||||||
callbacks.invoke_table_row_callbacks::<Table>("table", &self.table, event);
|
callbacks.invoke_table_row_callbacks::<Pond>("pond", &self.pond, event);
|
||||||
|
callbacks.invoke_table_row_callbacks::<Hand>(
|
||||||
|
"view_player_hand",
|
||||||
|
&self.view_player_hand,
|
||||||
|
event,
|
||||||
|
);
|
||||||
callbacks.invoke_table_row_callbacks::<Wall>("wall", &self.wall, event);
|
callbacks.invoke_table_row_callbacks::<Wall>("wall", &self.wall, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -907,10 +968,12 @@ impl __sdk::SpacetimeModule for RemoteModule {
|
||||||
type SubscriptionHandle = SubscriptionHandle;
|
type SubscriptionHandle = SubscriptionHandle;
|
||||||
|
|
||||||
fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
|
fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
|
||||||
drawn_table::register_table(client_cache);
|
bot_table::register_table(client_cache);
|
||||||
hand_table::register_table(client_cache);
|
hand_table::register_table(client_cache);
|
||||||
|
lobby_table::register_table(client_cache);
|
||||||
player_table::register_table(client_cache);
|
player_table::register_table(client_cache);
|
||||||
table_table::register_table(client_cache);
|
pond_table::register_table(client_cache);
|
||||||
|
view_player_hand_table::register_table(client_cache);
|
||||||
wall_table::register_table(client_cache);
|
wall_table::register_table(client_cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,8 +6,12 @@ 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 struct Drawn {}
|
pub enum PlayerOrBot {
|
||||||
|
Player(u32),
|
||||||
|
|
||||||
impl __sdk::InModule for Drawn {
|
Bot(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for PlayerOrBot {
|
||||||
type Module = super::RemoteModule;
|
type Module = super::RemoteModule;
|
||||||
}
|
}
|
||||||
|
|
@ -81,6 +81,24 @@ impl<'ctx> __sdk::Table for PlayerTableHandle<'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::<Player>("player");
|
let _table = client_cache.get_or_make_table::<Player>("player");
|
||||||
|
_table.add_unique_constraint::<__sdk::Identity>("identity", |row| &row.identity);
|
||||||
|
_table.add_unique_constraint::<u32>("id", |row| &row.id);
|
||||||
|
}
|
||||||
|
pub struct PlayerUpdateCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::TableWithPrimaryKey for PlayerTableHandle<'ctx> {
|
||||||
|
type UpdateCallbackId = PlayerUpdateCallbackId;
|
||||||
|
|
||||||
|
fn on_update(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||||
|
) -> PlayerUpdateCallbackId {
|
||||||
|
PlayerUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_update(&self, callback: PlayerUpdateCallbackId) {
|
||||||
|
self.imp.remove_on_update(callback.0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
|
@ -93,3 +111,65 @@ pub(super) fn parse_table_update(
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Access to the `identity` unique index on the table `player`,
|
||||||
|
/// which allows point queries on the field of the same name
|
||||||
|
/// via the [`PlayerIdentityUnique::find`] method.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.player().identity().find(...)`.
|
||||||
|
pub struct PlayerIdentityUnique<'ctx> {
|
||||||
|
imp: __sdk::UniqueConstraintHandle<Player, __sdk::Identity>,
|
||||||
|
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> PlayerTableHandle<'ctx> {
|
||||||
|
/// Get a handle on the `identity` unique index on the table `player`.
|
||||||
|
pub fn identity(&self) -> PlayerIdentityUnique<'ctx> {
|
||||||
|
PlayerIdentityUnique {
|
||||||
|
imp: self
|
||||||
|
.imp
|
||||||
|
.get_unique_constraint::<__sdk::Identity>("identity"),
|
||||||
|
phantom: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> PlayerIdentityUnique<'ctx> {
|
||||||
|
/// Find the subscribed row whose `identity` column value is equal to `col_val`,
|
||||||
|
/// if such a row is present in the client cache.
|
||||||
|
pub fn find(&self, col_val: &__sdk::Identity) -> Option<Player> {
|
||||||
|
self.imp.find(col_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Access to the `id` unique index on the table `player`,
|
||||||
|
/// which allows point queries on the field of the same name
|
||||||
|
/// via the [`PlayerIdUnique::find`] method.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.player().id().find(...)`.
|
||||||
|
pub struct PlayerIdUnique<'ctx> {
|
||||||
|
imp: __sdk::UniqueConstraintHandle<Player, u32>,
|
||||||
|
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> PlayerTableHandle<'ctx> {
|
||||||
|
/// Get a handle on the `id` unique index on the table `player`.
|
||||||
|
pub fn id(&self) -> PlayerIdUnique<'ctx> {
|
||||||
|
PlayerIdUnique {
|
||||||
|
imp: self.imp.get_unique_constraint::<u32>("id"),
|
||||||
|
phantom: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> PlayerIdUnique<'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<Player> {
|
||||||
|
self.imp.find(col_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,9 +7,12 @@ 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 struct Player {
|
pub struct Player {
|
||||||
pub username: String,
|
|
||||||
pub identity: __sdk::Identity,
|
pub identity: __sdk::Identity,
|
||||||
pub connection_id: __sdk::ConnectionId,
|
pub id: u32,
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub lobby_id: u32,
|
||||||
|
pub hand_id: u32,
|
||||||
|
pub pond_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for Player {
|
impl __sdk::InModule for Player {
|
||||||
144
jong/src/stdb/pond_table.rs
Normal file
144
jong/src/stdb/pond_table.rs
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
|
use super::pond_type::Pond;
|
||||||
|
use super::tile_type::Tile;
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
/// Table handle for the table `pond`.
|
||||||
|
///
|
||||||
|
/// Obtain a handle from the [`PondTableAccess::pond`] method on [`super::RemoteTables`],
|
||||||
|
/// like `ctx.db.pond()`.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.pond().on_insert(...)`.
|
||||||
|
pub struct PondTableHandle<'ctx> {
|
||||||
|
imp: __sdk::TableHandle<Pond>,
|
||||||
|
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the table `pond`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteTables`].
|
||||||
|
pub trait PondTableAccess {
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
/// Obtain a [`PondTableHandle`], which mediates access to the table `pond`.
|
||||||
|
fn pond(&self) -> PondTableHandle<'_>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PondTableAccess for super::RemoteTables {
|
||||||
|
fn pond(&self) -> PondTableHandle<'_> {
|
||||||
|
PondTableHandle {
|
||||||
|
imp: self.imp.get_table::<Pond>("pond"),
|
||||||
|
ctx: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PondInsertCallbackId(__sdk::CallbackId);
|
||||||
|
pub struct PondDeleteCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::Table for PondTableHandle<'ctx> {
|
||||||
|
type Row = Pond;
|
||||||
|
type EventContext = super::EventContext;
|
||||||
|
|
||||||
|
fn count(&self) -> u64 {
|
||||||
|
self.imp.count()
|
||||||
|
}
|
||||||
|
fn iter(&self) -> impl Iterator<Item = Pond> + '_ {
|
||||||
|
self.imp.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
type InsertCallbackId = PondInsertCallbackId;
|
||||||
|
|
||||||
|
fn on_insert(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||||
|
) -> PondInsertCallbackId {
|
||||||
|
PondInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_insert(&self, callback: PondInsertCallbackId) {
|
||||||
|
self.imp.remove_on_insert(callback.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteCallbackId = PondDeleteCallbackId;
|
||||||
|
|
||||||
|
fn on_delete(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||||
|
) -> PondDeleteCallbackId {
|
||||||
|
PondDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_delete(&self, callback: PondDeleteCallbackId) {
|
||||||
|
self.imp.remove_on_delete(callback.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||||
|
let _table = client_cache.get_or_make_table::<Pond>("pond");
|
||||||
|
_table.add_unique_constraint::<u32>("id", |row| &row.id);
|
||||||
|
}
|
||||||
|
pub struct PondUpdateCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::TableWithPrimaryKey for PondTableHandle<'ctx> {
|
||||||
|
type UpdateCallbackId = PondUpdateCallbackId;
|
||||||
|
|
||||||
|
fn on_update(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||||
|
) -> PondUpdateCallbackId {
|
||||||
|
PondUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_update(&self, callback: PondUpdateCallbackId) {
|
||||||
|
self.imp.remove_on_update(callback.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub(super) fn parse_table_update(
|
||||||
|
raw_updates: __ws::TableUpdate<__ws::BsatnFormat>,
|
||||||
|
) -> __sdk::Result<__sdk::TableUpdate<Pond>> {
|
||||||
|
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||||
|
__sdk::InternalError::failed_parse("TableUpdate<Pond>", "TableUpdate")
|
||||||
|
.with_cause(e)
|
||||||
|
.into()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Access to the `id` unique index on the table `pond`,
|
||||||
|
/// which allows point queries on the field of the same name
|
||||||
|
/// via the [`PondIdUnique::find`] method.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.pond().id().find(...)`.
|
||||||
|
pub struct PondIdUnique<'ctx> {
|
||||||
|
imp: __sdk::UniqueConstraintHandle<Pond, u32>,
|
||||||
|
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> PondTableHandle<'ctx> {
|
||||||
|
/// Get a handle on the `id` unique index on the table `pond`.
|
||||||
|
pub fn id(&self) -> PondIdUnique<'ctx> {
|
||||||
|
PondIdUnique {
|
||||||
|
imp: self.imp.get_unique_constraint::<u32>("id"),
|
||||||
|
phantom: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> PondIdUnique<'ctx> {
|
||||||
|
/// Find the subscribed row whose `id` column value is equal to `col_val`,
|
||||||
|
/// if such a row is present in the client cache.
|
||||||
|
pub fn find(&self, col_val: &u32) -> Option<Pond> {
|
||||||
|
self.imp.find(col_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
20
jong/src/stdb/pond_type.rs
Normal file
20
jong/src/stdb/pond_type.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
|
use super::tile_type::Tile;
|
||||||
|
|
||||||
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
|
#[sats(crate = __lib)]
|
||||||
|
pub struct Pond {
|
||||||
|
pub id: u32,
|
||||||
|
pub owner: PlayerOrBot,
|
||||||
|
pub tiles: Vec<Tile>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for Pond {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
@ -6,8 +6,10 @@ 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 struct Hand {}
|
pub struct Rank {
|
||||||
|
pub number: u8,
|
||||||
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for Hand {
|
impl __sdk::InModule for Rank {
|
||||||
type Module = super::RemoteModule;
|
type Module = super::RemoteModule;
|
||||||
}
|
}
|
||||||
105
jong/src/stdb/shuffle_deal_reducer.rs
Normal file
105
jong/src/stdb/shuffle_deal_reducer.rs
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
// 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 ShuffleDealArgs {
|
||||||
|
pub lobby_id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ShuffleDealArgs> for super::Reducer {
|
||||||
|
fn from(args: ShuffleDealArgs) -> Self {
|
||||||
|
Self::ShuffleDeal {
|
||||||
|
lobby_id: args.lobby_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for ShuffleDealArgs {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ShuffleDealCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the reducer `shuffle_deal`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteReducers`].
|
||||||
|
pub trait shuffle_deal {
|
||||||
|
/// 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.
|
||||||
|
/// The reducer will run asynchronously in the future,
|
||||||
|
/// and its status can be observed by listening for [`Self::on_shuffle_deal`] callbacks.
|
||||||
|
fn shuffle_deal(&self, lobby_id: u32) -> __sdk::Result<()>;
|
||||||
|
/// 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`]
|
||||||
|
/// to determine the reducer's status.
|
||||||
|
///
|
||||||
|
/// The returned [`ShuffleDealCallbackId`] can be passed to [`Self::remove_on_shuffle_deal`]
|
||||||
|
/// to cancel the callback.
|
||||||
|
fn on_shuffle_deal(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static,
|
||||||
|
) -> ShuffleDealCallbackId;
|
||||||
|
/// Cancel a callback previously registered by [`Self::on_shuffle_deal`],
|
||||||
|
/// causing it not to run in the future.
|
||||||
|
fn remove_on_shuffle_deal(&self, callback: ShuffleDealCallbackId);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl shuffle_deal for super::RemoteReducers {
|
||||||
|
fn shuffle_deal(&self, lobby_id: u32) -> __sdk::Result<()> {
|
||||||
|
self.imp
|
||||||
|
.call_reducer("shuffle_deal", ShuffleDealArgs { lobby_id })
|
||||||
|
}
|
||||||
|
fn on_shuffle_deal(
|
||||||
|
&self,
|
||||||
|
mut callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static,
|
||||||
|
) -> ShuffleDealCallbackId {
|
||||||
|
ShuffleDealCallbackId(self.imp.on_reducer(
|
||||||
|
"shuffle_deal",
|
||||||
|
Box::new(move |ctx: &super::ReducerEventContext| {
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
let super::ReducerEventContext {
|
||||||
|
event:
|
||||||
|
__sdk::ReducerEvent {
|
||||||
|
reducer: super::Reducer::ShuffleDeal { lobby_id },
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} = ctx
|
||||||
|
else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
callback(ctx, lobby_id)
|
||||||
|
}),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
fn remove_on_shuffle_deal(&self, callback: ShuffleDealCallbackId) {
|
||||||
|
self.imp.remove_on_reducer("shuffle_deal", callback.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[doc(hidden)]
|
||||||
|
/// Extension trait for setting the call-flags for the reducer `shuffle_deal`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::SetReducerFlags`].
|
||||||
|
///
|
||||||
|
/// This type is currently unstable and may be removed without a major version bump.
|
||||||
|
pub trait set_flags_for_shuffle_deal {
|
||||||
|
/// 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.
|
||||||
|
fn shuffle_deal(&self, flags: __ws::CallReducerFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl set_flags_for_shuffle_deal for super::SetReducerFlags {
|
||||||
|
fn shuffle_deal(&self, flags: __ws::CallReducerFlags) {
|
||||||
|
self.imp.set_call_reducer_flags("shuffle_deal", flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
jong/src/stdb/suit_type.rs
Normal file
27
jong/src/stdb/suit_type.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
use super::dragon_type::Dragon;
|
||||||
|
use super::rank_type::Rank;
|
||||||
|
use super::wind_type::Wind;
|
||||||
|
|
||||||
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
|
#[sats(crate = __lib)]
|
||||||
|
pub enum Suit {
|
||||||
|
Man(Rank),
|
||||||
|
|
||||||
|
Pin(Rank),
|
||||||
|
|
||||||
|
Sou(Rank),
|
||||||
|
|
||||||
|
Wind(Wind),
|
||||||
|
|
||||||
|
Dragon(Dragon),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for Suit {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
17
jong/src/stdb/tile_type.rs
Normal file
17
jong/src/stdb/tile_type.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
use super::suit_type::Suit;
|
||||||
|
|
||||||
|
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||||
|
#[sats(crate = __lib)]
|
||||||
|
pub struct Tile {
|
||||||
|
pub suit: Suit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for Tile {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
97
jong/src/stdb/view_player_hand_table.rs
Normal file
97
jong/src/stdb/view_player_hand_table.rs
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||||
|
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||||
|
|
||||||
|
#![allow(unused, clippy::all)]
|
||||||
|
use super::hand_type::Hand;
|
||||||
|
use super::player_or_bot_type::PlayerOrBot;
|
||||||
|
use super::tile_type::Tile;
|
||||||
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
/// Table handle for the table `view_player_hand`.
|
||||||
|
///
|
||||||
|
/// Obtain a handle from the [`ViewPlayerHandTableAccess::view_player_hand`] method on [`super::RemoteTables`],
|
||||||
|
/// like `ctx.db.view_player_hand()`.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.view_player_hand().on_insert(...)`.
|
||||||
|
pub struct ViewPlayerHandTableHandle<'ctx> {
|
||||||
|
imp: __sdk::TableHandle<Hand>,
|
||||||
|
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
/// Extension trait for access to the table `view_player_hand`.
|
||||||
|
///
|
||||||
|
/// Implemented for [`super::RemoteTables`].
|
||||||
|
pub trait ViewPlayerHandTableAccess {
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
/// Obtain a [`ViewPlayerHandTableHandle`], which mediates access to the table `view_player_hand`.
|
||||||
|
fn view_player_hand(&self) -> ViewPlayerHandTableHandle<'_>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ViewPlayerHandTableAccess for super::RemoteTables {
|
||||||
|
fn view_player_hand(&self) -> ViewPlayerHandTableHandle<'_> {
|
||||||
|
ViewPlayerHandTableHandle {
|
||||||
|
imp: self.imp.get_table::<Hand>("view_player_hand"),
|
||||||
|
ctx: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ViewPlayerHandInsertCallbackId(__sdk::CallbackId);
|
||||||
|
pub struct ViewPlayerHandDeleteCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::Table for ViewPlayerHandTableHandle<'ctx> {
|
||||||
|
type Row = Hand;
|
||||||
|
type EventContext = super::EventContext;
|
||||||
|
|
||||||
|
fn count(&self) -> u64 {
|
||||||
|
self.imp.count()
|
||||||
|
}
|
||||||
|
fn iter(&self) -> impl Iterator<Item = Hand> + '_ {
|
||||||
|
self.imp.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
type InsertCallbackId = ViewPlayerHandInsertCallbackId;
|
||||||
|
|
||||||
|
fn on_insert(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||||
|
) -> ViewPlayerHandInsertCallbackId {
|
||||||
|
ViewPlayerHandInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_insert(&self, callback: ViewPlayerHandInsertCallbackId) {
|
||||||
|
self.imp.remove_on_insert(callback.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteCallbackId = ViewPlayerHandDeleteCallbackId;
|
||||||
|
|
||||||
|
fn on_delete(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||||
|
) -> ViewPlayerHandDeleteCallbackId {
|
||||||
|
ViewPlayerHandDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_delete(&self, callback: ViewPlayerHandDeleteCallbackId) {
|
||||||
|
self.imp.remove_on_delete(callback.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||||
|
let _table = client_cache.get_or_make_table::<Hand>("view_player_hand");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub(super) fn parse_table_update(
|
||||||
|
raw_updates: __ws::TableUpdate<__ws::BsatnFormat>,
|
||||||
|
) -> __sdk::Result<__sdk::TableUpdate<Hand>> {
|
||||||
|
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||||
|
__sdk::InternalError::failed_parse("TableUpdate<Hand>", "TableUpdate")
|
||||||
|
.with_cause(e)
|
||||||
|
.into()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -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::tile_type::Tile;
|
||||||
use super::wall_type::Wall;
|
use super::wall_type::Wall;
|
||||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||||
|
|
||||||
|
|
@ -81,6 +82,23 @@ impl<'ctx> __sdk::Table for WallTableHandle<'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::<Wall>("wall");
|
let _table = client_cache.get_or_make_table::<Wall>("wall");
|
||||||
|
_table.add_unique_constraint::<u32>("lobby_id", |row| &row.lobby_id);
|
||||||
|
}
|
||||||
|
pub struct WallUpdateCallbackId(__sdk::CallbackId);
|
||||||
|
|
||||||
|
impl<'ctx> __sdk::TableWithPrimaryKey for WallTableHandle<'ctx> {
|
||||||
|
type UpdateCallbackId = WallUpdateCallbackId;
|
||||||
|
|
||||||
|
fn on_update(
|
||||||
|
&self,
|
||||||
|
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||||
|
) -> WallUpdateCallbackId {
|
||||||
|
WallUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_on_update(&self, callback: WallUpdateCallbackId) {
|
||||||
|
self.imp.remove_on_update(callback.0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
|
@ -93,3 +111,33 @@ pub(super) fn parse_table_update(
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Access to the `lobby_id` unique index on the table `wall`,
|
||||||
|
/// which allows point queries on the field of the same name
|
||||||
|
/// via the [`WallLobbyIdUnique::find`] method.
|
||||||
|
///
|
||||||
|
/// Users are encouraged not to explicitly reference this type,
|
||||||
|
/// but to directly chain method calls,
|
||||||
|
/// like `ctx.db.wall().lobby_id().find(...)`.
|
||||||
|
pub struct WallLobbyIdUnique<'ctx> {
|
||||||
|
imp: __sdk::UniqueConstraintHandle<Wall, u32>,
|
||||||
|
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> WallTableHandle<'ctx> {
|
||||||
|
/// Get a handle on the `lobby_id` unique index on the table `wall`.
|
||||||
|
pub fn lobby_id(&self) -> WallLobbyIdUnique<'ctx> {
|
||||||
|
WallLobbyIdUnique {
|
||||||
|
imp: self.imp.get_unique_constraint::<u32>("lobby_id"),
|
||||||
|
phantom: std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx> WallLobbyIdUnique<'ctx> {
|
||||||
|
/// Find the subscribed row whose `lobby_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<Wall> {
|
||||||
|
self.imp.find(col_val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,9 +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 Wall {}
|
pub struct Wall {
|
||||||
|
pub lobby_id: u32,
|
||||||
|
pub tiles: Vec<Tile>,
|
||||||
|
}
|
||||||
|
|
||||||
impl __sdk::InModule for Wall {
|
impl __sdk::InModule for Wall {
|
||||||
type Module = super::RemoteModule;
|
type Module = super::RemoteModule;
|
||||||
22
jong/src/stdb/wind_type.rs
Normal file
22
jong/src/stdb/wind_type.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
// 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)]
|
||||||
|
#[derive(Copy, Eq, Hash)]
|
||||||
|
pub enum Wind {
|
||||||
|
Ton,
|
||||||
|
|
||||||
|
Nan,
|
||||||
|
|
||||||
|
Shaa,
|
||||||
|
|
||||||
|
Pei,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl __sdk::InModule for Wind {
|
||||||
|
type Module = super::RemoteModule;
|
||||||
|
}
|
||||||
|
|
@ -1,77 +1,11 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use strum::FromRepr;
|
|
||||||
|
|
||||||
#[derive(Component, Debug, Clone, Copy)]
|
use jong_types::*;
|
||||||
pub struct Tile {
|
|
||||||
pub suit: Suit,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(/* MapEntities, */ Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy)]
|
|
||||||
pub enum Suit {
|
|
||||||
Man(Rank),
|
|
||||||
Pin(Rank),
|
|
||||||
Sou(Rank),
|
|
||||||
Wind(Wind),
|
|
||||||
Dragon(Dragon),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Suit {
|
|
||||||
pub fn rank(&self) -> Option<Rank> {
|
|
||||||
match self {
|
|
||||||
Suit::Man(rank) => Some(*rank),
|
|
||||||
Suit::Pin(rank) => Some(*rank),
|
|
||||||
Suit::Sou(rank) => Some(*rank),
|
|
||||||
// Suit::Wind(wind) | Suit::Dragon(dragon) => None,
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deref, DerefMut, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy)]
|
|
||||||
pub struct Rank(pub u8);
|
|
||||||
|
|
||||||
#[derive(FromRepr, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy)]
|
|
||||||
pub enum Wind {
|
|
||||||
Ton,
|
|
||||||
Nan,
|
|
||||||
Shaa,
|
|
||||||
Pei,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, FromRepr, PartialEq, PartialOrd, Eq, Ord, Clone, Copy)]
|
|
||||||
pub enum Dragon {
|
|
||||||
Haku,
|
|
||||||
Hatsu,
|
|
||||||
Chun,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Dora;
|
pub struct Dora;
|
||||||
|
|
||||||
pub fn init_tiles(mut commands: Commands) {
|
pub fn init_tiles(mut commands: Commands) {
|
||||||
let mut tiles = vec![];
|
let tiles = tiles();
|
||||||
for _ in 0..4 {
|
|
||||||
for i in 1..=9 {
|
|
||||||
tiles.push(Tile {
|
|
||||||
suit: Suit::Pin(Rank(i)),
|
|
||||||
});
|
|
||||||
tiles.push(Tile {
|
|
||||||
suit: Suit::Sou(Rank(i)),
|
|
||||||
});
|
|
||||||
tiles.push(Tile {
|
|
||||||
suit: Suit::Man(Rank(i)),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for i in 0..4 {
|
|
||||||
tiles.push(Tile {
|
|
||||||
suit: Suit::Wind(Wind::from_repr(i).unwrap()),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for i in 0..3 {
|
|
||||||
tiles.push(Tile {
|
|
||||||
suit: Suit::Dragon(Dragon::from_repr(i).unwrap()),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
commands.spawn_batch(tiles);
|
commands.spawn_batch(tiles);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,15 @@ use std::time::Duration;
|
||||||
|
|
||||||
use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin};
|
use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin};
|
||||||
use bevy_ratatui::RatatuiPlugins;
|
use bevy_ratatui::RatatuiPlugins;
|
||||||
use jong::game::{
|
|
||||||
GameMessage, GameState,
|
|
||||||
hand::{Drawn, Hand},
|
|
||||||
player::{CurrentPlayer, Player},
|
|
||||||
};
|
|
||||||
use tui_logger::TuiWidgetState;
|
use tui_logger::TuiWidgetState;
|
||||||
|
|
||||||
use crate::tui::{input::ConfirmSelect, states::ConsoleWidget};
|
use crate::tui::{input::ConfirmSelect, states::ConsoleWidget};
|
||||||
|
use jong::game::{
|
||||||
|
GameMessage,
|
||||||
|
hand::{Drawn, Hand},
|
||||||
|
player::{CurrentPlayer, Player},
|
||||||
|
};
|
||||||
|
use jong_types::GameState;
|
||||||
|
|
||||||
mod input;
|
mod input;
|
||||||
mod layout;
|
mod layout;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
use bevy_ratatui::crossterm::event::KeyCode;
|
||||||
use bevy_ratatui::event::KeyMessage;
|
use bevy_ratatui::event::KeyMessage;
|
||||||
use ratatui::crossterm::event::KeyCode;
|
// use ratatui::crossterm::event::KeyCode;
|
||||||
use tui_logger::TuiWidgetEvent;
|
use tui_logger::TuiWidgetEvent;
|
||||||
|
|
||||||
use jong::game::GameState;
|
|
||||||
|
|
||||||
use crate::tui::layout::Overlays;
|
use crate::tui::layout::Overlays;
|
||||||
use crate::tui::states::ConsoleWidget;
|
use crate::tui::states::ConsoleWidget;
|
||||||
use crate::tui::states::TuiState;
|
use crate::tui::states::TuiState;
|
||||||
|
use jong_types::GameState;
|
||||||
|
|
||||||
pub(crate) fn keyboard(
|
pub(crate) fn keyboard(
|
||||||
mut messages: MessageReader<KeyMessage>,
|
mut messages: MessageReader<KeyMessage>,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
use bevy_ratatui::crossterm::event::{MouseButton, MouseEventKind};
|
||||||
use bevy_ratatui::event::MouseMessage;
|
use bevy_ratatui::event::MouseMessage;
|
||||||
use ratatui::layout::Position;
|
use ratatui::layout::Position;
|
||||||
|
|
||||||
|
|
@ -21,8 +22,8 @@ pub(crate) fn mouse(
|
||||||
let position = Position::new(event.column, event.row);
|
let position = Position::new(event.column, event.row);
|
||||||
match event.kind {
|
match event.kind {
|
||||||
#[allow(clippy::single_match)]
|
#[allow(clippy::single_match)]
|
||||||
ratatui::crossterm::event::MouseEventKind::Down(mouse_button) => match mouse_button {
|
MouseEventKind::Down(mouse_button) => match mouse_button {
|
||||||
ratatui::crossterm::event::MouseButton::Left => {
|
MouseButton::Left => {
|
||||||
for (entity, region) in &entities {
|
for (entity, region) in &entities {
|
||||||
if region.area.contains(position) {
|
if region.area.contains(position) {
|
||||||
commands.entity(entity).insert(StartSelect);
|
commands.entity(entity).insert(StartSelect);
|
||||||
|
|
@ -34,7 +35,7 @@ pub(crate) fn mouse(
|
||||||
// ratatui::crossterm::event::MouseButton::Middle => debug!("unhandled mouse event"),
|
// ratatui::crossterm::event::MouseButton::Middle => debug!("unhandled mouse event"),
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
ratatui::crossterm::event::MouseEventKind::Moved => {
|
MouseEventKind::Moved => {
|
||||||
for (entity, region) in &hovered {
|
for (entity, region) in &hovered {
|
||||||
if !region.area.contains(position) {
|
if !region.area.contains(position) {
|
||||||
commands.entity(entity).remove::<Hovered>();
|
commands.entity(entity).remove::<Hovered>();
|
||||||
|
|
@ -46,8 +47,8 @@ pub(crate) fn mouse(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ratatui::crossterm::event::MouseEventKind::Up(mouse_button) => match mouse_button {
|
MouseEventKind::Up(mouse_button) => match mouse_button {
|
||||||
ratatui::crossterm::event::MouseButton::Left => {
|
MouseButton::Left => {
|
||||||
for (entity, region) in &startselected {
|
for (entity, region) in &startselected {
|
||||||
if region.area.contains(position) {
|
if region.area.contains(position) {
|
||||||
commands.entity(entity).remove::<StartSelect>();
|
commands.entity(entity).remove::<StartSelect>();
|
||||||
|
|
@ -55,7 +56,7 @@ pub(crate) fn mouse(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ratatui::crossterm::event::MouseButton::Right => {
|
MouseButton::Right => {
|
||||||
for (entity, _) in &startselected {
|
for (entity, _) in &startselected {
|
||||||
commands.entity(entity).remove::<StartSelect>();
|
commands.entity(entity).remove::<StartSelect>();
|
||||||
}
|
}
|
||||||
|
|
@ -63,19 +64,19 @@ pub(crate) fn mouse(
|
||||||
// ratatui::crossterm::event::MouseButton::Middle => debug!("unhandled mouse event"),
|
// ratatui::crossterm::event::MouseButton::Middle => debug!("unhandled mouse event"),
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
ratatui::crossterm::event::MouseEventKind::Drag(mouse_button) => {
|
MouseEventKind::Drag(mouse_button) => {
|
||||||
// debug!("unhandled mouse event")
|
// debug!("unhandled mouse event")
|
||||||
}
|
}
|
||||||
ratatui::crossterm::event::MouseEventKind::ScrollDown => {
|
MouseEventKind::ScrollDown => {
|
||||||
// debug!("unhandled mouse event")
|
// debug!("unhandled mouse event")
|
||||||
}
|
}
|
||||||
ratatui::crossterm::event::MouseEventKind::ScrollUp => {
|
MouseEventKind::ScrollUp => {
|
||||||
// debug!("unhandled mouse event")
|
// debug!("unhandled mouse event")
|
||||||
}
|
}
|
||||||
ratatui::crossterm::event::MouseEventKind::ScrollLeft => {
|
MouseEventKind::ScrollLeft => {
|
||||||
// debug!("unhandled mouse event")
|
// debug!("unhandled mouse event")
|
||||||
}
|
}
|
||||||
ratatui::crossterm::event::MouseEventKind::ScrollRight => {
|
MouseEventKind::ScrollRight => {
|
||||||
// debug!("unhandled mouse event")
|
// debug!("unhandled mouse event")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use ratatui::widgets::{Block, Borders, Clear, Paragraph};
|
||||||
use jong::game::hand::{Drawn, Hand};
|
use jong::game::hand::{Drawn, Hand};
|
||||||
use jong::game::player::{CurrentPlayer, MainPlayer, Player};
|
use jong::game::player::{CurrentPlayer, MainPlayer, Player};
|
||||||
use jong::game::round::Wind;
|
use jong::game::round::Wind;
|
||||||
use jong::tile::Tile;
|
// use jong_types::*;
|
||||||
|
|
||||||
use crate::tui::input::Hovered;
|
use crate::tui::input::Hovered;
|
||||||
use crate::tui::layout::*;
|
use crate::tui::layout::*;
|
||||||
|
|
@ -20,23 +20,24 @@ pub(crate) struct PickRegion {
|
||||||
pub(crate) area: Rect,
|
pub(crate) area: Rect,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_tile(tile: &Tile, hovered: bool) -> Paragraph<'_> {
|
fn render_tile(tile: &jong_types::Tile, hovered: bool) -> Paragraph<'_> {
|
||||||
|
use jong_types::*;
|
||||||
let block = ratatui::widgets::Block::bordered();
|
let block = ratatui::widgets::Block::bordered();
|
||||||
let mut widget = Paragraph::new(match &tile.suit {
|
let mut widget = Paragraph::new(match &tile.suit {
|
||||||
jong::tile::Suit::Pin(rank) => format!("{}\np", rank.0),
|
Suit::Pin(rank) => format!("{}\np", rank.number),
|
||||||
jong::tile::Suit::Sou(rank) => format!("{}\ns", rank.0),
|
Suit::Sou(rank) => format!("{}\ns", rank.number),
|
||||||
jong::tile::Suit::Man(rank) => format!("{}\nm", rank.0),
|
Suit::Man(rank) => format!("{}\nm", rank.number),
|
||||||
jong::tile::Suit::Wind(wind) => (match wind {
|
Suit::Wind(wind) => (match wind {
|
||||||
jong::tile::Wind::Ton => "e\nw",
|
Wind::Ton => "e\nw",
|
||||||
jong::tile::Wind::Nan => "s\nw",
|
Wind::Nan => "s\nw",
|
||||||
jong::tile::Wind::Shaa => "w\nw",
|
Wind::Shaa => "w\nw",
|
||||||
jong::tile::Wind::Pei => "n\nw",
|
Wind::Pei => "n\nw",
|
||||||
})
|
})
|
||||||
.into(),
|
.into(),
|
||||||
jong::tile::Suit::Dragon(dragon) => (match dragon {
|
Suit::Dragon(dragon) => (match dragon {
|
||||||
jong::tile::Dragon::Haku => "w\nd",
|
Dragon::Haku => "w\nd",
|
||||||
jong::tile::Dragon::Hatsu => "g\nd",
|
Dragon::Hatsu => "g\nd",
|
||||||
jong::tile::Dragon::Chun => "r\nd",
|
Dragon::Chun => "r\nd",
|
||||||
})
|
})
|
||||||
.into(),
|
.into(),
|
||||||
})
|
})
|
||||||
|
|
@ -102,7 +103,7 @@ pub(crate) fn render_hands(
|
||||||
hovered: Query<Entity, With<Hovered>>,
|
hovered: Query<Entity, With<Hovered>>,
|
||||||
layouts: Res<HandLayouts>,
|
layouts: Res<HandLayouts>,
|
||||||
|
|
||||||
tiles: Query<&Tile>,
|
tiles: Query<&jong_types::Tile>,
|
||||||
main_player: Single<(&Player, Entity, &Wind), With<MainPlayer>>,
|
main_player: Single<(&Player, Entity, &Wind), With<MainPlayer>>,
|
||||||
curr_player: Single<Entity, With<CurrentPlayer>>,
|
curr_player: Single<Entity, With<CurrentPlayer>>,
|
||||||
players: Query<(&Player, Entity, &Children)>,
|
players: Query<(&Player, Entity, &Children)>,
|
||||||
|
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
use spacetimedb::{reducer, ConnectionId, Identity, ReducerContext};
|
|
||||||
|
|
||||||
// use jong::tile::Tile;
|
|
||||||
|
|
||||||
#[spacetimedb::table(name = player)]
|
|
||||||
pub struct Player {
|
|
||||||
username: String,
|
|
||||||
|
|
||||||
identity: Identity,
|
|
||||||
connection_id: ConnectionId,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[spacetimedb::table(name = table, public)]
|
|
||||||
pub struct Table {
|
|
||||||
players: Player,
|
|
||||||
hands: Vec<Hand>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[spacetimedb::table(name = wall)]
|
|
||||||
pub struct Wall {
|
|
||||||
// tiles: Vec<Tile>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[spacetimedb::table(name = hand)]
|
|
||||||
pub struct Hand {
|
|
||||||
// hand: Vec<Tile>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[spacetimedb::table(name = drawn)]
|
|
||||||
pub struct Drawn {
|
|
||||||
// tile: Tile,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[reducer(init)]
|
|
||||||
pub fn init(_ctx: &ReducerContext) {
|
|
||||||
// Called when the module is initially published
|
|
||||||
}
|
|
||||||
|
|
||||||
#[reducer(client_connected)]
|
|
||||||
pub fn identity_connected(ctx: &ReducerContext) {
|
|
||||||
// Called everytime a new client connects
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called everytime a client disconnects
|
|
||||||
#[reducer(client_disconnected)]
|
|
||||||
pub fn identity_disconnected(ctx: &ReducerContext) {
|
|
||||||
// ctx.db.player().identity().delete(ctx.sender);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[reducer]
|
|
||||||
pub fn create_player(ctx: &ReducerContext, username: String) {
|
|
||||||
let connection_id = ctx.connection_id.unwrap();
|
|
||||||
let identity = ctx.identity();
|
|
||||||
// ctx.db.player().insert(Player {
|
|
||||||
// username,
|
|
||||||
// connection_id,
|
|
||||||
// identity,
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[spacetimedb::reducer]
|
|
||||||
// pub fn say_hello(ctx: &ReducerContext) {
|
|
||||||
// for person in ctx.db.person().iter() {
|
|
||||||
// log::info!("Hello, {}!", person.name);
|
|
||||||
// }
|
|
||||||
// log::info!("Hello, World!");
|
|
||||||
// }
|
|
||||||
14
justfile
14
justfile
|
|
@ -2,17 +2,25 @@ 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:
|
||||||
cargo update
|
cargo update
|
||||||
nix flake update
|
devenv update
|
||||||
|
|
||||||
spacetime:
|
spacetime:
|
||||||
spacetime build --project-path jongline
|
devenv up
|
||||||
spacetime generate --lang rust --project-path jongline --out-dir jong/src/jongline_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
|
||||||
|
|
|
||||||
6
mprocs.log
Normal file
6
mprocs.log
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
ERROR [lib::error] Error: channel closed
|
||||||
|
ERROR [lib::error] Error: channel closed
|
||||||
|
ERROR [lib::error] Error: channel closed
|
||||||
|
ERROR [lib::error] Error: channel closed
|
||||||
|
ERROR [lib::error] Error: channel closed
|
||||||
|
ERROR [lib::error] Error: channel closed
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[toolchain]
|
|
||||||
channel = "nightly"
|
|
||||||
1
rustfmt.toml
Normal file
1
rustfmt.toml
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
unstable_features = true
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "jongline"
|
name = "jongline"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|
@ -9,6 +9,6 @@ edition = "2021"
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
spacetimedb = "1.11.*"
|
spacetimedb = { workspace = true }
|
||||||
log = "0.4"
|
log = { workspace = true }
|
||||||
# jong = { version = "0.1.0", path = "../jong" }
|
jong-types = { workspace = true }
|
||||||
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
|
||||||
|
}
|
||||||
74
spacetimedb/src/lib.rs
Normal file
74
spacetimedb/src/lib.rs
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
use log::{debug, info};
|
||||||
|
use spacetimedb::{
|
||||||
|
ReducerContext, Table, ViewContext, rand::seq::SliceRandom, reducer, table, view,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::tables::*;
|
||||||
|
use jong_types::*;
|
||||||
|
|
||||||
|
mod game;
|
||||||
|
mod tables;
|
||||||
|
|
||||||
|
#[reducer(client_connected)]
|
||||||
|
pub fn login_or_add_player(ctx: &ReducerContext) {
|
||||||
|
let identity = ctx.sender;
|
||||||
|
|
||||||
|
// TODO remove player on disconnect
|
||||||
|
if let Ok(player) = ctx.db.player().try_insert(Player {
|
||||||
|
identity,
|
||||||
|
id: 0,
|
||||||
|
name: None,
|
||||||
|
lobby_id: 0,
|
||||||
|
hand_id: 0,
|
||||||
|
pond_id: 0,
|
||||||
|
}) {
|
||||||
|
info!("added player: {:?}", player);
|
||||||
|
} else {
|
||||||
|
let player = ctx.db.player().identity().find(identity).unwrap();
|
||||||
|
info!("player {:?} has reconnected", player)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[reducer(init)]
|
||||||
|
// pub fn init(_ctx: &ReducerContext) {
|
||||||
|
// // Called when the module is initially published
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[reducer(client_connected)]
|
||||||
|
// pub fn identity_connected(_ctx: &ReducerContext) {
|
||||||
|
// // Called everytime a new client connects
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[reducer(client_disconnected)]
|
||||||
|
// pub fn identity_disconnected(_ctx: &ReducerContext) {
|
||||||
|
// // Called everytime a client disconnects
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[reducer]
|
||||||
|
// pub fn add(ctx: &ReducerContext, name: String) {
|
||||||
|
// ctx.db.player().insert(Player { name });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[reducer]
|
||||||
|
// pub fn say_hello(ctx: &ReducerContext) {
|
||||||
|
// for person in ctx.db.person().iter() {
|
||||||
|
// log::info!("Hello, {}!", person.name);
|
||||||
|
// }
|
||||||
|
// log::info!("Hello, World!");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[reducer]
|
||||||
|
// pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> {
|
||||||
|
// if name.is_empty() {
|
||||||
|
// return Err("names must not be empty".into());
|
||||||
|
// }
|
||||||
|
// if let Some(player) = ctx.db.player().identity().find(ctx.sender) {
|
||||||
|
// ctx.db.player().identity().update(Player {
|
||||||
|
// name: Some(name),
|
||||||
|
// ..player
|
||||||
|
// });
|
||||||
|
// Ok(())
|
||||||
|
// } else {
|
||||||
|
// Err("cannot set name for unknown user".into())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
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