From d52a1c4d8e8e32ce0ed56f80d8c25e10283a7c87 Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Fri, 6 Feb 2026 22:07:10 -0800 Subject: [PATCH 01/11] some cleanup --- Cargo.lock | 221 ++--- Cargo.toml | 18 +- flake.lock | 12 +- flake.nix | 10 +- jong/Cargo.toml | 27 +- .../create_player_reducer.rs | 105 -- jong/src/jongline_bindings/drawn_table.rs | 95 -- jong/src/jongline_bindings/drawn_type.rs | 13 - jong/src/jongline_bindings/hand_table.rs | 95 -- jong/src/jongline_bindings/hand_type.rs | 13 - .../identity_connected_reducer.rs | 101 -- .../identity_disconnected_reducer.rs | 103 -- jong/src/jongline_bindings/mod.rs | 916 ------------------ jong/src/jongline_bindings/player_table.rs | 95 -- jong/src/jongline_bindings/player_type.rs | 17 - jong/src/jongline_bindings/table_table.rs | 97 -- jong/src/jongline_bindings/table_type.rs | 19 - jong/src/jongline_bindings/wall_table.rs | 95 -- jong/src/jongline_bindings/wall_type.rs | 13 - jong/src/lib.rs | 6 +- jong/src/main.rs | 14 +- jong/src/tui/input/keyboard.rs | 3 +- jong/src/tui/input/mouse.rs | 23 +- jongline/Cargo.toml | 14 - jongline/src/lib.rs | 67 -- 25 files changed, 138 insertions(+), 2054 deletions(-) delete mode 100644 jong/src/jongline_bindings/create_player_reducer.rs delete mode 100644 jong/src/jongline_bindings/drawn_table.rs delete mode 100644 jong/src/jongline_bindings/drawn_type.rs delete mode 100644 jong/src/jongline_bindings/hand_table.rs delete mode 100644 jong/src/jongline_bindings/hand_type.rs delete mode 100644 jong/src/jongline_bindings/identity_connected_reducer.rs delete mode 100644 jong/src/jongline_bindings/identity_disconnected_reducer.rs delete mode 100644 jong/src/jongline_bindings/mod.rs delete mode 100644 jong/src/jongline_bindings/player_table.rs delete mode 100644 jong/src/jongline_bindings/player_type.rs delete mode 100644 jong/src/jongline_bindings/table_table.rs delete mode 100644 jong/src/jongline_bindings/table_type.rs delete mode 100644 jong/src/jongline_bindings/wall_table.rs delete mode 100644 jong/src/jongline_bindings/wall_type.rs delete mode 100644 jongline/Cargo.toml delete mode 100644 jongline/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 8141aca..b9331ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,7 +97,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.3.4", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -249,9 +249,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" [[package]] name = "anymap" @@ -1173,7 +1173,7 @@ dependencies = [ "critical-section", "foldhash 0.2.0", "futures-channel", - "getrandom 0.3.4", + "getrandom", "hashbrown 0.16.1", "js-sys", "portable-atomic", @@ -1229,7 +1229,6 @@ dependencies = [ "bitflags 2.10.0", "color-eyre", "ratatui", - "smol_str", "tracing", ] @@ -1839,9 +1838,9 @@ checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "bytemuck" -version = "1.24.0" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" dependencies = [ "bytemuck_derive", ] @@ -1871,9 +1870,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "bytestring" @@ -1922,9 +1921,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.53" +version = "1.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" dependencies = [ "find-msvc-tools", "jobserver", @@ -1984,9 +1983,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.54" +version = "4.5.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" +checksum = "6899ea499e3fb9305a65d5ebf6e3d2248c5fab291f300ad0a704fbe142eae31a" dependencies = [ "clap_builder", "clap_derive", @@ -1994,9 +1993,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.54" +version = "4.5.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" +checksum = "7b12c8b680195a62a8364d16b8447b01b6c2c8f9aaf68bee653be34d4245e238" dependencies = [ "anstream", "anstyle", @@ -2006,9 +2005,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -2829,9 +2828,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "finl_unicode" @@ -2853,9 +2852,9 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flate2" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", @@ -3084,17 +3083,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "getrandom" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - [[package]] name = "getrandom" version = "0.3.4" @@ -3437,9 +3425,9 @@ checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -3733,7 +3721,7 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.4", + "getrandom", "libc", ] @@ -3745,7 +3733,6 @@ dependencies = [ "bevy_ratatui", "bevy_spacetimedb", "clap", - "jongline", "log", "rand 0.9.2", "ratatui", @@ -3755,14 +3742,6 @@ dependencies = [ "tui-logger", ] -[[package]] -name = "jongline" -version = "0.1.0" -dependencies = [ - "log", - "spacetimedb", -] - [[package]] name = "js-sys" version = "0.3.85" @@ -3860,9 +3839,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" @@ -3981,9 +3960,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" @@ -4243,9 +4222,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-derive" @@ -4733,9 +4712,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.5" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" dependencies = [ "memchr", "ucd-trie", @@ -4743,9 +4722,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.5" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f9dbced329c441fa79d80472764b1a2c7e57123553b8519b36663a2fb234ed" +checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" dependencies = [ "pest", "pest_generator", @@ -4753,9 +4732,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.5" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bb96d5051a78f44f43c8f712d8e810adb0ebf923fc9ed2655a7f66f63ba8ee5" +checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" dependencies = [ "pest", "pest_meta", @@ -4766,9 +4745,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.8.5" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602113b5b5e8621770cfd490cfd90b9f84ab29bd2b0e49ad83eb6d186cef2365" +checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" dependencies = [ "pest", "sha2", @@ -4917,15 +4896,15 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" dependencies = [ "portable-atomic", ] @@ -5059,8 +5038,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "libc", - "rand_chacha 0.3.1", "rand_core 0.6.4", ] @@ -5070,20 +5047,10 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha 0.9.0", + "rand_chacha", "rand_core 0.9.5", ] -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - [[package]] name = "rand_chacha" version = "0.9.0" @@ -5099,9 +5066,6 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.17", -] [[package]] name = "rand_core" @@ -5109,7 +5073,7 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ - "getrandom 0.3.4", + "getrandom", ] [[package]] @@ -5310,9 +5274,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -5322,9 +5286,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -5333,9 +5297,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" [[package]] name = "renderdoc-sys" @@ -5495,9 +5459,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e910108742c57a770f492731f99be216a52fadd361b06c8fb59d74ccc267d2" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" dependencies = [ "dyn-clone", "ref-cast", @@ -5632,7 +5596,7 @@ dependencies = [ "indexmap 1.9.3", "indexmap 2.13.0", "schemars 0.9.0", - "schemars 1.2.0", + "schemars 1.2.1", "serde_core", "serde_json", "serde_with_macros", @@ -5737,9 +5701,9 @@ checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" [[package]] name = "siphasher" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" [[package]] name = "skrifa" @@ -5753,9 +5717,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "slotmap" @@ -5808,36 +5772,14 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" dependencies = [ "libc", "windows-sys 0.60.2", ] -[[package]] -name = "spacetimedb" -version = "1.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83af98280374b59796296f512f7855fd19e19240a358bb7706a54f1c4e4e7dff" -dependencies = [ - "anyhow", - "bytemuck", - "bytes", - "derive_more 0.99.20", - "getrandom 0.2.17", - "http", - "log", - "rand 0.8.5", - "scoped-tls", - "serde_json", - "spacetimedb-bindings-macro", - "spacetimedb-bindings-sys", - "spacetimedb-lib", - "spacetimedb-primitives", -] - [[package]] name = "spacetimedb-bindings-macro" version = "1.11.3" @@ -5852,15 +5794,6 @@ dependencies = [ "syn 2.0.114", ] -[[package]] -name = "spacetimedb-bindings-sys" -version = "1.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a0d30e1655731b1564b7094a6213ef6c354ea920e3c04424e55ad377a1bc3e2" -dependencies = [ - "spacetimedb-primitives", -] - [[package]] name = "spacetimedb-client-api-messages" version = "1.11.3" @@ -6191,7 +6124,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom", "once_cell", "rustix 1.1.3", "windows-sys 0.61.2", @@ -6320,9 +6253,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.45" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", @@ -6337,15 +6270,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.25" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -6722,9 +6655,9 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.2.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "unicode-xid" @@ -6764,12 +6697,12 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" dependencies = [ "atomic", - "getrandom 0.3.4", + "getrandom", "js-sys", "serde_core", "wasm-bindgen", @@ -7047,7 +6980,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "692daff6d93d94e29e4114544ef6d5c942a7ed998b37abdc19b17136ea428eb7" dependencies = [ - "getrandom 0.3.4", + "getrandom", "mac_address", "sha2", "thiserror 1.0.69", @@ -7978,18 +7911,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.33" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.33" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", @@ -8052,6 +7985,6 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.16" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfcd145825aace48cff44a8844de64bf75feec3080e0aa5cdbde72961ae51a65" +checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445" diff --git a/Cargo.toml b/Cargo.toml index aa55a94..66302f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,25 @@ [workspace] resolver = "3" -members = ["jong", "jongline"] +members = ["jong"] + +[workspace.dependencies] +bevy = "0.17.3" +bevy_ratatui = "0.10.0" +bevy_spacetimedb = "0.7" +clap = "4.5.54" +log = "0.4.29" +rand = "0.9.2" +ratatui = "0.30.0" +strum = "0.27.2" +tracing = "0.1.44" +tracing-subscriber = "0.3.22" +tui-logger = "0.18.0" [profile.dev] opt-level = 1 [profile.dev.package."*"] opt-level = 3 + +[patch.crates-io] +bevy_ratatui = {path = "/home/tao/clones/bevy_ratatui"} diff --git a/flake.lock b/flake.lock index e4af06f..13b0421 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1768564909, - "narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=", + "lastModified": 1770197578, + "narHash": "sha256-AYqlWrX09+HvGs8zM6ebZ1pwUqjkfpnv8mewYwAo+iM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f", + "rev": "00c21e4c93d963c50d4c0c89bfa84ed6e0694df2", "type": "github" }, "original": { @@ -62,11 +62,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1768617670, - "narHash": "sha256-Z3+6dxoWZn+QFwjxAt5ZGXkiuCvCLgQP6pTS5eSWXqk=", + "lastModified": 1770433312, + "narHash": "sha256-IaiqGwmLBrR0z67t/oaS6GIFxv9V8mDY7dBTuYVTbKY=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "56d0fbdd732f3686e8414b857cf885038fc17d57", + "rev": "9922ff9f99a6436756cbe6f5d11f9c3630e58cf0", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 826c958..3a332de 100644 --- a/flake.nix +++ b/flake.nix @@ -21,7 +21,7 @@ }; in { devShells.default = with pkgs; - mkShell { + mkShell rec { buildInputs = [ # Rust dependencies @@ -53,13 +53,7 @@ binaryen ]; RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; - LD_LIBRARY_PATH = lib.makeLibraryPath [ - vulkan-loader - xorg.libX11 - xorg.libXi - xorg.libXcursor - libxkbcommon - ]; + LD_LIBRARY_PATH = lib.makeLibraryPath buildInputs; RUST_LOG = "jong=trace"; }; } diff --git a/jong/Cargo.toml b/jong/Cargo.toml index 8ab386e..74353e2 100644 --- a/jong/Cargo.toml +++ b/jong/Cargo.toml @@ -10,19 +10,16 @@ readme = false [lib] [dependencies] -bevy = { version = "0.17.3", features = ["dynamic_linking"] } +bevy = { workspace = true, features = ["dynamic_linking"] } +bevy_ratatui = { workspace = true } # bevy_ratatui = { git = "https://github.com/kenianbei/bevy_ratatui.git", rev = "e4b022308e08ab360ef89eca8e9f8b1c969e9a56" } -bevy_ratatui = { path = "/home/tao/clones/bevy_ratatui" } -bevy_spacetimedb = "0.7" -clap = { version = "4.5.54", features = ["derive"] } -jongline = { version = "0.1.0", path = "../jongline" } -log = { version = "0.4.29", features = [ - "release_max_level_error", - "max_level_trace", -] } -rand = "0.9.2" -ratatui = "0.30.0" -strum = { version = "0.27.2", features = ["derive"] } -tracing = "0.1.44" -tracing-subscriber = "0.3.22" -tui-logger = { version = "0.18.0", features = ["tracing-support", "crossterm"] } +# bevy_ratatui = { path = "/home/tao/clones/bevy_ratatui" } +bevy_spacetimedb = { workspace = true } +clap = { workspace = true, features = ["derive"] } +log = { workspace = true, features = ["release_max_level_error", "max_level_trace"] } +rand = { workspace = true } +ratatui = { workspace = true } +strum = { workspace = true, features = ["derive"] } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } +tui-logger = { workspace = true, features = ["tracing-support", "crossterm"] } diff --git a/jong/src/jongline_bindings/create_player_reducer.rs b/jong/src/jongline_bindings/create_player_reducer.rs deleted file mode 100644 index 6271888..0000000 --- a/jong/src/jongline_bindings/create_player_reducer.rs +++ /dev/null @@ -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 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); - } -} diff --git a/jong/src/jongline_bindings/drawn_table.rs b/jong/src/jongline_bindings/drawn_table.rs deleted file mode 100644 index 2df1f4b..0000000 --- a/jong/src/jongline_bindings/drawn_table.rs +++ /dev/null @@ -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, - 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"), - 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 + '_ { - 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) { - let _table = client_cache.get_or_make_table::("drawn"); -} - -#[doc(hidden)] -pub(super) fn parse_table_update( - raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, -) -> __sdk::Result<__sdk::TableUpdate> { - __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { - __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") - .with_cause(e) - .into() - }) -} diff --git a/jong/src/jongline_bindings/drawn_type.rs b/jong/src/jongline_bindings/drawn_type.rs deleted file mode 100644 index c443a03..0000000 --- a/jong/src/jongline_bindings/drawn_type.rs +++ /dev/null @@ -1,13 +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 struct Drawn {} - -impl __sdk::InModule for Drawn { - type Module = super::RemoteModule; -} diff --git a/jong/src/jongline_bindings/hand_table.rs b/jong/src/jongline_bindings/hand_table.rs deleted file mode 100644 index 9e15c00..0000000 --- a/jong/src/jongline_bindings/hand_table.rs +++ /dev/null @@ -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::hand_type::Hand; -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -/// Table handle for the table `hand`. -/// -/// Obtain a handle from the [`HandTableAccess::hand`] method on [`super::RemoteTables`], -/// like `ctx.db.hand()`. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.hand().on_insert(...)`. -pub struct HandTableHandle<'ctx> { - imp: __sdk::TableHandle, - ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -#[allow(non_camel_case_types)] -/// Extension trait for access to the table `hand`. -/// -/// Implemented for [`super::RemoteTables`]. -pub trait HandTableAccess { - #[allow(non_snake_case)] - /// Obtain a [`HandTableHandle`], which mediates access to the table `hand`. - fn hand(&self) -> HandTableHandle<'_>; -} - -impl HandTableAccess for super::RemoteTables { - fn hand(&self) -> HandTableHandle<'_> { - HandTableHandle { - imp: self.imp.get_table::("hand"), - ctx: std::marker::PhantomData, - } - } -} - -pub struct HandInsertCallbackId(__sdk::CallbackId); -pub struct HandDeleteCallbackId(__sdk::CallbackId); - -impl<'ctx> __sdk::Table for HandTableHandle<'ctx> { - type Row = Hand; - type EventContext = super::EventContext; - - fn count(&self) -> u64 { - self.imp.count() - } - fn iter(&self) -> impl Iterator + '_ { - self.imp.iter() - } - - type InsertCallbackId = HandInsertCallbackId; - - fn on_insert( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> HandInsertCallbackId { - HandInsertCallbackId(self.imp.on_insert(Box::new(callback))) - } - - fn remove_on_insert(&self, callback: HandInsertCallbackId) { - self.imp.remove_on_insert(callback.0) - } - - type DeleteCallbackId = HandDeleteCallbackId; - - fn on_delete( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> HandDeleteCallbackId { - HandDeleteCallbackId(self.imp.on_delete(Box::new(callback))) - } - - fn remove_on_delete(&self, callback: HandDeleteCallbackId) { - self.imp.remove_on_delete(callback.0) - } -} - -#[doc(hidden)] -pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { - let _table = client_cache.get_or_make_table::("hand"); -} - -#[doc(hidden)] -pub(super) fn parse_table_update( - raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, -) -> __sdk::Result<__sdk::TableUpdate> { - __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { - __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") - .with_cause(e) - .into() - }) -} diff --git a/jong/src/jongline_bindings/hand_type.rs b/jong/src/jongline_bindings/hand_type.rs deleted file mode 100644 index f2bbfd2..0000000 --- a/jong/src/jongline_bindings/hand_type.rs +++ /dev/null @@ -1,13 +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 struct Hand {} - -impl __sdk::InModule for Hand { - type Module = super::RemoteModule; -} diff --git a/jong/src/jongline_bindings/identity_connected_reducer.rs b/jong/src/jongline_bindings/identity_connected_reducer.rs deleted file mode 100644 index 2eaaab0..0000000 --- a/jong/src/jongline_bindings/identity_connected_reducer.rs +++ /dev/null @@ -1,101 +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 IdentityConnectedArgs {} - -impl From for super::Reducer { - fn from(args: IdentityConnectedArgs) -> Self { - Self::IdentityConnected - } -} - -impl __sdk::InModule for IdentityConnectedArgs { - type Module = super::RemoteModule; -} - -pub struct IdentityConnectedCallbackId(__sdk::CallbackId); - -#[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `identity_connected`. -/// -/// Implemented for [`super::RemoteReducers`]. -pub trait identity_connected { - /// Request that the remote module invoke the reducer `identity_connected` 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_connected`] callbacks. - fn identity_connected(&self) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `identity_connected`. - /// - /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] - /// to determine the reducer's status. - /// - /// The returned [`IdentityConnectedCallbackId`] can be passed to [`Self::remove_on_identity_connected`] - /// to cancel the callback. - fn on_identity_connected( - &self, - callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> IdentityConnectedCallbackId; - /// Cancel a callback previously registered by [`Self::on_identity_connected`], - /// causing it not to run in the future. - fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId); -} - -impl identity_connected for super::RemoteReducers { - fn identity_connected(&self) -> __sdk::Result<()> { - self.imp - .call_reducer("identity_connected", IdentityConnectedArgs {}) - } - fn on_identity_connected( - &self, - mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> IdentityConnectedCallbackId { - IdentityConnectedCallbackId(self.imp.on_reducer( - "identity_connected", - Box::new(move |ctx: &super::ReducerEventContext| { - #[allow(irrefutable_let_patterns)] - let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::IdentityConnected {}, - .. - }, - .. - } = ctx - else { - unreachable!() - }; - callback(ctx) - }), - )) - } - fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId) { - self.imp.remove_on_reducer("identity_connected", callback.0) - } -} - -#[allow(non_camel_case_types)] -#[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `identity_connected`. -/// -/// Implemented for [`super::SetReducerFlags`]. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_identity_connected { - /// Set the call-reducer flags for the reducer `identity_connected` to `flags`. - /// - /// This type is currently unstable and may be removed without a major version bump. - fn identity_connected(&self, flags: __ws::CallReducerFlags); -} - -impl set_flags_for_identity_connected for super::SetReducerFlags { - fn identity_connected(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("identity_connected", flags); - } -} diff --git a/jong/src/jongline_bindings/identity_disconnected_reducer.rs b/jong/src/jongline_bindings/identity_disconnected_reducer.rs deleted file mode 100644 index c2892ed..0000000 --- a/jong/src/jongline_bindings/identity_disconnected_reducer.rs +++ /dev/null @@ -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 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); - } -} diff --git a/jong/src/jongline_bindings/mod.rs b/jong/src/jongline_bindings/mod.rs deleted file mode 100644 index 00aa7f7..0000000 --- a/jong/src/jongline_bindings/mod.rs +++ /dev/null @@ -1,916 +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. - -// This was generated using spacetimedb cli version 1.11.3 (commit 02449737ca3b29e7e39679fccbef541a50f32094). - -#![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -pub mod create_player_reducer; -pub mod drawn_table; -pub mod drawn_type; -pub mod hand_table; -pub mod hand_type; -pub mod identity_connected_reducer; -pub mod identity_disconnected_reducer; -pub mod player_table; -pub mod player_type; -pub mod table_table; -pub mod table_type; -pub mod wall_table; -pub mod wall_type; - -pub use create_player_reducer::{ - create_player, set_flags_for_create_player, CreatePlayerCallbackId, -}; -pub use drawn_table::*; -pub use drawn_type::Drawn; -pub use hand_table::*; -pub use hand_type::Hand; -pub use identity_connected_reducer::{ - identity_connected, set_flags_for_identity_connected, IdentityConnectedCallbackId, -}; -pub use identity_disconnected_reducer::{ - identity_disconnected, set_flags_for_identity_disconnected, IdentityDisconnectedCallbackId, -}; -pub use player_table::*; -pub use player_type::Player; -pub use table_table::*; -pub use table_type::Table; -pub use wall_table::*; -pub use wall_type::Wall; - -#[derive(Clone, PartialEq, Debug)] - -/// One of the reducers defined by this module. -/// -/// Contained within a [`__sdk::ReducerEvent`] in [`EventContext`]s for reducer events -/// to indicate which reducer caused the event. - -pub enum Reducer { - CreatePlayer { username: String }, - IdentityConnected, - IdentityDisconnected, -} - -impl __sdk::InModule for Reducer { - type Module = RemoteModule; -} - -impl __sdk::Reducer for Reducer { - fn reducer_name(&self) -> &'static str { - match self { - Reducer::CreatePlayer { .. } => "create_player", - Reducer::IdentityConnected => "identity_connected", - Reducer::IdentityDisconnected => "identity_disconnected", - _ => unreachable!(), - } - } -} -impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { - type Error = __sdk::Error; - fn try_from(value: __ws::ReducerCallInfo<__ws::BsatnFormat>) -> __sdk::Result { - match &value.reducer_name[..] { - "create_player" => Ok(__sdk::parse_reducer_args::< - create_player_reducer::CreatePlayerArgs, - >("create_player", &value.args)? - .into()), - "identity_connected" => Ok(__sdk::parse_reducer_args::< - identity_connected_reducer::IdentityConnectedArgs, - >("identity_connected", &value.args)? - .into()), - "identity_disconnected" => Ok(__sdk::parse_reducer_args::< - identity_disconnected_reducer::IdentityDisconnectedArgs, - >("identity_disconnected", &value.args)? - .into()), - unknown => { - Err( - __sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo") - .into(), - ) - } - } - } -} - -#[derive(Default)] -#[allow(non_snake_case)] -#[doc(hidden)] -pub struct DbUpdate { - drawn: __sdk::TableUpdate, - hand: __sdk::TableUpdate, - player: __sdk::TableUpdate, - table: __sdk::TableUpdate, - wall: __sdk::TableUpdate, -} - -impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { - type Error = __sdk::Error; - fn try_from(raw: __ws::DatabaseUpdate<__ws::BsatnFormat>) -> Result { - let mut db_update = DbUpdate::default(); - for table_update in raw.tables { - match &table_update.table_name[..] { - "drawn" => db_update - .drawn - .append(drawn_table::parse_table_update(table_update)?), - "hand" => db_update - .hand - .append(hand_table::parse_table_update(table_update)?), - "player" => db_update - .player - .append(player_table::parse_table_update(table_update)?), - "table" => db_update - .table - .append(table_table::parse_table_update(table_update)?), - "wall" => db_update - .wall - .append(wall_table::parse_table_update(table_update)?), - - unknown => { - return Err(__sdk::InternalError::unknown_name( - "table", - unknown, - "DatabaseUpdate", - ) - .into()); - } - } - } - Ok(db_update) - } -} - -impl __sdk::InModule for DbUpdate { - type Module = RemoteModule; -} - -impl __sdk::DbUpdate for DbUpdate { - fn apply_to_client_cache( - &self, - cache: &mut __sdk::ClientCache, - ) -> AppliedDiff<'_> { - let mut diff = AppliedDiff::default(); - - diff.drawn = cache.apply_diff_to_table::("drawn", &self.drawn); - diff.hand = cache.apply_diff_to_table::("hand", &self.hand); - diff.player = cache.apply_diff_to_table::("player", &self.player); - diff.table = cache.apply_diff_to_table::
("table", &self.table); - diff.wall = cache.apply_diff_to_table::("wall", &self.wall); - - diff - } -} - -#[derive(Default)] -#[allow(non_snake_case)] -#[doc(hidden)] -pub struct AppliedDiff<'r> { - drawn: __sdk::TableAppliedDiff<'r, Drawn>, - hand: __sdk::TableAppliedDiff<'r, Hand>, - player: __sdk::TableAppliedDiff<'r, Player>, - table: __sdk::TableAppliedDiff<'r, Table>, - wall: __sdk::TableAppliedDiff<'r, Wall>, - __unused: std::marker::PhantomData<&'r ()>, -} - -impl __sdk::InModule for AppliedDiff<'_> { - type Module = RemoteModule; -} - -impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { - fn invoke_row_callbacks( - &self, - event: &EventContext, - callbacks: &mut __sdk::DbCallbacks, - ) { - callbacks.invoke_table_row_callbacks::("drawn", &self.drawn, event); - callbacks.invoke_table_row_callbacks::("hand", &self.hand, event); - callbacks.invoke_table_row_callbacks::("player", &self.player, event); - callbacks.invoke_table_row_callbacks::
("table", &self.table, event); - callbacks.invoke_table_row_callbacks::("wall", &self.wall, event); - } -} - -#[doc(hidden)] -pub struct RemoteModule; - -impl __sdk::InModule for RemoteModule { - type Module = Self; -} - -/// The `reducers` field of [`EventContext`] and [`DbConnection`], -/// with methods provided by extension traits for each reducer defined by the module. -pub struct RemoteReducers { - imp: __sdk::DbContextImpl, -} - -impl __sdk::InModule for RemoteReducers { - type Module = RemoteModule; -} - -/// The `procedures` field of [`DbConnection`] and other [`DbContext`] types, -/// with methods provided by extension traits for each procedure defined by the module. -pub struct RemoteProcedures { - imp: __sdk::DbContextImpl, -} - -impl __sdk::InModule for RemoteProcedures { - type Module = RemoteModule; -} - -#[doc(hidden)] -/// The `set_reducer_flags` field of [`DbConnection`], -/// with methods provided by extension traits for each reducer defined by the module. -/// Each method sets the flags for the reducer with the same name. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub struct SetReducerFlags { - imp: __sdk::DbContextImpl, -} - -impl __sdk::InModule for SetReducerFlags { - type Module = RemoteModule; -} - -/// The `db` field of [`EventContext`] and [`DbConnection`], -/// with methods provided by extension traits for each table defined by the module. -pub struct RemoteTables { - imp: __sdk::DbContextImpl, -} - -impl __sdk::InModule for RemoteTables { - type Module = RemoteModule; -} - -/// A connection to a remote module, including a materialized view of a subset of the database. -/// -/// Connect to a remote module by calling [`DbConnection::builder`] -/// and using the [`__sdk::DbConnectionBuilder`] builder-pattern constructor. -/// -/// You must explicitly advance the connection by calling any one of: -/// -/// - [`DbConnection::frame_tick`]. -/// - [`DbConnection::run_threaded`]. -/// - [`DbConnection::run_async`]. -/// - [`DbConnection::advance_one_message`]. -/// - [`DbConnection::advance_one_message_blocking`]. -/// - [`DbConnection::advance_one_message_async`]. -/// -/// Which of these methods you should call depends on the specific needs of your application, -/// but you must call one of them, or else the connection will never progress. -pub struct DbConnection { - /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. - pub db: RemoteTables, - /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. - pub reducers: RemoteReducers, - #[doc(hidden)] - /// Access to setting the call-flags of each reducer defined for each reducer defined by the module - /// via extension traits implemented for [`SetReducerFlags`]. - /// - /// This type is currently unstable and may be removed without a major version bump. - pub set_reducer_flags: SetReducerFlags, - - /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. - pub procedures: RemoteProcedures, - - imp: __sdk::DbContextImpl, -} - -impl __sdk::InModule for DbConnection { - type Module = RemoteModule; -} - -impl __sdk::DbContext for DbConnection { - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; - - fn db(&self) -> &Self::DbView { - &self.db - } - fn reducers(&self) -> &Self::Reducers { - &self.reducers - } - fn procedures(&self) -> &Self::Procedures { - &self.procedures - } - fn set_reducer_flags(&self) -> &Self::SetReducerFlags { - &self.set_reducer_flags - } - - fn is_active(&self) -> bool { - self.imp.is_active() - } - - fn disconnect(&self) -> __sdk::Result<()> { - self.imp.disconnect() - } - - type SubscriptionBuilder = __sdk::SubscriptionBuilder; - - fn subscription_builder(&self) -> Self::SubscriptionBuilder { - __sdk::SubscriptionBuilder::new(&self.imp) - } - - fn try_identity(&self) -> Option<__sdk::Identity> { - self.imp.try_identity() - } - fn connection_id(&self) -> __sdk::ConnectionId { - self.imp.connection_id() - } - fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { - self.imp.try_connection_id() - } -} - -impl DbConnection { - /// Builder-pattern constructor for a connection to a remote module. - /// - /// See [`__sdk::DbConnectionBuilder`] for required and optional configuration for the new connection. - pub fn builder() -> __sdk::DbConnectionBuilder { - __sdk::DbConnectionBuilder::new() - } - - /// If any WebSocket messages are waiting, process one of them. - /// - /// Returns `true` if a message was processed, or `false` if the queue is empty. - /// Callers should invoke this message in a loop until it returns `false` - /// or for as much time is available to process messages. - /// - /// Returns an error if the connection is disconnected. - /// If the disconnection in question was normal, - /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], - /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. - /// - /// This is a low-level primitive exposed for power users who need significant control over scheduling. - /// Most applications should call [`Self::frame_tick`] each frame - /// to fully exhaust the queue whenever time is available. - pub fn advance_one_message(&self) -> __sdk::Result { - self.imp.advance_one_message() - } - - /// Process one WebSocket message, potentially blocking the current thread until one is received. - /// - /// Returns an error if the connection is disconnected. - /// If the disconnection in question was normal, - /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], - /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. - /// - /// This is a low-level primitive exposed for power users who need significant control over scheduling. - /// Most applications should call [`Self::run_threaded`] to spawn a thread - /// which advances the connection automatically. - pub fn advance_one_message_blocking(&self) -> __sdk::Result<()> { - self.imp.advance_one_message_blocking() - } - - /// Process one WebSocket message, `await`ing until one is received. - /// - /// Returns an error if the connection is disconnected. - /// If the disconnection in question was normal, - /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], - /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. - /// - /// This is a low-level primitive exposed for power users who need significant control over scheduling. - /// Most applications should call [`Self::run_async`] to run an `async` loop - /// which advances the connection when polled. - pub async fn advance_one_message_async(&self) -> __sdk::Result<()> { - self.imp.advance_one_message_async().await - } - - /// Process all WebSocket messages waiting in the queue, - /// then return without `await`ing or blocking the current thread. - pub fn frame_tick(&self) -> __sdk::Result<()> { - self.imp.frame_tick() - } - - /// Spawn a thread which processes WebSocket messages as they are received. - pub fn run_threaded(&self) -> std::thread::JoinHandle<()> { - self.imp.run_threaded() - } - - /// Run an `async` loop which processes WebSocket messages when polled. - pub async fn run_async(&self) -> __sdk::Result<()> { - self.imp.run_async().await - } -} - -impl __sdk::DbConnection for DbConnection { - fn new(imp: __sdk::DbContextImpl) -> Self { - Self { - db: RemoteTables { imp: imp.clone() }, - reducers: RemoteReducers { imp: imp.clone() }, - procedures: RemoteProcedures { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, - imp, - } - } -} - -/// A handle on a subscribed query. -// TODO: Document this better after implementing the new subscription API. -#[derive(Clone)] -pub struct SubscriptionHandle { - imp: __sdk::SubscriptionHandleImpl, -} - -impl __sdk::InModule for SubscriptionHandle { - type Module = RemoteModule; -} - -impl __sdk::SubscriptionHandle for SubscriptionHandle { - fn new(imp: __sdk::SubscriptionHandleImpl) -> Self { - Self { imp } - } - - /// Returns true if this subscription has been terminated due to an unsubscribe call or an error. - fn is_ended(&self) -> bool { - self.imp.is_ended() - } - - /// Returns true if this subscription has been applied and has not yet been unsubscribed. - fn is_active(&self) -> bool { - self.imp.is_active() - } - - /// Unsubscribe from the query controlled by this `SubscriptionHandle`, - /// then run `on_end` when its rows are removed from the client cache. - fn unsubscribe_then(self, on_end: __sdk::OnEndedCallback) -> __sdk::Result<()> { - self.imp.unsubscribe_then(Some(on_end)) - } - - fn unsubscribe(self) -> __sdk::Result<()> { - self.imp.unsubscribe_then(None) - } -} - -/// Alias trait for a [`__sdk::DbContext`] connected to this module, -/// with that trait's associated types bounded to this module's concrete types. -/// -/// Users can use this trait as a boundary on definitions which should accept -/// either a [`DbConnection`] or an [`EventContext`] and operate on either. -pub trait RemoteDbContext: - __sdk::DbContext< - DbView = RemoteTables, - Reducers = RemoteReducers, - SetReducerFlags = SetReducerFlags, - SubscriptionBuilder = __sdk::SubscriptionBuilder, -> -{ -} -impl< - Ctx: __sdk::DbContext< - DbView = RemoteTables, - Reducers = RemoteReducers, - SetReducerFlags = SetReducerFlags, - SubscriptionBuilder = __sdk::SubscriptionBuilder, - >, - > RemoteDbContext for Ctx -{ -} - -/// An [`__sdk::DbContext`] augmented with a [`__sdk::Event`], -/// passed to [`__sdk::Table::on_insert`], [`__sdk::Table::on_delete`] and [`__sdk::TableWithPrimaryKey::on_update`] callbacks. -pub struct EventContext { - /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. - pub db: RemoteTables, - /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. - pub reducers: RemoteReducers, - /// Access to setting the call-flags of each reducer defined for each reducer defined by the module - /// via extension traits implemented for [`SetReducerFlags`]. - /// - /// This type is currently unstable and may be removed without a major version bump. - pub set_reducer_flags: SetReducerFlags, - /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. - pub procedures: RemoteProcedures, - /// The event which caused these callbacks to run. - pub event: __sdk::Event, - imp: __sdk::DbContextImpl, -} - -impl __sdk::AbstractEventContext for EventContext { - type Event = __sdk::Event; - fn event(&self) -> &Self::Event { - &self.event - } - fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { - Self { - db: RemoteTables { imp: imp.clone() }, - reducers: RemoteReducers { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, - procedures: RemoteProcedures { imp: imp.clone() }, - event, - imp, - } - } -} - -impl __sdk::InModule for EventContext { - type Module = RemoteModule; -} - -impl __sdk::DbContext for EventContext { - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; - - fn db(&self) -> &Self::DbView { - &self.db - } - fn reducers(&self) -> &Self::Reducers { - &self.reducers - } - fn procedures(&self) -> &Self::Procedures { - &self.procedures - } - fn set_reducer_flags(&self) -> &Self::SetReducerFlags { - &self.set_reducer_flags - } - - fn is_active(&self) -> bool { - self.imp.is_active() - } - - fn disconnect(&self) -> __sdk::Result<()> { - self.imp.disconnect() - } - - type SubscriptionBuilder = __sdk::SubscriptionBuilder; - - fn subscription_builder(&self) -> Self::SubscriptionBuilder { - __sdk::SubscriptionBuilder::new(&self.imp) - } - - fn try_identity(&self) -> Option<__sdk::Identity> { - self.imp.try_identity() - } - fn connection_id(&self) -> __sdk::ConnectionId { - self.imp.connection_id() - } - fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { - self.imp.try_connection_id() - } -} - -impl __sdk::EventContext for EventContext {} - -/// An [`__sdk::DbContext`] augmented with a [`__sdk::ReducerEvent`], -/// passed to on-reducer callbacks. -pub struct ReducerEventContext { - /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. - pub db: RemoteTables, - /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. - pub reducers: RemoteReducers, - /// Access to setting the call-flags of each reducer defined for each reducer defined by the module - /// via extension traits implemented for [`SetReducerFlags`]. - /// - /// This type is currently unstable and may be removed without a major version bump. - pub set_reducer_flags: SetReducerFlags, - /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. - pub procedures: RemoteProcedures, - /// The event which caused these callbacks to run. - pub event: __sdk::ReducerEvent, - imp: __sdk::DbContextImpl, -} - -impl __sdk::AbstractEventContext for ReducerEventContext { - type Event = __sdk::ReducerEvent; - fn event(&self) -> &Self::Event { - &self.event - } - fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { - Self { - db: RemoteTables { imp: imp.clone() }, - reducers: RemoteReducers { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, - procedures: RemoteProcedures { imp: imp.clone() }, - event, - imp, - } - } -} - -impl __sdk::InModule for ReducerEventContext { - type Module = RemoteModule; -} - -impl __sdk::DbContext for ReducerEventContext { - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; - - fn db(&self) -> &Self::DbView { - &self.db - } - fn reducers(&self) -> &Self::Reducers { - &self.reducers - } - fn procedures(&self) -> &Self::Procedures { - &self.procedures - } - fn set_reducer_flags(&self) -> &Self::SetReducerFlags { - &self.set_reducer_flags - } - - fn is_active(&self) -> bool { - self.imp.is_active() - } - - fn disconnect(&self) -> __sdk::Result<()> { - self.imp.disconnect() - } - - type SubscriptionBuilder = __sdk::SubscriptionBuilder; - - fn subscription_builder(&self) -> Self::SubscriptionBuilder { - __sdk::SubscriptionBuilder::new(&self.imp) - } - - fn try_identity(&self) -> Option<__sdk::Identity> { - self.imp.try_identity() - } - fn connection_id(&self) -> __sdk::ConnectionId { - self.imp.connection_id() - } - fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { - self.imp.try_connection_id() - } -} - -impl __sdk::ReducerEventContext for ReducerEventContext {} - -/// An [`__sdk::DbContext`] passed to procedure callbacks. -pub struct ProcedureEventContext { - /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. - pub db: RemoteTables, - /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. - pub reducers: RemoteReducers, - /// Access to setting the call-flags of each reducer defined for each reducer defined by the module - /// via extension traits implemented for [`SetReducerFlags`]. - /// - /// This type is currently unstable and may be removed without a major version bump. - pub set_reducer_flags: SetReducerFlags, - /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. - pub procedures: RemoteProcedures, - imp: __sdk::DbContextImpl, -} - -impl __sdk::AbstractEventContext for ProcedureEventContext { - type Event = (); - fn event(&self) -> &Self::Event { - &() - } - fn new(imp: __sdk::DbContextImpl, _event: Self::Event) -> Self { - Self { - db: RemoteTables { imp: imp.clone() }, - reducers: RemoteReducers { imp: imp.clone() }, - procedures: RemoteProcedures { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, - imp, - } - } -} - -impl __sdk::InModule for ProcedureEventContext { - type Module = RemoteModule; -} - -impl __sdk::DbContext for ProcedureEventContext { - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; - - fn db(&self) -> &Self::DbView { - &self.db - } - fn reducers(&self) -> &Self::Reducers { - &self.reducers - } - fn procedures(&self) -> &Self::Procedures { - &self.procedures - } - fn set_reducer_flags(&self) -> &Self::SetReducerFlags { - &self.set_reducer_flags - } - - fn is_active(&self) -> bool { - self.imp.is_active() - } - - fn disconnect(&self) -> __sdk::Result<()> { - self.imp.disconnect() - } - - type SubscriptionBuilder = __sdk::SubscriptionBuilder; - - fn subscription_builder(&self) -> Self::SubscriptionBuilder { - __sdk::SubscriptionBuilder::new(&self.imp) - } - - fn try_identity(&self) -> Option<__sdk::Identity> { - self.imp.try_identity() - } - fn connection_id(&self) -> __sdk::ConnectionId { - self.imp.connection_id() - } - fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { - self.imp.try_connection_id() - } -} - -impl __sdk::ProcedureEventContext for ProcedureEventContext {} - -/// An [`__sdk::DbContext`] passed to [`__sdk::SubscriptionBuilder::on_applied`] and [`SubscriptionHandle::unsubscribe_then`] callbacks. -pub struct SubscriptionEventContext { - /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. - pub db: RemoteTables, - /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. - pub reducers: RemoteReducers, - /// Access to setting the call-flags of each reducer defined for each reducer defined by the module - /// via extension traits implemented for [`SetReducerFlags`]. - /// - /// This type is currently unstable and may be removed without a major version bump. - pub set_reducer_flags: SetReducerFlags, - /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. - pub procedures: RemoteProcedures, - imp: __sdk::DbContextImpl, -} - -impl __sdk::AbstractEventContext for SubscriptionEventContext { - type Event = (); - fn event(&self) -> &Self::Event { - &() - } - fn new(imp: __sdk::DbContextImpl, _event: Self::Event) -> Self { - Self { - db: RemoteTables { imp: imp.clone() }, - reducers: RemoteReducers { imp: imp.clone() }, - procedures: RemoteProcedures { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, - imp, - } - } -} - -impl __sdk::InModule for SubscriptionEventContext { - type Module = RemoteModule; -} - -impl __sdk::DbContext for SubscriptionEventContext { - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; - - fn db(&self) -> &Self::DbView { - &self.db - } - fn reducers(&self) -> &Self::Reducers { - &self.reducers - } - fn procedures(&self) -> &Self::Procedures { - &self.procedures - } - fn set_reducer_flags(&self) -> &Self::SetReducerFlags { - &self.set_reducer_flags - } - - fn is_active(&self) -> bool { - self.imp.is_active() - } - - fn disconnect(&self) -> __sdk::Result<()> { - self.imp.disconnect() - } - - type SubscriptionBuilder = __sdk::SubscriptionBuilder; - - fn subscription_builder(&self) -> Self::SubscriptionBuilder { - __sdk::SubscriptionBuilder::new(&self.imp) - } - - fn try_identity(&self) -> Option<__sdk::Identity> { - self.imp.try_identity() - } - fn connection_id(&self) -> __sdk::ConnectionId { - self.imp.connection_id() - } - fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { - self.imp.try_connection_id() - } -} - -impl __sdk::SubscriptionEventContext for SubscriptionEventContext {} - -/// An [`__sdk::DbContext`] augmented with a [`__sdk::Error`], -/// passed to [`__sdk::DbConnectionBuilder::on_disconnect`], [`__sdk::DbConnectionBuilder::on_connect_error`] and [`__sdk::SubscriptionBuilder::on_error`] callbacks. -pub struct ErrorContext { - /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. - pub db: RemoteTables, - /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. - pub reducers: RemoteReducers, - /// Access to setting the call-flags of each reducer defined for each reducer defined by the module - /// via extension traits implemented for [`SetReducerFlags`]. - /// - /// This type is currently unstable and may be removed without a major version bump. - pub set_reducer_flags: SetReducerFlags, - /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. - pub procedures: RemoteProcedures, - /// The event which caused these callbacks to run. - pub event: Option<__sdk::Error>, - imp: __sdk::DbContextImpl, -} - -impl __sdk::AbstractEventContext for ErrorContext { - type Event = Option<__sdk::Error>; - fn event(&self) -> &Self::Event { - &self.event - } - fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { - Self { - db: RemoteTables { imp: imp.clone() }, - reducers: RemoteReducers { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, - procedures: RemoteProcedures { imp: imp.clone() }, - event, - imp, - } - } -} - -impl __sdk::InModule for ErrorContext { - type Module = RemoteModule; -} - -impl __sdk::DbContext for ErrorContext { - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; - - fn db(&self) -> &Self::DbView { - &self.db - } - fn reducers(&self) -> &Self::Reducers { - &self.reducers - } - fn procedures(&self) -> &Self::Procedures { - &self.procedures - } - fn set_reducer_flags(&self) -> &Self::SetReducerFlags { - &self.set_reducer_flags - } - - fn is_active(&self) -> bool { - self.imp.is_active() - } - - fn disconnect(&self) -> __sdk::Result<()> { - self.imp.disconnect() - } - - type SubscriptionBuilder = __sdk::SubscriptionBuilder; - - fn subscription_builder(&self) -> Self::SubscriptionBuilder { - __sdk::SubscriptionBuilder::new(&self.imp) - } - - fn try_identity(&self) -> Option<__sdk::Identity> { - self.imp.try_identity() - } - fn connection_id(&self) -> __sdk::ConnectionId { - self.imp.connection_id() - } - fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { - self.imp.try_connection_id() - } -} - -impl __sdk::ErrorContext for ErrorContext {} - -impl __sdk::SpacetimeModule for RemoteModule { - type DbConnection = DbConnection; - type EventContext = EventContext; - type ReducerEventContext = ReducerEventContext; - type ProcedureEventContext = ProcedureEventContext; - type SubscriptionEventContext = SubscriptionEventContext; - type ErrorContext = ErrorContext; - type Reducer = Reducer; - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type SetReducerFlags = SetReducerFlags; - type DbUpdate = DbUpdate; - type AppliedDiff<'r> = AppliedDiff<'r>; - type SubscriptionHandle = SubscriptionHandle; - - fn register_tables(client_cache: &mut __sdk::ClientCache) { - drawn_table::register_table(client_cache); - hand_table::register_table(client_cache); - player_table::register_table(client_cache); - table_table::register_table(client_cache); - wall_table::register_table(client_cache); - } -} diff --git a/jong/src/jongline_bindings/player_table.rs b/jong/src/jongline_bindings/player_table.rs deleted file mode 100644 index 3014fc8..0000000 --- a/jong/src/jongline_bindings/player_table.rs +++ /dev/null @@ -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::player_type::Player; -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -/// Table handle for the table `player`. -/// -/// Obtain a handle from the [`PlayerTableAccess::player`] method on [`super::RemoteTables`], -/// like `ctx.db.player()`. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.player().on_insert(...)`. -pub struct PlayerTableHandle<'ctx> { - imp: __sdk::TableHandle, - ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -#[allow(non_camel_case_types)] -/// Extension trait for access to the table `player`. -/// -/// Implemented for [`super::RemoteTables`]. -pub trait PlayerTableAccess { - #[allow(non_snake_case)] - /// Obtain a [`PlayerTableHandle`], which mediates access to the table `player`. - fn player(&self) -> PlayerTableHandle<'_>; -} - -impl PlayerTableAccess for super::RemoteTables { - fn player(&self) -> PlayerTableHandle<'_> { - PlayerTableHandle { - imp: self.imp.get_table::("player"), - ctx: std::marker::PhantomData, - } - } -} - -pub struct PlayerInsertCallbackId(__sdk::CallbackId); -pub struct PlayerDeleteCallbackId(__sdk::CallbackId); - -impl<'ctx> __sdk::Table for PlayerTableHandle<'ctx> { - type Row = Player; - type EventContext = super::EventContext; - - fn count(&self) -> u64 { - self.imp.count() - } - fn iter(&self) -> impl Iterator + '_ { - self.imp.iter() - } - - type InsertCallbackId = PlayerInsertCallbackId; - - fn on_insert( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> PlayerInsertCallbackId { - PlayerInsertCallbackId(self.imp.on_insert(Box::new(callback))) - } - - fn remove_on_insert(&self, callback: PlayerInsertCallbackId) { - self.imp.remove_on_insert(callback.0) - } - - type DeleteCallbackId = PlayerDeleteCallbackId; - - fn on_delete( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> PlayerDeleteCallbackId { - PlayerDeleteCallbackId(self.imp.on_delete(Box::new(callback))) - } - - fn remove_on_delete(&self, callback: PlayerDeleteCallbackId) { - self.imp.remove_on_delete(callback.0) - } -} - -#[doc(hidden)] -pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { - let _table = client_cache.get_or_make_table::("player"); -} - -#[doc(hidden)] -pub(super) fn parse_table_update( - raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, -) -> __sdk::Result<__sdk::TableUpdate> { - __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { - __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") - .with_cause(e) - .into() - }) -} diff --git a/jong/src/jongline_bindings/player_type.rs b/jong/src/jongline_bindings/player_type.rs deleted file mode 100644 index 871ae30..0000000 --- a/jong/src/jongline_bindings/player_type.rs +++ /dev/null @@ -1,17 +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 struct Player { - pub username: String, - pub identity: __sdk::Identity, - pub connection_id: __sdk::ConnectionId, -} - -impl __sdk::InModule for Player { - type Module = super::RemoteModule; -} diff --git a/jong/src/jongline_bindings/table_table.rs b/jong/src/jongline_bindings/table_table.rs deleted file mode 100644 index 9b05b54..0000000 --- a/jong/src/jongline_bindings/table_table.rs +++ /dev/null @@ -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
, - 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"), - 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 + '_ { - 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) { - let _table = client_cache.get_or_make_table::
("table"); -} - -#[doc(hidden)] -pub(super) fn parse_table_update( - raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, -) -> __sdk::Result<__sdk::TableUpdate
> { - __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { - __sdk::InternalError::failed_parse("TableUpdate
", "TableUpdate") - .with_cause(e) - .into() - }) -} diff --git a/jong/src/jongline_bindings/table_type.rs b/jong/src/jongline_bindings/table_type.rs deleted file mode 100644 index 4d03385..0000000 --- a/jong/src/jongline_bindings/table_type.rs +++ /dev/null @@ -1,19 +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}; - -use super::hand_type::Hand; -use super::player_type::Player; - -#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] -#[sats(crate = __lib)] -pub struct Table { - pub players: Player, - pub hands: Vec, -} - -impl __sdk::InModule for Table { - type Module = super::RemoteModule; -} diff --git a/jong/src/jongline_bindings/wall_table.rs b/jong/src/jongline_bindings/wall_table.rs deleted file mode 100644 index 8657bf9..0000000 --- a/jong/src/jongline_bindings/wall_table.rs +++ /dev/null @@ -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::wall_type::Wall; -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -/// Table handle for the table `wall`. -/// -/// Obtain a handle from the [`WallTableAccess::wall`] method on [`super::RemoteTables`], -/// like `ctx.db.wall()`. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.wall().on_insert(...)`. -pub struct WallTableHandle<'ctx> { - imp: __sdk::TableHandle, - ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -#[allow(non_camel_case_types)] -/// Extension trait for access to the table `wall`. -/// -/// Implemented for [`super::RemoteTables`]. -pub trait WallTableAccess { - #[allow(non_snake_case)] - /// Obtain a [`WallTableHandle`], which mediates access to the table `wall`. - fn wall(&self) -> WallTableHandle<'_>; -} - -impl WallTableAccess for super::RemoteTables { - fn wall(&self) -> WallTableHandle<'_> { - WallTableHandle { - imp: self.imp.get_table::("wall"), - ctx: std::marker::PhantomData, - } - } -} - -pub struct WallInsertCallbackId(__sdk::CallbackId); -pub struct WallDeleteCallbackId(__sdk::CallbackId); - -impl<'ctx> __sdk::Table for WallTableHandle<'ctx> { - type Row = Wall; - type EventContext = super::EventContext; - - fn count(&self) -> u64 { - self.imp.count() - } - fn iter(&self) -> impl Iterator + '_ { - self.imp.iter() - } - - type InsertCallbackId = WallInsertCallbackId; - - fn on_insert( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> WallInsertCallbackId { - WallInsertCallbackId(self.imp.on_insert(Box::new(callback))) - } - - fn remove_on_insert(&self, callback: WallInsertCallbackId) { - self.imp.remove_on_insert(callback.0) - } - - type DeleteCallbackId = WallDeleteCallbackId; - - fn on_delete( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> WallDeleteCallbackId { - WallDeleteCallbackId(self.imp.on_delete(Box::new(callback))) - } - - fn remove_on_delete(&self, callback: WallDeleteCallbackId) { - self.imp.remove_on_delete(callback.0) - } -} - -#[doc(hidden)] -pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { - let _table = client_cache.get_or_make_table::("wall"); -} - -#[doc(hidden)] -pub(super) fn parse_table_update( - raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, -) -> __sdk::Result<__sdk::TableUpdate> { - __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { - __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") - .with_cause(e) - .into() - }) -} diff --git a/jong/src/jongline_bindings/wall_type.rs b/jong/src/jongline_bindings/wall_type.rs deleted file mode 100644 index 2056ff5..0000000 --- a/jong/src/jongline_bindings/wall_type.rs +++ /dev/null @@ -1,13 +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 struct Wall {} - -impl __sdk::InModule for Wall { - type Module = super::RemoteModule; -} diff --git a/jong/src/lib.rs b/jong/src/lib.rs index 4fcaff4..eaa491e 100644 --- a/jong/src/lib.rs +++ b/jong/src/lib.rs @@ -3,8 +3,8 @@ use bevy::prelude::*; use bevy_spacetimedb::StdbConnection; -mod jongline_bindings; -use jongline_bindings::*; +// mod jongline_bindings; +// use jongline_bindings::*; pub mod game; pub mod tile; @@ -14,4 +14,4 @@ trait EnumNextCycle { fn next(&self) -> Self; } -pub type SpacetimeDb<'a> = Res<'a, StdbConnection>; +// pub type SpacetimeDb<'a> = Res<'a, StdbConnection>; diff --git a/jong/src/main.rs b/jong/src/main.rs index 2b2c4d3..53ed662 100644 --- a/jong/src/main.rs +++ b/jong/src/main.rs @@ -47,13 +47,13 @@ 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( + // 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); diff --git a/jong/src/tui/input/keyboard.rs b/jong/src/tui/input/keyboard.rs index 62e8648..b879f77 100644 --- a/jong/src/tui/input/keyboard.rs +++ b/jong/src/tui/input/keyboard.rs @@ -1,6 +1,7 @@ use bevy::prelude::*; +use bevy_ratatui::crossterm::event::KeyCode; use bevy_ratatui::event::KeyMessage; -use ratatui::crossterm::event::KeyCode; +// use ratatui::crossterm::event::KeyCode; use tui_logger::TuiWidgetEvent; use jong::game::GameState; diff --git a/jong/src/tui/input/mouse.rs b/jong/src/tui/input/mouse.rs index cf86f04..c828eec 100644 --- a/jong/src/tui/input/mouse.rs +++ b/jong/src/tui/input/mouse.rs @@ -1,4 +1,5 @@ use bevy::prelude::*; +use bevy_ratatui::crossterm::event::{MouseButton, MouseEventKind}; use bevy_ratatui::event::MouseMessage; use ratatui::layout::Position; @@ -21,8 +22,8 @@ pub(crate) fn mouse( let position = Position::new(event.column, event.row); match event.kind { #[allow(clippy::single_match)] - ratatui::crossterm::event::MouseEventKind::Down(mouse_button) => match mouse_button { - ratatui::crossterm::event::MouseButton::Left => { + MouseEventKind::Down(mouse_button) => match mouse_button { + MouseButton::Left => { for (entity, region) in &entities { if region.area.contains(position) { 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::MouseEventKind::Moved => { + MouseEventKind::Moved => { for (entity, region) in &hovered { if !region.area.contains(position) { commands.entity(entity).remove::(); @@ -46,8 +47,8 @@ pub(crate) fn mouse( } } } - ratatui::crossterm::event::MouseEventKind::Up(mouse_button) => match mouse_button { - ratatui::crossterm::event::MouseButton::Left => { + MouseEventKind::Up(mouse_button) => match mouse_button { + MouseButton::Left => { for (entity, region) in &startselected { if region.area.contains(position) { commands.entity(entity).remove::(); @@ -55,7 +56,7 @@ pub(crate) fn mouse( } } } - ratatui::crossterm::event::MouseButton::Right => { + MouseButton::Right => { for (entity, _) in &startselected { commands.entity(entity).remove::(); } @@ -63,19 +64,19 @@ pub(crate) fn mouse( // ratatui::crossterm::event::MouseButton::Middle => debug!("unhandled mouse event"), _ => {} }, - ratatui::crossterm::event::MouseEventKind::Drag(mouse_button) => { + MouseEventKind::Drag(mouse_button) => { // debug!("unhandled mouse event") } - ratatui::crossterm::event::MouseEventKind::ScrollDown => { + MouseEventKind::ScrollDown => { // debug!("unhandled mouse event") } - ratatui::crossterm::event::MouseEventKind::ScrollUp => { + MouseEventKind::ScrollUp => { // debug!("unhandled mouse event") } - ratatui::crossterm::event::MouseEventKind::ScrollLeft => { + MouseEventKind::ScrollLeft => { // debug!("unhandled mouse event") } - ratatui::crossterm::event::MouseEventKind::ScrollRight => { + MouseEventKind::ScrollRight => { // debug!("unhandled mouse event") } } diff --git a/jongline/Cargo.toml b/jongline/Cargo.toml deleted file mode 100644 index 7667498..0000000 --- a/jongline/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "jongline" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib"] - -[dependencies] -spacetimedb = "1.11.*" -log = "0.4" -# jong = { version = "0.1.0", path = "../jong" } diff --git a/jongline/src/lib.rs b/jongline/src/lib.rs deleted file mode 100644 index 257a2f1..0000000 --- a/jongline/src/lib.rs +++ /dev/null @@ -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, -} - -#[spacetimedb::table(name = wall)] -pub struct Wall { - // tiles: Vec, -} - -#[spacetimedb::table(name = hand)] -pub struct Hand { - // hand: Vec, -} - -#[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!"); -// } From 3ca8574a6e8c12fadaaf879e7c82d926e4e50b80 Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Fri, 6 Feb 2026 23:51:08 -0800 Subject: [PATCH 02/11] reinit spacetimedb --- Cargo.lock | 81 +- Cargo.toml | 4 +- justfile | 3 +- module_bindings/add_reducer.rs | 102 ++ module_bindings/identity_connected_reducer.rs | 101 ++ .../identity_disconnected_reducer.rs | 103 ++ module_bindings/mod.rs | 876 ++++++++++++++++++ module_bindings/person_table.rs | 95 ++ module_bindings/person_type.rs | 15 + module_bindings/say_hello_reducer.rs | 100 ++ spacetimedb/Cargo.toml | 13 + spacetimedb/src/lib.rs | 61 ++ src/module_bindings/add_reducer.rs | 102 ++ .../identity_connected_reducer.rs | 101 ++ .../identity_disconnected_reducer.rs | 103 ++ src/module_bindings/mod.rs | 876 ++++++++++++++++++ src/module_bindings/person_table.rs | 95 ++ src/module_bindings/person_type.rs | 15 + src/module_bindings/say_hello_reducer.rs | 100 ++ 19 files changed, 2934 insertions(+), 12 deletions(-) create mode 100644 module_bindings/add_reducer.rs create mode 100644 module_bindings/identity_connected_reducer.rs create mode 100644 module_bindings/identity_disconnected_reducer.rs create mode 100644 module_bindings/mod.rs create mode 100644 module_bindings/person_table.rs create mode 100644 module_bindings/person_type.rs create mode 100644 module_bindings/say_hello_reducer.rs create mode 100644 spacetimedb/Cargo.toml create mode 100644 spacetimedb/src/lib.rs create mode 100644 src/module_bindings/add_reducer.rs create mode 100644 src/module_bindings/identity_connected_reducer.rs create mode 100644 src/module_bindings/identity_disconnected_reducer.rs create mode 100644 src/module_bindings/mod.rs create mode 100644 src/module_bindings/person_table.rs create mode 100644 src/module_bindings/person_type.rs create mode 100644 src/module_bindings/say_hello_reducer.rs diff --git a/Cargo.lock b/Cargo.lock index b9331ed..28043e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,7 +97,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -1173,7 +1173,7 @@ dependencies = [ "critical-section", "foldhash 0.2.0", "futures-channel", - "getrandom", + "getrandom 0.3.4", "hashbrown 0.16.1", "js-sys", "portable-atomic", @@ -3083,6 +3083,17 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "getrandom" version = "0.3.4" @@ -3721,7 +3732,7 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom", + "getrandom 0.3.4", "libc", ] @@ -3742,6 +3753,14 @@ dependencies = [ "tui-logger", ] +[[package]] +name = "jongline" +version = "0.1.0" +dependencies = [ + "log", + "spacetimedb", +] + [[package]] name = "js-sys" version = "0.3.85" @@ -5038,6 +5057,8 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ + "libc", + "rand_chacha 0.3.1", "rand_core 0.6.4", ] @@ -5047,10 +5068,20 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0", "rand_core 0.9.5", ] +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.9.0" @@ -5066,6 +5097,9 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] [[package]] name = "rand_core" @@ -5073,7 +5107,7 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ - "getrandom", + "getrandom 0.3.4", ] [[package]] @@ -5780,6 +5814,28 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "spacetimedb" +version = "1.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83af98280374b59796296f512f7855fd19e19240a358bb7706a54f1c4e4e7dff" +dependencies = [ + "anyhow", + "bytemuck", + "bytes", + "derive_more 0.99.20", + "getrandom 0.2.17", + "http", + "log", + "rand 0.8.5", + "scoped-tls", + "serde_json", + "spacetimedb-bindings-macro", + "spacetimedb-bindings-sys", + "spacetimedb-lib", + "spacetimedb-primitives", +] + [[package]] name = "spacetimedb-bindings-macro" version = "1.11.3" @@ -5794,6 +5850,15 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "spacetimedb-bindings-sys" +version = "1.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0d30e1655731b1564b7094a6213ef6c354ea920e3c04424e55ad377a1bc3e2" +dependencies = [ + "spacetimedb-primitives", +] + [[package]] name = "spacetimedb-client-api-messages" version = "1.11.3" @@ -6124,7 +6189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", - "getrandom", + "getrandom 0.3.4", "once_cell", "rustix 1.1.3", "windows-sys 0.61.2", @@ -6702,7 +6767,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" dependencies = [ "atomic", - "getrandom", + "getrandom 0.3.4", "js-sys", "serde_core", "wasm-bindgen", @@ -6980,7 +7045,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "692daff6d93d94e29e4114544ef6d5c942a7ed998b37abdc19b17136ea428eb7" dependencies = [ - "getrandom", + "getrandom 0.3.4", "mac_address", "sha2", "thiserror 1.0.69", diff --git a/Cargo.toml b/Cargo.toml index 66302f6..c5968cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "3" -members = ["jong"] +members = ["jong", "spacetimedb"] [workspace.dependencies] bevy = "0.17.3" @@ -22,4 +22,4 @@ opt-level = 1 opt-level = 3 [patch.crates-io] -bevy_ratatui = {path = "/home/tao/clones/bevy_ratatui"} +bevy_ratatui = { path = "/home/tao/clones/bevy_ratatui" } diff --git a/justfile b/justfile index 61f0930..7285e79 100644 --- a/justfile +++ b/justfile @@ -14,5 +14,4 @@ update: nix flake update spacetime: - spacetime build --project-path jongline - spacetime generate --lang rust --project-path jongline --out-dir jong/src/jongline_bindings + spacetime dev --module-bindings-path modules_bindings diff --git a/module_bindings/add_reducer.rs b/module_bindings/add_reducer.rs new file mode 100644 index 0000000..5bfecc3 --- /dev/null +++ b/module_bindings/add_reducer.rs @@ -0,0 +1,102 @@ +// 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 AddArgs { + pub name: String, +} + +impl From for super::Reducer { + fn from(args: AddArgs) -> Self { + Self::Add { name: args.name } + } +} + +impl __sdk::InModule for AddArgs { + type Module = super::RemoteModule; +} + +pub struct AddCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `add`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait add { + /// Request that the remote module invoke the reducer `add` 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`] callbacks. + fn add(&self, name: String) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `add`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`AddCallbackId`] can be passed to [`Self::remove_on_add`] + /// to cancel the callback. + fn on_add( + &self, + callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, + ) -> AddCallbackId; + /// Cancel a callback previously registered by [`Self::on_add`], + /// causing it not to run in the future. + fn remove_on_add(&self, callback: AddCallbackId); +} + +impl add for super::RemoteReducers { + fn add(&self, name: String) -> __sdk::Result<()> { + self.imp.call_reducer("add", AddArgs { name }) + } + fn on_add( + &self, + mut callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, + ) -> AddCallbackId { + AddCallbackId(self.imp.on_reducer( + "add", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::Add { name }, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx, name) + }), + )) + } + fn remove_on_add(&self, callback: AddCallbackId) { + self.imp.remove_on_reducer("add", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `add`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_add { + /// Set the call-reducer flags for the reducer `add` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn add(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_add for super::SetReducerFlags { + fn add(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("add", flags); + } +} diff --git a/module_bindings/identity_connected_reducer.rs b/module_bindings/identity_connected_reducer.rs new file mode 100644 index 0000000..2eaaab0 --- /dev/null +++ b/module_bindings/identity_connected_reducer.rs @@ -0,0 +1,101 @@ +// 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 IdentityConnectedArgs {} + +impl From for super::Reducer { + fn from(args: IdentityConnectedArgs) -> Self { + Self::IdentityConnected + } +} + +impl __sdk::InModule for IdentityConnectedArgs { + type Module = super::RemoteModule; +} + +pub struct IdentityConnectedCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `identity_connected`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait identity_connected { + /// Request that the remote module invoke the reducer `identity_connected` 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_connected`] callbacks. + fn identity_connected(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `identity_connected`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`IdentityConnectedCallbackId`] can be passed to [`Self::remove_on_identity_connected`] + /// to cancel the callback. + fn on_identity_connected( + &self, + callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> IdentityConnectedCallbackId; + /// Cancel a callback previously registered by [`Self::on_identity_connected`], + /// causing it not to run in the future. + fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId); +} + +impl identity_connected for super::RemoteReducers { + fn identity_connected(&self) -> __sdk::Result<()> { + self.imp + .call_reducer("identity_connected", IdentityConnectedArgs {}) + } + fn on_identity_connected( + &self, + mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> IdentityConnectedCallbackId { + IdentityConnectedCallbackId(self.imp.on_reducer( + "identity_connected", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::IdentityConnected {}, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx) + }), + )) + } + fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId) { + self.imp.remove_on_reducer("identity_connected", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `identity_connected`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_identity_connected { + /// Set the call-reducer flags for the reducer `identity_connected` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn identity_connected(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_identity_connected for super::SetReducerFlags { + fn identity_connected(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("identity_connected", flags); + } +} diff --git a/module_bindings/identity_disconnected_reducer.rs b/module_bindings/identity_disconnected_reducer.rs new file mode 100644 index 0000000..c2892ed --- /dev/null +++ b/module_bindings/identity_disconnected_reducer.rs @@ -0,0 +1,103 @@ +// 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 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); + } +} diff --git a/module_bindings/mod.rs b/module_bindings/mod.rs new file mode 100644 index 0000000..e89f725 --- /dev/null +++ b/module_bindings/mod.rs @@ -0,0 +1,876 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +// This was generated using spacetimedb cli version 1.11.3 (commit 02449737ca3b29e7e39679fccbef541a50f32094). + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +pub mod add_reducer; +pub mod identity_connected_reducer; +pub mod identity_disconnected_reducer; +pub mod person_table; +pub mod person_type; +pub mod say_hello_reducer; + +pub use add_reducer::{add, set_flags_for_add, AddCallbackId}; +pub use identity_connected_reducer::{ + identity_connected, set_flags_for_identity_connected, IdentityConnectedCallbackId, +}; +pub use identity_disconnected_reducer::{ + identity_disconnected, set_flags_for_identity_disconnected, IdentityDisconnectedCallbackId, +}; +pub use person_table::*; +pub use person_type::Person; +pub use say_hello_reducer::{say_hello, set_flags_for_say_hello, SayHelloCallbackId}; + +#[derive(Clone, PartialEq, Debug)] + +/// One of the reducers defined by this module. +/// +/// Contained within a [`__sdk::ReducerEvent`] in [`EventContext`]s for reducer events +/// to indicate which reducer caused the event. + +pub enum Reducer { + Add { name: String }, + IdentityConnected, + IdentityDisconnected, + SayHello, +} + +impl __sdk::InModule for Reducer { + type Module = RemoteModule; +} + +impl __sdk::Reducer for Reducer { + fn reducer_name(&self) -> &'static str { + match self { + Reducer::Add { .. } => "add", + Reducer::IdentityConnected => "identity_connected", + Reducer::IdentityDisconnected => "identity_disconnected", + Reducer::SayHello => "say_hello", + _ => unreachable!(), + } + } +} +impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { + type Error = __sdk::Error; + fn try_from(value: __ws::ReducerCallInfo<__ws::BsatnFormat>) -> __sdk::Result { + match &value.reducer_name[..] { + "add" => { + Ok(__sdk::parse_reducer_args::("add", &value.args)?.into()) + } + "identity_connected" => Ok(__sdk::parse_reducer_args::< + identity_connected_reducer::IdentityConnectedArgs, + >("identity_connected", &value.args)? + .into()), + "identity_disconnected" => Ok(__sdk::parse_reducer_args::< + identity_disconnected_reducer::IdentityDisconnectedArgs, + >("identity_disconnected", &value.args)? + .into()), + "say_hello" => Ok( + __sdk::parse_reducer_args::( + "say_hello", + &value.args, + )? + .into(), + ), + unknown => { + Err( + __sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo") + .into(), + ) + } + } + } +} + +#[derive(Default)] +#[allow(non_snake_case)] +#[doc(hidden)] +pub struct DbUpdate { + person: __sdk::TableUpdate, +} + +impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { + type Error = __sdk::Error; + fn try_from(raw: __ws::DatabaseUpdate<__ws::BsatnFormat>) -> Result { + let mut db_update = DbUpdate::default(); + for table_update in raw.tables { + match &table_update.table_name[..] { + "person" => db_update + .person + .append(person_table::parse_table_update(table_update)?), + + unknown => { + return Err(__sdk::InternalError::unknown_name( + "table", + unknown, + "DatabaseUpdate", + ) + .into()); + } + } + } + Ok(db_update) + } +} + +impl __sdk::InModule for DbUpdate { + type Module = RemoteModule; +} + +impl __sdk::DbUpdate for DbUpdate { + fn apply_to_client_cache( + &self, + cache: &mut __sdk::ClientCache, + ) -> AppliedDiff<'_> { + let mut diff = AppliedDiff::default(); + + diff.person = cache.apply_diff_to_table::("person", &self.person); + + diff + } +} + +#[derive(Default)] +#[allow(non_snake_case)] +#[doc(hidden)] +pub struct AppliedDiff<'r> { + person: __sdk::TableAppliedDiff<'r, Person>, + __unused: std::marker::PhantomData<&'r ()>, +} + +impl __sdk::InModule for AppliedDiff<'_> { + type Module = RemoteModule; +} + +impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { + fn invoke_row_callbacks( + &self, + event: &EventContext, + callbacks: &mut __sdk::DbCallbacks, + ) { + callbacks.invoke_table_row_callbacks::("person", &self.person, event); + } +} + +#[doc(hidden)] +pub struct RemoteModule; + +impl __sdk::InModule for RemoteModule { + type Module = Self; +} + +/// The `reducers` field of [`EventContext`] and [`DbConnection`], +/// with methods provided by extension traits for each reducer defined by the module. +pub struct RemoteReducers { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for RemoteReducers { + type Module = RemoteModule; +} + +/// The `procedures` field of [`DbConnection`] and other [`DbContext`] types, +/// with methods provided by extension traits for each procedure defined by the module. +pub struct RemoteProcedures { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for RemoteProcedures { + type Module = RemoteModule; +} + +#[doc(hidden)] +/// The `set_reducer_flags` field of [`DbConnection`], +/// with methods provided by extension traits for each reducer defined by the module. +/// Each method sets the flags for the reducer with the same name. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub struct SetReducerFlags { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for SetReducerFlags { + type Module = RemoteModule; +} + +/// The `db` field of [`EventContext`] and [`DbConnection`], +/// with methods provided by extension traits for each table defined by the module. +pub struct RemoteTables { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for RemoteTables { + type Module = RemoteModule; +} + +/// A connection to a remote module, including a materialized view of a subset of the database. +/// +/// Connect to a remote module by calling [`DbConnection::builder`] +/// and using the [`__sdk::DbConnectionBuilder`] builder-pattern constructor. +/// +/// You must explicitly advance the connection by calling any one of: +/// +/// - [`DbConnection::frame_tick`]. +/// - [`DbConnection::run_threaded`]. +/// - [`DbConnection::run_async`]. +/// - [`DbConnection::advance_one_message`]. +/// - [`DbConnection::advance_one_message_blocking`]. +/// - [`DbConnection::advance_one_message_async`]. +/// +/// Which of these methods you should call depends on the specific needs of your application, +/// but you must call one of them, or else the connection will never progress. +pub struct DbConnection { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + #[doc(hidden)] + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for DbConnection { + type Module = RemoteModule; +} + +impl __sdk::DbContext for DbConnection { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl DbConnection { + /// Builder-pattern constructor for a connection to a remote module. + /// + /// See [`__sdk::DbConnectionBuilder`] for required and optional configuration for the new connection. + pub fn builder() -> __sdk::DbConnectionBuilder { + __sdk::DbConnectionBuilder::new() + } + + /// If any WebSocket messages are waiting, process one of them. + /// + /// Returns `true` if a message was processed, or `false` if the queue is empty. + /// Callers should invoke this message in a loop until it returns `false` + /// or for as much time is available to process messages. + /// + /// Returns an error if the connection is disconnected. + /// If the disconnection in question was normal, + /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], + /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. + /// + /// This is a low-level primitive exposed for power users who need significant control over scheduling. + /// Most applications should call [`Self::frame_tick`] each frame + /// to fully exhaust the queue whenever time is available. + pub fn advance_one_message(&self) -> __sdk::Result { + self.imp.advance_one_message() + } + + /// Process one WebSocket message, potentially blocking the current thread until one is received. + /// + /// Returns an error if the connection is disconnected. + /// If the disconnection in question was normal, + /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], + /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. + /// + /// This is a low-level primitive exposed for power users who need significant control over scheduling. + /// Most applications should call [`Self::run_threaded`] to spawn a thread + /// which advances the connection automatically. + pub fn advance_one_message_blocking(&self) -> __sdk::Result<()> { + self.imp.advance_one_message_blocking() + } + + /// Process one WebSocket message, `await`ing until one is received. + /// + /// Returns an error if the connection is disconnected. + /// If the disconnection in question was normal, + /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], + /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. + /// + /// This is a low-level primitive exposed for power users who need significant control over scheduling. + /// Most applications should call [`Self::run_async`] to run an `async` loop + /// which advances the connection when polled. + pub async fn advance_one_message_async(&self) -> __sdk::Result<()> { + self.imp.advance_one_message_async().await + } + + /// Process all WebSocket messages waiting in the queue, + /// then return without `await`ing or blocking the current thread. + pub fn frame_tick(&self) -> __sdk::Result<()> { + self.imp.frame_tick() + } + + /// Spawn a thread which processes WebSocket messages as they are received. + pub fn run_threaded(&self) -> std::thread::JoinHandle<()> { + self.imp.run_threaded() + } + + /// Run an `async` loop which processes WebSocket messages when polled. + pub async fn run_async(&self) -> __sdk::Result<()> { + self.imp.run_async().await + } +} + +impl __sdk::DbConnection for DbConnection { + fn new(imp: __sdk::DbContextImpl) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + imp, + } + } +} + +/// A handle on a subscribed query. +// TODO: Document this better after implementing the new subscription API. +#[derive(Clone)] +pub struct SubscriptionHandle { + imp: __sdk::SubscriptionHandleImpl, +} + +impl __sdk::InModule for SubscriptionHandle { + type Module = RemoteModule; +} + +impl __sdk::SubscriptionHandle for SubscriptionHandle { + fn new(imp: __sdk::SubscriptionHandleImpl) -> Self { + Self { imp } + } + + /// Returns true if this subscription has been terminated due to an unsubscribe call or an error. + fn is_ended(&self) -> bool { + self.imp.is_ended() + } + + /// Returns true if this subscription has been applied and has not yet been unsubscribed. + fn is_active(&self) -> bool { + self.imp.is_active() + } + + /// Unsubscribe from the query controlled by this `SubscriptionHandle`, + /// then run `on_end` when its rows are removed from the client cache. + fn unsubscribe_then(self, on_end: __sdk::OnEndedCallback) -> __sdk::Result<()> { + self.imp.unsubscribe_then(Some(on_end)) + } + + fn unsubscribe(self) -> __sdk::Result<()> { + self.imp.unsubscribe_then(None) + } +} + +/// Alias trait for a [`__sdk::DbContext`] connected to this module, +/// with that trait's associated types bounded to this module's concrete types. +/// +/// Users can use this trait as a boundary on definitions which should accept +/// either a [`DbConnection`] or an [`EventContext`] and operate on either. +pub trait RemoteDbContext: + __sdk::DbContext< + DbView = RemoteTables, + Reducers = RemoteReducers, + SetReducerFlags = SetReducerFlags, + SubscriptionBuilder = __sdk::SubscriptionBuilder, +> +{ +} +impl< + Ctx: __sdk::DbContext< + DbView = RemoteTables, + Reducers = RemoteReducers, + SetReducerFlags = SetReducerFlags, + SubscriptionBuilder = __sdk::SubscriptionBuilder, + >, + > RemoteDbContext for Ctx +{ +} + +/// An [`__sdk::DbContext`] augmented with a [`__sdk::Event`], +/// passed to [`__sdk::Table::on_insert`], [`__sdk::Table::on_delete`] and [`__sdk::TableWithPrimaryKey::on_update`] callbacks. +pub struct EventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + /// The event which caused these callbacks to run. + pub event: __sdk::Event, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for EventContext { + type Event = __sdk::Event; + fn event(&self) -> &Self::Event { + &self.event + } + fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + event, + imp, + } + } +} + +impl __sdk::InModule for EventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for EventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::EventContext for EventContext {} + +/// An [`__sdk::DbContext`] augmented with a [`__sdk::ReducerEvent`], +/// passed to on-reducer callbacks. +pub struct ReducerEventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + /// The event which caused these callbacks to run. + pub event: __sdk::ReducerEvent, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for ReducerEventContext { + type Event = __sdk::ReducerEvent; + fn event(&self) -> &Self::Event { + &self.event + } + fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + event, + imp, + } + } +} + +impl __sdk::InModule for ReducerEventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for ReducerEventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::ReducerEventContext for ReducerEventContext {} + +/// An [`__sdk::DbContext`] passed to procedure callbacks. +pub struct ProcedureEventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for ProcedureEventContext { + type Event = (); + fn event(&self) -> &Self::Event { + &() + } + fn new(imp: __sdk::DbContextImpl, _event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + imp, + } + } +} + +impl __sdk::InModule for ProcedureEventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for ProcedureEventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::ProcedureEventContext for ProcedureEventContext {} + +/// An [`__sdk::DbContext`] passed to [`__sdk::SubscriptionBuilder::on_applied`] and [`SubscriptionHandle::unsubscribe_then`] callbacks. +pub struct SubscriptionEventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for SubscriptionEventContext { + type Event = (); + fn event(&self) -> &Self::Event { + &() + } + fn new(imp: __sdk::DbContextImpl, _event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + imp, + } + } +} + +impl __sdk::InModule for SubscriptionEventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for SubscriptionEventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::SubscriptionEventContext for SubscriptionEventContext {} + +/// An [`__sdk::DbContext`] augmented with a [`__sdk::Error`], +/// passed to [`__sdk::DbConnectionBuilder::on_disconnect`], [`__sdk::DbConnectionBuilder::on_connect_error`] and [`__sdk::SubscriptionBuilder::on_error`] callbacks. +pub struct ErrorContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + /// The event which caused these callbacks to run. + pub event: Option<__sdk::Error>, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for ErrorContext { + type Event = Option<__sdk::Error>; + fn event(&self) -> &Self::Event { + &self.event + } + fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + event, + imp, + } + } +} + +impl __sdk::InModule for ErrorContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for ErrorContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::ErrorContext for ErrorContext {} + +impl __sdk::SpacetimeModule for RemoteModule { + type DbConnection = DbConnection; + type EventContext = EventContext; + type ReducerEventContext = ReducerEventContext; + type ProcedureEventContext = ProcedureEventContext; + type SubscriptionEventContext = SubscriptionEventContext; + type ErrorContext = ErrorContext; + type Reducer = Reducer; + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type SetReducerFlags = SetReducerFlags; + type DbUpdate = DbUpdate; + type AppliedDiff<'r> = AppliedDiff<'r>; + type SubscriptionHandle = SubscriptionHandle; + + fn register_tables(client_cache: &mut __sdk::ClientCache) { + person_table::register_table(client_cache); + } +} diff --git a/module_bindings/person_table.rs b/module_bindings/person_table.rs new file mode 100644 index 0000000..da3f64b --- /dev/null +++ b/module_bindings/person_table.rs @@ -0,0 +1,95 @@ +// 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::person_type::Person; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `person`. +/// +/// Obtain a handle from the [`PersonTableAccess::person`] method on [`super::RemoteTables`], +/// like `ctx.db.person()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.person().on_insert(...)`. +pub struct PersonTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `person`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait PersonTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`PersonTableHandle`], which mediates access to the table `person`. + fn person(&self) -> PersonTableHandle<'_>; +} + +impl PersonTableAccess for super::RemoteTables { + fn person(&self) -> PersonTableHandle<'_> { + PersonTableHandle { + imp: self.imp.get_table::("person"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct PersonInsertCallbackId(__sdk::CallbackId); +pub struct PersonDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for PersonTableHandle<'ctx> { + type Row = Person; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = PersonInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PersonInsertCallbackId { + PersonInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: PersonInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = PersonDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PersonDeleteCallbackId { + PersonDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: PersonDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("person"); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} diff --git a/module_bindings/person_type.rs b/module_bindings/person_type.rs new file mode 100644 index 0000000..56436ae --- /dev/null +++ b/module_bindings/person_type.rs @@ -0,0 +1,15 @@ +// 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 Person { + pub name: String, +} + +impl __sdk::InModule for Person { + type Module = super::RemoteModule; +} diff --git a/module_bindings/say_hello_reducer.rs b/module_bindings/say_hello_reducer.rs new file mode 100644 index 0000000..d326602 --- /dev/null +++ b/module_bindings/say_hello_reducer.rs @@ -0,0 +1,100 @@ +// 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 SayHelloArgs {} + +impl From for super::Reducer { + fn from(args: SayHelloArgs) -> Self { + Self::SayHello + } +} + +impl __sdk::InModule for SayHelloArgs { + type Module = super::RemoteModule; +} + +pub struct SayHelloCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `say_hello`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait say_hello { + /// Request that the remote module invoke the reducer `say_hello` 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_say_hello`] callbacks. + fn say_hello(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `say_hello`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`SayHelloCallbackId`] can be passed to [`Self::remove_on_say_hello`] + /// to cancel the callback. + fn on_say_hello( + &self, + callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> SayHelloCallbackId; + /// Cancel a callback previously registered by [`Self::on_say_hello`], + /// causing it not to run in the future. + fn remove_on_say_hello(&self, callback: SayHelloCallbackId); +} + +impl say_hello for super::RemoteReducers { + fn say_hello(&self) -> __sdk::Result<()> { + self.imp.call_reducer("say_hello", SayHelloArgs {}) + } + fn on_say_hello( + &self, + mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> SayHelloCallbackId { + SayHelloCallbackId(self.imp.on_reducer( + "say_hello", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::SayHello {}, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx) + }), + )) + } + fn remove_on_say_hello(&self, callback: SayHelloCallbackId) { + self.imp.remove_on_reducer("say_hello", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `say_hello`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_say_hello { + /// Set the call-reducer flags for the reducer `say_hello` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn say_hello(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_say_hello for super::SetReducerFlags { + fn say_hello(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("say_hello", flags); + } +} diff --git a/spacetimedb/Cargo.toml b/spacetimedb/Cargo.toml new file mode 100644 index 0000000..96c8641 --- /dev/null +++ b/spacetimedb/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "jongline" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib"] + +[dependencies] +spacetimedb = "1.11.*" +log = "0.4" diff --git a/spacetimedb/src/lib.rs b/spacetimedb/src/lib.rs new file mode 100644 index 0000000..cd942bd --- /dev/null +++ b/spacetimedb/src/lib.rs @@ -0,0 +1,61 @@ +use spacetimedb::{reducer, table, Identity, ReducerContext}; + +#[table(name = player, public)] +pub struct Player { + #[primary_key] + identity: Identity, + name: Option, + host: bool, +} + +#[table(name = wall)] +pub struct Wall { + tiles: Vec<()> +} + +#[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 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()) + } +} + +#[reducer] +pub fn shuffle_wall(ctx: &ReducerContext) {} + +// #[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!"); +// } diff --git a/src/module_bindings/add_reducer.rs b/src/module_bindings/add_reducer.rs new file mode 100644 index 0000000..5bfecc3 --- /dev/null +++ b/src/module_bindings/add_reducer.rs @@ -0,0 +1,102 @@ +// 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 AddArgs { + pub name: String, +} + +impl From for super::Reducer { + fn from(args: AddArgs) -> Self { + Self::Add { name: args.name } + } +} + +impl __sdk::InModule for AddArgs { + type Module = super::RemoteModule; +} + +pub struct AddCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `add`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait add { + /// Request that the remote module invoke the reducer `add` 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`] callbacks. + fn add(&self, name: String) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `add`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`AddCallbackId`] can be passed to [`Self::remove_on_add`] + /// to cancel the callback. + fn on_add( + &self, + callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, + ) -> AddCallbackId; + /// Cancel a callback previously registered by [`Self::on_add`], + /// causing it not to run in the future. + fn remove_on_add(&self, callback: AddCallbackId); +} + +impl add for super::RemoteReducers { + fn add(&self, name: String) -> __sdk::Result<()> { + self.imp.call_reducer("add", AddArgs { name }) + } + fn on_add( + &self, + mut callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, + ) -> AddCallbackId { + AddCallbackId(self.imp.on_reducer( + "add", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::Add { name }, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx, name) + }), + )) + } + fn remove_on_add(&self, callback: AddCallbackId) { + self.imp.remove_on_reducer("add", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `add`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_add { + /// Set the call-reducer flags for the reducer `add` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn add(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_add for super::SetReducerFlags { + fn add(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("add", flags); + } +} diff --git a/src/module_bindings/identity_connected_reducer.rs b/src/module_bindings/identity_connected_reducer.rs new file mode 100644 index 0000000..2eaaab0 --- /dev/null +++ b/src/module_bindings/identity_connected_reducer.rs @@ -0,0 +1,101 @@ +// 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 IdentityConnectedArgs {} + +impl From for super::Reducer { + fn from(args: IdentityConnectedArgs) -> Self { + Self::IdentityConnected + } +} + +impl __sdk::InModule for IdentityConnectedArgs { + type Module = super::RemoteModule; +} + +pub struct IdentityConnectedCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `identity_connected`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait identity_connected { + /// Request that the remote module invoke the reducer `identity_connected` 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_connected`] callbacks. + fn identity_connected(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `identity_connected`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`IdentityConnectedCallbackId`] can be passed to [`Self::remove_on_identity_connected`] + /// to cancel the callback. + fn on_identity_connected( + &self, + callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> IdentityConnectedCallbackId; + /// Cancel a callback previously registered by [`Self::on_identity_connected`], + /// causing it not to run in the future. + fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId); +} + +impl identity_connected for super::RemoteReducers { + fn identity_connected(&self) -> __sdk::Result<()> { + self.imp + .call_reducer("identity_connected", IdentityConnectedArgs {}) + } + fn on_identity_connected( + &self, + mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> IdentityConnectedCallbackId { + IdentityConnectedCallbackId(self.imp.on_reducer( + "identity_connected", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::IdentityConnected {}, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx) + }), + )) + } + fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId) { + self.imp.remove_on_reducer("identity_connected", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `identity_connected`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_identity_connected { + /// Set the call-reducer flags for the reducer `identity_connected` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn identity_connected(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_identity_connected for super::SetReducerFlags { + fn identity_connected(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("identity_connected", flags); + } +} diff --git a/src/module_bindings/identity_disconnected_reducer.rs b/src/module_bindings/identity_disconnected_reducer.rs new file mode 100644 index 0000000..c2892ed --- /dev/null +++ b/src/module_bindings/identity_disconnected_reducer.rs @@ -0,0 +1,103 @@ +// 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 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); + } +} diff --git a/src/module_bindings/mod.rs b/src/module_bindings/mod.rs new file mode 100644 index 0000000..e89f725 --- /dev/null +++ b/src/module_bindings/mod.rs @@ -0,0 +1,876 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +// This was generated using spacetimedb cli version 1.11.3 (commit 02449737ca3b29e7e39679fccbef541a50f32094). + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +pub mod add_reducer; +pub mod identity_connected_reducer; +pub mod identity_disconnected_reducer; +pub mod person_table; +pub mod person_type; +pub mod say_hello_reducer; + +pub use add_reducer::{add, set_flags_for_add, AddCallbackId}; +pub use identity_connected_reducer::{ + identity_connected, set_flags_for_identity_connected, IdentityConnectedCallbackId, +}; +pub use identity_disconnected_reducer::{ + identity_disconnected, set_flags_for_identity_disconnected, IdentityDisconnectedCallbackId, +}; +pub use person_table::*; +pub use person_type::Person; +pub use say_hello_reducer::{say_hello, set_flags_for_say_hello, SayHelloCallbackId}; + +#[derive(Clone, PartialEq, Debug)] + +/// One of the reducers defined by this module. +/// +/// Contained within a [`__sdk::ReducerEvent`] in [`EventContext`]s for reducer events +/// to indicate which reducer caused the event. + +pub enum Reducer { + Add { name: String }, + IdentityConnected, + IdentityDisconnected, + SayHello, +} + +impl __sdk::InModule for Reducer { + type Module = RemoteModule; +} + +impl __sdk::Reducer for Reducer { + fn reducer_name(&self) -> &'static str { + match self { + Reducer::Add { .. } => "add", + Reducer::IdentityConnected => "identity_connected", + Reducer::IdentityDisconnected => "identity_disconnected", + Reducer::SayHello => "say_hello", + _ => unreachable!(), + } + } +} +impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { + type Error = __sdk::Error; + fn try_from(value: __ws::ReducerCallInfo<__ws::BsatnFormat>) -> __sdk::Result { + match &value.reducer_name[..] { + "add" => { + Ok(__sdk::parse_reducer_args::("add", &value.args)?.into()) + } + "identity_connected" => Ok(__sdk::parse_reducer_args::< + identity_connected_reducer::IdentityConnectedArgs, + >("identity_connected", &value.args)? + .into()), + "identity_disconnected" => Ok(__sdk::parse_reducer_args::< + identity_disconnected_reducer::IdentityDisconnectedArgs, + >("identity_disconnected", &value.args)? + .into()), + "say_hello" => Ok( + __sdk::parse_reducer_args::( + "say_hello", + &value.args, + )? + .into(), + ), + unknown => { + Err( + __sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo") + .into(), + ) + } + } + } +} + +#[derive(Default)] +#[allow(non_snake_case)] +#[doc(hidden)] +pub struct DbUpdate { + person: __sdk::TableUpdate, +} + +impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { + type Error = __sdk::Error; + fn try_from(raw: __ws::DatabaseUpdate<__ws::BsatnFormat>) -> Result { + let mut db_update = DbUpdate::default(); + for table_update in raw.tables { + match &table_update.table_name[..] { + "person" => db_update + .person + .append(person_table::parse_table_update(table_update)?), + + unknown => { + return Err(__sdk::InternalError::unknown_name( + "table", + unknown, + "DatabaseUpdate", + ) + .into()); + } + } + } + Ok(db_update) + } +} + +impl __sdk::InModule for DbUpdate { + type Module = RemoteModule; +} + +impl __sdk::DbUpdate for DbUpdate { + fn apply_to_client_cache( + &self, + cache: &mut __sdk::ClientCache, + ) -> AppliedDiff<'_> { + let mut diff = AppliedDiff::default(); + + diff.person = cache.apply_diff_to_table::("person", &self.person); + + diff + } +} + +#[derive(Default)] +#[allow(non_snake_case)] +#[doc(hidden)] +pub struct AppliedDiff<'r> { + person: __sdk::TableAppliedDiff<'r, Person>, + __unused: std::marker::PhantomData<&'r ()>, +} + +impl __sdk::InModule for AppliedDiff<'_> { + type Module = RemoteModule; +} + +impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { + fn invoke_row_callbacks( + &self, + event: &EventContext, + callbacks: &mut __sdk::DbCallbacks, + ) { + callbacks.invoke_table_row_callbacks::("person", &self.person, event); + } +} + +#[doc(hidden)] +pub struct RemoteModule; + +impl __sdk::InModule for RemoteModule { + type Module = Self; +} + +/// The `reducers` field of [`EventContext`] and [`DbConnection`], +/// with methods provided by extension traits for each reducer defined by the module. +pub struct RemoteReducers { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for RemoteReducers { + type Module = RemoteModule; +} + +/// The `procedures` field of [`DbConnection`] and other [`DbContext`] types, +/// with methods provided by extension traits for each procedure defined by the module. +pub struct RemoteProcedures { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for RemoteProcedures { + type Module = RemoteModule; +} + +#[doc(hidden)] +/// The `set_reducer_flags` field of [`DbConnection`], +/// with methods provided by extension traits for each reducer defined by the module. +/// Each method sets the flags for the reducer with the same name. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub struct SetReducerFlags { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for SetReducerFlags { + type Module = RemoteModule; +} + +/// The `db` field of [`EventContext`] and [`DbConnection`], +/// with methods provided by extension traits for each table defined by the module. +pub struct RemoteTables { + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for RemoteTables { + type Module = RemoteModule; +} + +/// A connection to a remote module, including a materialized view of a subset of the database. +/// +/// Connect to a remote module by calling [`DbConnection::builder`] +/// and using the [`__sdk::DbConnectionBuilder`] builder-pattern constructor. +/// +/// You must explicitly advance the connection by calling any one of: +/// +/// - [`DbConnection::frame_tick`]. +/// - [`DbConnection::run_threaded`]. +/// - [`DbConnection::run_async`]. +/// - [`DbConnection::advance_one_message`]. +/// - [`DbConnection::advance_one_message_blocking`]. +/// - [`DbConnection::advance_one_message_async`]. +/// +/// Which of these methods you should call depends on the specific needs of your application, +/// but you must call one of them, or else the connection will never progress. +pub struct DbConnection { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + #[doc(hidden)] + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + + imp: __sdk::DbContextImpl, +} + +impl __sdk::InModule for DbConnection { + type Module = RemoteModule; +} + +impl __sdk::DbContext for DbConnection { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl DbConnection { + /// Builder-pattern constructor for a connection to a remote module. + /// + /// See [`__sdk::DbConnectionBuilder`] for required and optional configuration for the new connection. + pub fn builder() -> __sdk::DbConnectionBuilder { + __sdk::DbConnectionBuilder::new() + } + + /// If any WebSocket messages are waiting, process one of them. + /// + /// Returns `true` if a message was processed, or `false` if the queue is empty. + /// Callers should invoke this message in a loop until it returns `false` + /// or for as much time is available to process messages. + /// + /// Returns an error if the connection is disconnected. + /// If the disconnection in question was normal, + /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], + /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. + /// + /// This is a low-level primitive exposed for power users who need significant control over scheduling. + /// Most applications should call [`Self::frame_tick`] each frame + /// to fully exhaust the queue whenever time is available. + pub fn advance_one_message(&self) -> __sdk::Result { + self.imp.advance_one_message() + } + + /// Process one WebSocket message, potentially blocking the current thread until one is received. + /// + /// Returns an error if the connection is disconnected. + /// If the disconnection in question was normal, + /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], + /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. + /// + /// This is a low-level primitive exposed for power users who need significant control over scheduling. + /// Most applications should call [`Self::run_threaded`] to spawn a thread + /// which advances the connection automatically. + pub fn advance_one_message_blocking(&self) -> __sdk::Result<()> { + self.imp.advance_one_message_blocking() + } + + /// Process one WebSocket message, `await`ing until one is received. + /// + /// Returns an error if the connection is disconnected. + /// If the disconnection in question was normal, + /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], + /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. + /// + /// This is a low-level primitive exposed for power users who need significant control over scheduling. + /// Most applications should call [`Self::run_async`] to run an `async` loop + /// which advances the connection when polled. + pub async fn advance_one_message_async(&self) -> __sdk::Result<()> { + self.imp.advance_one_message_async().await + } + + /// Process all WebSocket messages waiting in the queue, + /// then return without `await`ing or blocking the current thread. + pub fn frame_tick(&self) -> __sdk::Result<()> { + self.imp.frame_tick() + } + + /// Spawn a thread which processes WebSocket messages as they are received. + pub fn run_threaded(&self) -> std::thread::JoinHandle<()> { + self.imp.run_threaded() + } + + /// Run an `async` loop which processes WebSocket messages when polled. + pub async fn run_async(&self) -> __sdk::Result<()> { + self.imp.run_async().await + } +} + +impl __sdk::DbConnection for DbConnection { + fn new(imp: __sdk::DbContextImpl) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + imp, + } + } +} + +/// A handle on a subscribed query. +// TODO: Document this better after implementing the new subscription API. +#[derive(Clone)] +pub struct SubscriptionHandle { + imp: __sdk::SubscriptionHandleImpl, +} + +impl __sdk::InModule for SubscriptionHandle { + type Module = RemoteModule; +} + +impl __sdk::SubscriptionHandle for SubscriptionHandle { + fn new(imp: __sdk::SubscriptionHandleImpl) -> Self { + Self { imp } + } + + /// Returns true if this subscription has been terminated due to an unsubscribe call or an error. + fn is_ended(&self) -> bool { + self.imp.is_ended() + } + + /// Returns true if this subscription has been applied and has not yet been unsubscribed. + fn is_active(&self) -> bool { + self.imp.is_active() + } + + /// Unsubscribe from the query controlled by this `SubscriptionHandle`, + /// then run `on_end` when its rows are removed from the client cache. + fn unsubscribe_then(self, on_end: __sdk::OnEndedCallback) -> __sdk::Result<()> { + self.imp.unsubscribe_then(Some(on_end)) + } + + fn unsubscribe(self) -> __sdk::Result<()> { + self.imp.unsubscribe_then(None) + } +} + +/// Alias trait for a [`__sdk::DbContext`] connected to this module, +/// with that trait's associated types bounded to this module's concrete types. +/// +/// Users can use this trait as a boundary on definitions which should accept +/// either a [`DbConnection`] or an [`EventContext`] and operate on either. +pub trait RemoteDbContext: + __sdk::DbContext< + DbView = RemoteTables, + Reducers = RemoteReducers, + SetReducerFlags = SetReducerFlags, + SubscriptionBuilder = __sdk::SubscriptionBuilder, +> +{ +} +impl< + Ctx: __sdk::DbContext< + DbView = RemoteTables, + Reducers = RemoteReducers, + SetReducerFlags = SetReducerFlags, + SubscriptionBuilder = __sdk::SubscriptionBuilder, + >, + > RemoteDbContext for Ctx +{ +} + +/// An [`__sdk::DbContext`] augmented with a [`__sdk::Event`], +/// passed to [`__sdk::Table::on_insert`], [`__sdk::Table::on_delete`] and [`__sdk::TableWithPrimaryKey::on_update`] callbacks. +pub struct EventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + /// The event which caused these callbacks to run. + pub event: __sdk::Event, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for EventContext { + type Event = __sdk::Event; + fn event(&self) -> &Self::Event { + &self.event + } + fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + event, + imp, + } + } +} + +impl __sdk::InModule for EventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for EventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::EventContext for EventContext {} + +/// An [`__sdk::DbContext`] augmented with a [`__sdk::ReducerEvent`], +/// passed to on-reducer callbacks. +pub struct ReducerEventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + /// The event which caused these callbacks to run. + pub event: __sdk::ReducerEvent, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for ReducerEventContext { + type Event = __sdk::ReducerEvent; + fn event(&self) -> &Self::Event { + &self.event + } + fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + event, + imp, + } + } +} + +impl __sdk::InModule for ReducerEventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for ReducerEventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::ReducerEventContext for ReducerEventContext {} + +/// An [`__sdk::DbContext`] passed to procedure callbacks. +pub struct ProcedureEventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for ProcedureEventContext { + type Event = (); + fn event(&self) -> &Self::Event { + &() + } + fn new(imp: __sdk::DbContextImpl, _event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + imp, + } + } +} + +impl __sdk::InModule for ProcedureEventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for ProcedureEventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::ProcedureEventContext for ProcedureEventContext {} + +/// An [`__sdk::DbContext`] passed to [`__sdk::SubscriptionBuilder::on_applied`] and [`SubscriptionHandle::unsubscribe_then`] callbacks. +pub struct SubscriptionEventContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for SubscriptionEventContext { + type Event = (); + fn event(&self) -> &Self::Event { + &() + } + fn new(imp: __sdk::DbContextImpl, _event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + imp, + } + } +} + +impl __sdk::InModule for SubscriptionEventContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for SubscriptionEventContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::SubscriptionEventContext for SubscriptionEventContext {} + +/// An [`__sdk::DbContext`] augmented with a [`__sdk::Error`], +/// passed to [`__sdk::DbConnectionBuilder::on_disconnect`], [`__sdk::DbConnectionBuilder::on_connect_error`] and [`__sdk::SubscriptionBuilder::on_error`] callbacks. +pub struct ErrorContext { + /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. + pub db: RemoteTables, + /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. + pub reducers: RemoteReducers, + /// Access to setting the call-flags of each reducer defined for each reducer defined by the module + /// via extension traits implemented for [`SetReducerFlags`]. + /// + /// This type is currently unstable and may be removed without a major version bump. + pub set_reducer_flags: SetReducerFlags, + /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. + pub procedures: RemoteProcedures, + /// The event which caused these callbacks to run. + pub event: Option<__sdk::Error>, + imp: __sdk::DbContextImpl, +} + +impl __sdk::AbstractEventContext for ErrorContext { + type Event = Option<__sdk::Error>; + fn event(&self) -> &Self::Event { + &self.event + } + fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { + Self { + db: RemoteTables { imp: imp.clone() }, + reducers: RemoteReducers { imp: imp.clone() }, + set_reducer_flags: SetReducerFlags { imp: imp.clone() }, + procedures: RemoteProcedures { imp: imp.clone() }, + event, + imp, + } + } +} + +impl __sdk::InModule for ErrorContext { + type Module = RemoteModule; +} + +impl __sdk::DbContext for ErrorContext { + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type Procedures = RemoteProcedures; + type SetReducerFlags = SetReducerFlags; + + fn db(&self) -> &Self::DbView { + &self.db + } + fn reducers(&self) -> &Self::Reducers { + &self.reducers + } + fn procedures(&self) -> &Self::Procedures { + &self.procedures + } + fn set_reducer_flags(&self) -> &Self::SetReducerFlags { + &self.set_reducer_flags + } + + fn is_active(&self) -> bool { + self.imp.is_active() + } + + fn disconnect(&self) -> __sdk::Result<()> { + self.imp.disconnect() + } + + type SubscriptionBuilder = __sdk::SubscriptionBuilder; + + fn subscription_builder(&self) -> Self::SubscriptionBuilder { + __sdk::SubscriptionBuilder::new(&self.imp) + } + + fn try_identity(&self) -> Option<__sdk::Identity> { + self.imp.try_identity() + } + fn connection_id(&self) -> __sdk::ConnectionId { + self.imp.connection_id() + } + fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { + self.imp.try_connection_id() + } +} + +impl __sdk::ErrorContext for ErrorContext {} + +impl __sdk::SpacetimeModule for RemoteModule { + type DbConnection = DbConnection; + type EventContext = EventContext; + type ReducerEventContext = ReducerEventContext; + type ProcedureEventContext = ProcedureEventContext; + type SubscriptionEventContext = SubscriptionEventContext; + type ErrorContext = ErrorContext; + type Reducer = Reducer; + type DbView = RemoteTables; + type Reducers = RemoteReducers; + type SetReducerFlags = SetReducerFlags; + type DbUpdate = DbUpdate; + type AppliedDiff<'r> = AppliedDiff<'r>; + type SubscriptionHandle = SubscriptionHandle; + + fn register_tables(client_cache: &mut __sdk::ClientCache) { + person_table::register_table(client_cache); + } +} diff --git a/src/module_bindings/person_table.rs b/src/module_bindings/person_table.rs new file mode 100644 index 0000000..da3f64b --- /dev/null +++ b/src/module_bindings/person_table.rs @@ -0,0 +1,95 @@ +// 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::person_type::Person; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `person`. +/// +/// Obtain a handle from the [`PersonTableAccess::person`] method on [`super::RemoteTables`], +/// like `ctx.db.person()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.person().on_insert(...)`. +pub struct PersonTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `person`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait PersonTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`PersonTableHandle`], which mediates access to the table `person`. + fn person(&self) -> PersonTableHandle<'_>; +} + +impl PersonTableAccess for super::RemoteTables { + fn person(&self) -> PersonTableHandle<'_> { + PersonTableHandle { + imp: self.imp.get_table::("person"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct PersonInsertCallbackId(__sdk::CallbackId); +pub struct PersonDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for PersonTableHandle<'ctx> { + type Row = Person; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = PersonInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PersonInsertCallbackId { + PersonInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: PersonInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = PersonDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PersonDeleteCallbackId { + PersonDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: PersonDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("person"); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} diff --git a/src/module_bindings/person_type.rs b/src/module_bindings/person_type.rs new file mode 100644 index 0000000..56436ae --- /dev/null +++ b/src/module_bindings/person_type.rs @@ -0,0 +1,15 @@ +// 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 Person { + pub name: String, +} + +impl __sdk::InModule for Person { + type Module = super::RemoteModule; +} diff --git a/src/module_bindings/say_hello_reducer.rs b/src/module_bindings/say_hello_reducer.rs new file mode 100644 index 0000000..d326602 --- /dev/null +++ b/src/module_bindings/say_hello_reducer.rs @@ -0,0 +1,100 @@ +// 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 SayHelloArgs {} + +impl From for super::Reducer { + fn from(args: SayHelloArgs) -> Self { + Self::SayHello + } +} + +impl __sdk::InModule for SayHelloArgs { + type Module = super::RemoteModule; +} + +pub struct SayHelloCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `say_hello`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait say_hello { + /// Request that the remote module invoke the reducer `say_hello` 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_say_hello`] callbacks. + fn say_hello(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `say_hello`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`SayHelloCallbackId`] can be passed to [`Self::remove_on_say_hello`] + /// to cancel the callback. + fn on_say_hello( + &self, + callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> SayHelloCallbackId; + /// Cancel a callback previously registered by [`Self::on_say_hello`], + /// causing it not to run in the future. + fn remove_on_say_hello(&self, callback: SayHelloCallbackId); +} + +impl say_hello for super::RemoteReducers { + fn say_hello(&self) -> __sdk::Result<()> { + self.imp.call_reducer("say_hello", SayHelloArgs {}) + } + fn on_say_hello( + &self, + mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> SayHelloCallbackId { + SayHelloCallbackId(self.imp.on_reducer( + "say_hello", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::SayHello {}, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx) + }), + )) + } + fn remove_on_say_hello(&self, callback: SayHelloCallbackId) { + self.imp.remove_on_reducer("say_hello", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `say_hello`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_say_hello { + /// Set the call-reducer flags for the reducer `say_hello` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn say_hello(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_say_hello for super::SetReducerFlags { + fn say_hello(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("say_hello", flags); + } +} From d7d567b0e6059b7108583e8c36ea49b532e01824 Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Sat, 7 Feb 2026 00:18:47 -0800 Subject: [PATCH 03/11] insert shuffled wall --- Cargo.lock | 2 ++ Cargo.toml | 2 ++ jong/Cargo.toml | 1 + jong/src/tile.rs | 21 ++++++++++++--------- jong/src/tui/render.rs | 6 +++--- spacetimedb/Cargo.toml | 5 +++-- spacetimedb/src/lib.rs | 16 +++++++++++++--- 7 files changed, 36 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 28043e6..3d1aba9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3747,6 +3747,7 @@ dependencies = [ "log", "rand 0.9.2", "ratatui", + "spacetimedb", "strum 0.27.2", "tracing", "tracing-subscriber", @@ -3757,6 +3758,7 @@ dependencies = [ name = "jongline" version = "0.1.0" dependencies = [ + "jong", "log", "spacetimedb", ] diff --git a/Cargo.toml b/Cargo.toml index c5968cd..f83cf09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,8 @@ strum = "0.27.2" tracing = "0.1.44" tracing-subscriber = "0.3.22" tui-logger = "0.18.0" +jong = { version = "0.1.0", path = "jong" } +spacetimedb = "1.11.*" [profile.dev] opt-level = 1 diff --git a/jong/Cargo.toml b/jong/Cargo.toml index 74353e2..a00f4da 100644 --- a/jong/Cargo.toml +++ b/jong/Cargo.toml @@ -19,6 +19,7 @@ clap = { workspace = true, features = ["derive"] } log = { workspace = true, features = ["release_max_level_error", "max_level_trace"] } rand = { workspace = true } ratatui = { workspace = true } +spacetimedb.workspace = true strum = { workspace = true, features = ["derive"] } tracing = { workspace = true } tracing-subscriber = { workspace = true } diff --git a/jong/src/tile.rs b/jong/src/tile.rs index 6d93f90..37659c5 100644 --- a/jong/src/tile.rs +++ b/jong/src/tile.rs @@ -1,12 +1,13 @@ use bevy::prelude::*; +use spacetimedb::SpacetimeType; use strum::FromRepr; -#[derive(Component, Debug, Clone, Copy)] +#[derive(Component, Debug, Clone, Copy, SpacetimeType)] pub struct Tile { pub suit: Suit, } -#[derive(/* MapEntities, */ Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy)] +#[derive(/* MapEntities, */ Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] pub enum Suit { Man(Rank), Pin(Rank), @@ -27,10 +28,12 @@ impl Suit { } } -#[derive(Deref, DerefMut, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy)] -pub struct Rank(pub u8); +#[derive(Deref, DerefMut, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +pub struct Rank { + pub number: u8, +} -#[derive(FromRepr, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy)] +#[derive(FromRepr, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] pub enum Wind { Ton, Nan, @@ -38,7 +41,7 @@ pub enum Wind { Pei, } -#[derive(Debug, FromRepr, PartialEq, PartialOrd, Eq, Ord, Clone, Copy)] +#[derive(Debug, FromRepr, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] pub enum Dragon { Haku, Hatsu, @@ -53,13 +56,13 @@ pub fn init_tiles(mut commands: Commands) { for _ in 0..4 { for i in 1..=9 { tiles.push(Tile { - suit: Suit::Pin(Rank(i)), + suit: Suit::Pin(Rank { number: i }), }); tiles.push(Tile { - suit: Suit::Sou(Rank(i)), + suit: Suit::Sou(Rank { number: i }), }); tiles.push(Tile { - suit: Suit::Man(Rank(i)), + suit: Suit::Man(Rank { number: i }), }); } for i in 0..4 { diff --git a/jong/src/tui/render.rs b/jong/src/tui/render.rs index ae6aae5..b2bbdaa 100644 --- a/jong/src/tui/render.rs +++ b/jong/src/tui/render.rs @@ -23,9 +23,9 @@ pub(crate) struct PickRegion { fn render_tile(tile: &Tile, hovered: bool) -> Paragraph<'_> { let block = ratatui::widgets::Block::bordered(); let mut widget = Paragraph::new(match &tile.suit { - jong::tile::Suit::Pin(rank) => format!("{}\np", rank.0), - jong::tile::Suit::Sou(rank) => format!("{}\ns", rank.0), - jong::tile::Suit::Man(rank) => format!("{}\nm", rank.0), + jong::tile::Suit::Pin(rank) => format!("{}\np", rank.number), + jong::tile::Suit::Sou(rank) => format!("{}\ns", rank.number), + jong::tile::Suit::Man(rank) => format!("{}\nm", rank.number), jong::tile::Suit::Wind(wind) => (match wind { jong::tile::Wind::Ton => "e\nw", jong::tile::Wind::Nan => "s\nw", diff --git a/spacetimedb/Cargo.toml b/spacetimedb/Cargo.toml index 96c8641..4697101 100644 --- a/spacetimedb/Cargo.toml +++ b/spacetimedb/Cargo.toml @@ -9,5 +9,6 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -spacetimedb = "1.11.*" -log = "0.4" +spacetimedb = { workspace = true } +log = { workspace = true } +jong = { workspace = true } diff --git a/spacetimedb/src/lib.rs b/spacetimedb/src/lib.rs index cd942bd..3e45fc5 100644 --- a/spacetimedb/src/lib.rs +++ b/spacetimedb/src/lib.rs @@ -1,4 +1,6 @@ -use spacetimedb::{reducer, table, Identity, ReducerContext}; +use spacetimedb::{Identity, ReducerContext, Table, rand::Rng, reducer, table}; + +use jong::tile::Tile; #[table(name = player, public)] pub struct Player { @@ -10,7 +12,7 @@ pub struct Player { #[table(name = wall)] pub struct Wall { - tiles: Vec<()> + tiles: Vec, } #[reducer(init)] @@ -45,7 +47,15 @@ pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> { } #[reducer] -pub fn shuffle_wall(ctx: &ReducerContext) {} +pub fn shuffle_wall(ctx: &ReducerContext) { + let mut rng = ctx.rng(); + let mut tiles: Vec = todo(); + + // rng.fill(); + // let tiles = rng.sh; + + ctx.db.wall().insert(Wall {tiles}); +} // #[reducer] // pub fn add(ctx: &ReducerContext, name: String) { From c86f8d93f179c17bf3a48664859ca695d3c11352 Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Sat, 7 Feb 2026 17:46:03 -0800 Subject: [PATCH 04/11] extract types --- Cargo.lock | 12 +- Cargo.toml | 8 +- flake.nix | 11 +- jong-types/Cargo.toml | 13 ++ jong-types/src/lib.rs | 77 ++++++++++ jong/Cargo.toml | 18 ++- jong/src/game/hand.rs | 6 +- jong/src/tile.rs | 111 ++++++-------- jong/src/tui/render.rs | 31 ++-- justfile | 2 +- module_bindings/add_player_reducer.rs | 102 +++++++++++++ module_bindings/dragon_type.rs | 20 +++ module_bindings/hand_table.rs | 96 ++++++++++++ module_bindings/hand_type.rs | 18 +++ .../identity_disconnected_reducer.rs | 103 ------------- module_bindings/mod.rs | 130 ++++++++++------ module_bindings/person_table.rs | 95 ------------ module_bindings/player_table.rs | 144 ++++++++++++++++++ module_bindings/player_type.rs | 18 +++ .../{person_type.rs => rank_type.rs} | 6 +- .../{add_reducer.rs => set_name_reducer.rs} | 68 ++++----- ...ted_reducer.rs => shuffle_wall_reducer.rs} | 69 +++++---- ..._hello_reducer.rs => sort_hand_reducer.rs} | 68 ++++----- module_bindings/suit_type.rs | 27 ++++ module_bindings/tile_type.rs | 17 +++ module_bindings/wall_table.rs | 96 ++++++++++++ module_bindings/wall_type.rs | 17 +++ module_bindings/wind_type.rs | 22 +++ spacetimedb/Cargo.toml | 2 +- spacetimedb/src/lib.rs | 53 ++++--- 30 files changed, 986 insertions(+), 474 deletions(-) create mode 100644 jong-types/Cargo.toml create mode 100644 jong-types/src/lib.rs create mode 100644 module_bindings/add_player_reducer.rs create mode 100644 module_bindings/dragon_type.rs create mode 100644 module_bindings/hand_table.rs create mode 100644 module_bindings/hand_type.rs delete mode 100644 module_bindings/identity_disconnected_reducer.rs delete mode 100644 module_bindings/person_table.rs create mode 100644 module_bindings/player_table.rs create mode 100644 module_bindings/player_type.rs rename module_bindings/{person_type.rs => rank_type.rs} (84%) rename module_bindings/{add_reducer.rs => set_name_reducer.rs} (56%) rename module_bindings/{identity_connected_reducer.rs => shuffle_wall_reducer.rs} (51%) rename module_bindings/{say_hello_reducer.rs => sort_hand_reducer.rs} (56%) create mode 100644 module_bindings/suit_type.rs create mode 100644 module_bindings/tile_type.rs create mode 100644 module_bindings/wall_table.rs create mode 100644 module_bindings/wall_type.rs create mode 100644 module_bindings/wind_type.rs diff --git a/Cargo.lock b/Cargo.lock index 3d1aba9..dcae9e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3744,6 +3744,7 @@ dependencies = [ "bevy_ratatui", "bevy_spacetimedb", "clap", + "jong-types", "log", "rand 0.9.2", "ratatui", @@ -3754,11 +3755,20 @@ dependencies = [ "tui-logger", ] +[[package]] +name = "jong-types" +version = "0.1.0" +dependencies = [ + "bevy", + "spacetimedb", + "strum 0.27.2", +] + [[package]] name = "jongline" version = "0.1.0" dependencies = [ - "jong", + "jong-types", "log", "spacetimedb", ] diff --git a/Cargo.toml b/Cargo.toml index f83cf09..4c025c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,20 +1,16 @@ [workspace] resolver = "3" -members = ["jong", "spacetimedb"] +members = ["jong", "jong-types", "spacetimedb"] [workspace.dependencies] -bevy = "0.17.3" -bevy_ratatui = "0.10.0" -bevy_spacetimedb = "0.7" clap = "4.5.54" log = "0.4.29" rand = "0.9.2" -ratatui = "0.30.0" strum = "0.27.2" tracing = "0.1.44" tracing-subscriber = "0.3.22" -tui-logger = "0.18.0" jong = { version = "0.1.0", path = "jong" } +jong-types = { version = "0.1.0", path = "jong-types" } spacetimedb = "1.11.*" [profile.dev] diff --git a/flake.nix b/flake.nix index 3a332de..0c46304 100644 --- a/flake.nix +++ b/flake.nix @@ -22,6 +22,12 @@ in { devShells.default = with pkgs; mkShell rec { + nativeBuildInputs = [ + pkg-config + # spacetimedb + openssl + binaryen + ]; buildInputs = [ # Rust dependencies @@ -29,7 +35,6 @@ extensions = ["rust-src" "rust-docs" "rustc-codegen-cranelift" "rust-analyzer" "rustfmt"]; targets = ["x86_64-unknown-linux-gnu" "wasm32-unknown-unknown"]; }) - pkg-config ] ++ lib.optionals (lib.strings.hasInfix "linux" system) [ # for Linux @@ -47,10 +52,6 @@ xorg.libXrandr libxkbcommon wayland - - # spacetimedb - openssl - binaryen ]; RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; LD_LIBRARY_PATH = lib.makeLibraryPath buildInputs; diff --git a/jong-types/Cargo.toml b/jong-types/Cargo.toml new file mode 100644 index 0000000..216a8df --- /dev/null +++ b/jong-types/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "jong-types" +version = "0.1.0" +edition = "2024" + +[lib] + +[dependencies] +bevy.version = "0.17.3" +bevy.default-features = false +spacetimedb.workspace = true +strum.workspace = true +strum.features = ["derive"] diff --git a/jong-types/src/lib.rs b/jong-types/src/lib.rs new file mode 100644 index 0000000..91d3444 --- /dev/null +++ b/jong-types/src/lib.rs @@ -0,0 +1,77 @@ +use bevy::prelude::*; +use spacetimedb::SpacetimeType; +use strum::FromRepr; + +#[derive(Component, Debug, Clone, Copy, SpacetimeType)] +pub struct Tile { + pub suit: Suit, +} + +#[derive(/* MapEntities, */ Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +pub enum Suit { + Man(Rank), + Pin(Rank), + Sou(Rank), + Wind(Wind), + Dragon(Dragon), +} + +impl Suit { + pub fn rank(&self) -> Option { + match self { + Suit::Man(rank) => Some(*rank), + Suit::Pin(rank) => Some(*rank), + Suit::Sou(rank) => Some(*rank), + // Suit::Wind(wind) | Suit::Dragon(dragon) => None, + _ => None, + } + } +} + +#[derive(Deref, DerefMut, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +pub struct Rank { + pub number: u8, +} + +#[derive(FromRepr, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +pub enum Wind { + Ton, + Nan, + Shaa, + Pei, +} + +#[derive(Debug, FromRepr, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +pub enum Dragon { + Haku, + Hatsu, + Chun, +} + +pub fn tiles() -> Vec { + let mut tiles = vec![]; + for _ in 0..4 { + for i in 1..=9 { + tiles.push(Tile { + suit: Suit::Pin(Rank { number: i }), + }); + tiles.push(Tile { + suit: Suit::Sou(Rank { number: i }), + }); + tiles.push(Tile { + suit: Suit::Man(Rank { number: i }), + }); + } + for i in 0..4 { + tiles.push(Tile { + suit: Suit::Wind(Wind::from_repr(i).unwrap()), + }); + } + for i in 0..3 { + tiles.push(Tile { + suit: Suit::Dragon(Dragon::from_repr(i).unwrap()), + }); + } + } + tiles +} diff --git a/jong/Cargo.toml b/jong/Cargo.toml index a00f4da..bf1e58f 100644 --- a/jong/Cargo.toml +++ b/jong/Cargo.toml @@ -10,17 +10,23 @@ readme = false [lib] [dependencies] -bevy = { workspace = true, features = ["dynamic_linking"] } -bevy_ratatui = { workspace = true } # bevy_ratatui = { git = "https://github.com/kenianbei/bevy_ratatui.git", rev = "e4b022308e08ab360ef89eca8e9f8b1c969e9a56" } # bevy_ratatui = { path = "/home/tao/clones/bevy_ratatui" } -bevy_spacetimedb = { workspace = true } +bevy.features = ["dynamic_linking"] +bevy.version = "0.17.3" +bevy_ratatui = "0.10.0" +bevy_spacetimedb = "0.7" clap = { workspace = true, features = ["derive"] } -log = { workspace = true, features = ["release_max_level_error", "max_level_trace"] } +jong-types = { version = "0.1.0", path = "../jong-types" } +log = { workspace = true, features = [ + "release_max_level_error", + "max_level_trace", +] } rand = { workspace = true } -ratatui = { workspace = true } +ratatui = "0.30.0" spacetimedb.workspace = true strum = { workspace = true, features = ["derive"] } tracing = { workspace = true } tracing-subscriber = { workspace = true } -tui-logger = { workspace = true, features = ["tracing-support", "crossterm"] } +tui-logger.features = ["tracing-support", "crossterm"] +tui-logger.version = "0.18.0" diff --git a/jong/src/game/hand.rs b/jong/src/game/hand.rs index 9717d79..26f81c1 100644 --- a/jong/src/game/hand.rs +++ b/jong/src/game/hand.rs @@ -2,10 +2,8 @@ use std::mem::discriminant; use bevy::prelude::*; -use crate::{ - game::{GameState, player::Player, wall::Wall}, - tile::Tile, -}; +use crate::game::{GameState, player::Player, wall::Wall}; +use jong_types::*; #[derive(Component)] pub struct Hand; diff --git a/jong/src/tile.rs b/jong/src/tile.rs index 37659c5..34b73c5 100644 --- a/jong/src/tile.rs +++ b/jong/src/tile.rs @@ -1,80 +1,59 @@ use bevy::prelude::*; -use spacetimedb::SpacetimeType; -use strum::FromRepr; +// use spacetimedb::SpacetimeType; +// use strum::FromRepr; -#[derive(Component, Debug, Clone, Copy, SpacetimeType)] -pub struct Tile { - pub suit: Suit, -} +use jong_types::*; -#[derive(/* MapEntities, */ Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] -pub enum Suit { - Man(Rank), - Pin(Rank), - Sou(Rank), - Wind(Wind), - Dragon(Dragon), -} +// #[derive(Component, Debug, Clone, Copy, SpacetimeType)] +// pub struct Tile { +// pub suit: Suit, +// } -impl Suit { - pub fn rank(&self) -> Option { - match self { - Suit::Man(rank) => Some(*rank), - Suit::Pin(rank) => Some(*rank), - Suit::Sou(rank) => Some(*rank), - // Suit::Wind(wind) | Suit::Dragon(dragon) => None, - _ => None, - } - } -} +// #[derive(/* MapEntities, */ Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +// pub enum Suit { +// Man(Rank), +// Pin(Rank), +// Sou(Rank), +// Wind(Wind), +// Dragon(Dragon), +// } -#[derive(Deref, DerefMut, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] -pub struct Rank { - pub number: u8, -} +// impl Suit { +// pub fn rank(&self) -> Option { +// match self { +// Suit::Man(rank) => Some(*rank), +// Suit::Pin(rank) => Some(*rank), +// Suit::Sou(rank) => Some(*rank), +// // Suit::Wind(wind) | Suit::Dragon(dragon) => None, +// _ => None, +// } +// } +// } -#[derive(FromRepr, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] -pub enum Wind { - Ton, - Nan, - Shaa, - Pei, -} +// #[derive(Deref, DerefMut, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +// pub struct Rank { +// pub number: u8, +// } -#[derive(Debug, FromRepr, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] -pub enum Dragon { - Haku, - Hatsu, - Chun, -} +// #[derive(FromRepr, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +// pub enum Wind { +// Ton, +// Nan, +// Shaa, +// Pei, +// } + +// #[derive(Debug, FromRepr, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +// pub enum Dragon { +// Haku, +// Hatsu, +// Chun, +// } #[derive(Component)] pub struct Dora; pub fn init_tiles(mut commands: Commands) { - 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()), - }); - } - } + let tiles = tiles(); commands.spawn_batch(tiles); } diff --git a/jong/src/tui/render.rs b/jong/src/tui/render.rs index b2bbdaa..a81588d 100644 --- a/jong/src/tui/render.rs +++ b/jong/src/tui/render.rs @@ -9,7 +9,7 @@ use ratatui::widgets::{Block, Borders, Clear, Paragraph}; use jong::game::hand::{Drawn, Hand}; use jong::game::player::{CurrentPlayer, MainPlayer, Player}; use jong::game::round::Wind; -use jong::tile::Tile; +// use jong_types::*; use crate::tui::input::Hovered; use crate::tui::layout::*; @@ -20,23 +20,24 @@ pub(crate) struct PickRegion { 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 mut widget = Paragraph::new(match &tile.suit { - jong::tile::Suit::Pin(rank) => format!("{}\np", rank.number), - jong::tile::Suit::Sou(rank) => format!("{}\ns", rank.number), - jong::tile::Suit::Man(rank) => format!("{}\nm", rank.number), - jong::tile::Suit::Wind(wind) => (match wind { - jong::tile::Wind::Ton => "e\nw", - jong::tile::Wind::Nan => "s\nw", - jong::tile::Wind::Shaa => "w\nw", - jong::tile::Wind::Pei => "n\nw", + Suit::Pin(rank) => format!("{}\np", rank.number), + Suit::Sou(rank) => format!("{}\ns", rank.number), + Suit::Man(rank) => format!("{}\nm", rank.number), + Suit::Wind(wind) => (match wind { + Wind::Ton => "e\nw", + Wind::Nan => "s\nw", + Wind::Shaa => "w\nw", + Wind::Pei => "n\nw", }) .into(), - jong::tile::Suit::Dragon(dragon) => (match dragon { - jong::tile::Dragon::Haku => "w\nd", - jong::tile::Dragon::Hatsu => "g\nd", - jong::tile::Dragon::Chun => "r\nd", + Suit::Dragon(dragon) => (match dragon { + Dragon::Haku => "w\nd", + Dragon::Hatsu => "g\nd", + Dragon::Chun => "r\nd", }) .into(), }) @@ -102,7 +103,7 @@ pub(crate) fn render_hands( hovered: Query>, layouts: Res, - tiles: Query<&Tile>, + tiles: Query<&jong_types::Tile>, main_player: Single<(&Player, Entity, &Wind), With>, curr_player: Single>, players: Query<(&Player, Entity, &Children)>, diff --git a/justfile b/justfile index 7285e79..f8f62e9 100644 --- a/justfile +++ b/justfile @@ -14,4 +14,4 @@ update: nix flake update spacetime: - spacetime dev --module-bindings-path modules_bindings + spacetime dev --module-bindings-path module_bindings fantastic-key-0909 diff --git a/module_bindings/add_player_reducer.rs b/module_bindings/add_player_reducer.rs new file mode 100644 index 0000000..757a0b6 --- /dev/null +++ b/module_bindings/add_player_reducer.rs @@ -0,0 +1,102 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct AddPlayerArgs { + pub name: Option, +} + +impl From for super::Reducer { + fn from(args: AddPlayerArgs) -> Self { + Self::AddPlayer { name: args.name } + } +} + +impl __sdk::InModule for AddPlayerArgs { + type Module = super::RemoteModule; +} + +pub struct AddPlayerCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `add_player`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait add_player { + /// Request that the remote module invoke the reducer `add_player` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_add_player`] callbacks. + fn add_player(&self, name: Option) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `add_player`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`AddPlayerCallbackId`] can be passed to [`Self::remove_on_add_player`] + /// to cancel the callback. + fn on_add_player( + &self, + callback: impl FnMut(&super::ReducerEventContext, &Option) + Send + 'static, + ) -> AddPlayerCallbackId; + /// Cancel a callback previously registered by [`Self::on_add_player`], + /// causing it not to run in the future. + fn remove_on_add_player(&self, callback: AddPlayerCallbackId); +} + +impl add_player for super::RemoteReducers { + fn add_player(&self, name: Option) -> __sdk::Result<()> { + self.imp.call_reducer("add_player", AddPlayerArgs { name }) + } + fn on_add_player( + &self, + mut callback: impl FnMut(&super::ReducerEventContext, &Option) + Send + 'static, + ) -> AddPlayerCallbackId { + AddPlayerCallbackId(self.imp.on_reducer( + "add_player", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::AddPlayer { name }, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx, name) + }), + )) + } + fn remove_on_add_player(&self, callback: AddPlayerCallbackId) { + self.imp.remove_on_reducer("add_player", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `add_player`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_add_player { + /// Set the call-reducer flags for the reducer `add_player` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn add_player(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_add_player for super::SetReducerFlags { + fn add_player(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("add_player", flags); + } +} diff --git a/module_bindings/dragon_type.rs b/module_bindings/dragon_type.rs new file mode 100644 index 0000000..4b954b1 --- /dev/null +++ b/module_bindings/dragon_type.rs @@ -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}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +#[derive(Copy, Eq, Hash)] +pub enum Dragon { + Haku, + + Hatsu, + + Chun, +} + +impl __sdk::InModule for Dragon { + type Module = super::RemoteModule; +} diff --git a/module_bindings/hand_table.rs b/module_bindings/hand_table.rs new file mode 100644 index 0000000..d648970 --- /dev/null +++ b/module_bindings/hand_table.rs @@ -0,0 +1,96 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use super::hand_type::Hand; +use super::tile_type::Tile; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `hand`. +/// +/// Obtain a handle from the [`HandTableAccess::hand`] method on [`super::RemoteTables`], +/// like `ctx.db.hand()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.hand().on_insert(...)`. +pub struct HandTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `hand`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait HandTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`HandTableHandle`], which mediates access to the table `hand`. + fn hand(&self) -> HandTableHandle<'_>; +} + +impl HandTableAccess for super::RemoteTables { + fn hand(&self) -> HandTableHandle<'_> { + HandTableHandle { + imp: self.imp.get_table::("hand"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct HandInsertCallbackId(__sdk::CallbackId); +pub struct HandDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for HandTableHandle<'ctx> { + type Row = Hand; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = HandInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> HandInsertCallbackId { + HandInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: HandInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = HandDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> HandDeleteCallbackId { + HandDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: HandDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("hand"); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} diff --git a/module_bindings/hand_type.rs b/module_bindings/hand_type.rs new file mode 100644 index 0000000..0f0dd43 --- /dev/null +++ b/module_bindings/hand_type.rs @@ -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}; + +use super::tile_type::Tile; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct Hand { + pub player_id: u32, + pub tiles: Vec, +} + +impl __sdk::InModule for Hand { + type Module = super::RemoteModule; +} diff --git a/module_bindings/identity_disconnected_reducer.rs b/module_bindings/identity_disconnected_reducer.rs deleted file mode 100644 index c2892ed..0000000 --- a/module_bindings/identity_disconnected_reducer.rs +++ /dev/null @@ -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 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); - } -} diff --git a/module_bindings/mod.rs b/module_bindings/mod.rs index e89f725..664e7d9 100644 --- a/module_bindings/mod.rs +++ b/module_bindings/mod.rs @@ -6,23 +6,37 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; -pub mod add_reducer; -pub mod identity_connected_reducer; -pub mod identity_disconnected_reducer; -pub mod person_table; -pub mod person_type; -pub mod say_hello_reducer; +pub mod add_player_reducer; +pub mod dragon_type; +pub mod hand_table; +pub mod hand_type; +pub mod player_table; +pub mod player_type; +pub mod rank_type; +pub mod set_name_reducer; +pub mod shuffle_wall_reducer; +pub mod sort_hand_reducer; +pub mod suit_type; +pub mod tile_type; +pub mod wall_table; +pub mod wall_type; +pub mod wind_type; -pub use add_reducer::{add, set_flags_for_add, AddCallbackId}; -pub use identity_connected_reducer::{ - identity_connected, set_flags_for_identity_connected, IdentityConnectedCallbackId, -}; -pub use identity_disconnected_reducer::{ - identity_disconnected, set_flags_for_identity_disconnected, IdentityDisconnectedCallbackId, -}; -pub use person_table::*; -pub use person_type::Person; -pub use say_hello_reducer::{say_hello, set_flags_for_say_hello, SayHelloCallbackId}; +pub use add_player_reducer::{add_player, set_flags_for_add_player, AddPlayerCallbackId}; +pub use dragon_type::Dragon; +pub use hand_table::*; +pub use hand_type::Hand; +pub use player_table::*; +pub use player_type::Player; +pub use rank_type::Rank; +pub use set_name_reducer::{set_flags_for_set_name, set_name, SetNameCallbackId}; +pub use shuffle_wall_reducer::{set_flags_for_shuffle_wall, shuffle_wall, ShuffleWallCallbackId}; +pub use sort_hand_reducer::{set_flags_for_sort_hand, sort_hand, SortHandCallbackId}; +pub use suit_type::Suit; +pub use tile_type::Tile; +pub use wall_table::*; +pub use wall_type::Wall; +pub use wind_type::Wind; #[derive(Clone, PartialEq, Debug)] @@ -32,10 +46,10 @@ pub use say_hello_reducer::{say_hello, set_flags_for_say_hello, SayHelloCallback /// to indicate which reducer caused the event. pub enum Reducer { - Add { name: String }, - IdentityConnected, - IdentityDisconnected, - SayHello, + AddPlayer { name: Option }, + SetName { name: String }, + ShuffleWall, + SortHand, } impl __sdk::InModule for Reducer { @@ -45,10 +59,10 @@ impl __sdk::InModule for Reducer { impl __sdk::Reducer for Reducer { fn reducer_name(&self) -> &'static str { match self { - Reducer::Add { .. } => "add", - Reducer::IdentityConnected => "identity_connected", - Reducer::IdentityDisconnected => "identity_disconnected", - Reducer::SayHello => "say_hello", + Reducer::AddPlayer { .. } => "add_player", + Reducer::SetName { .. } => "set_name", + Reducer::ShuffleWall => "shuffle_wall", + Reducer::SortHand => "sort_hand", _ => unreachable!(), } } @@ -57,20 +71,28 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { type Error = __sdk::Error; fn try_from(value: __ws::ReducerCallInfo<__ws::BsatnFormat>) -> __sdk::Result { match &value.reducer_name[..] { - "add" => { - Ok(__sdk::parse_reducer_args::("add", &value.args)?.into()) - } - "identity_connected" => Ok(__sdk::parse_reducer_args::< - identity_connected_reducer::IdentityConnectedArgs, - >("identity_connected", &value.args)? + "add_player" => Ok( + __sdk::parse_reducer_args::( + "add_player", + &value.args, + )? + .into(), + ), + "set_name" => Ok(__sdk::parse_reducer_args::( + "set_name", + &value.args, + )? .into()), - "identity_disconnected" => Ok(__sdk::parse_reducer_args::< - identity_disconnected_reducer::IdentityDisconnectedArgs, - >("identity_disconnected", &value.args)? - .into()), - "say_hello" => Ok( - __sdk::parse_reducer_args::( - "say_hello", + "shuffle_wall" => Ok( + __sdk::parse_reducer_args::( + "shuffle_wall", + &value.args, + )? + .into(), + ), + "sort_hand" => Ok( + __sdk::parse_reducer_args::( + "sort_hand", &value.args, )? .into(), @@ -89,7 +111,9 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { #[allow(non_snake_case)] #[doc(hidden)] pub struct DbUpdate { - person: __sdk::TableUpdate, + hand: __sdk::TableUpdate, + player: __sdk::TableUpdate, + wall: __sdk::TableUpdate, } impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { @@ -98,9 +122,15 @@ impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { let mut db_update = DbUpdate::default(); for table_update in raw.tables { match &table_update.table_name[..] { - "person" => db_update - .person - .append(person_table::parse_table_update(table_update)?), + "hand" => db_update + .hand + .append(hand_table::parse_table_update(table_update)?), + "player" => db_update + .player + .append(player_table::parse_table_update(table_update)?), + "wall" => db_update + .wall + .append(wall_table::parse_table_update(table_update)?), unknown => { return Err(__sdk::InternalError::unknown_name( @@ -127,7 +157,11 @@ impl __sdk::DbUpdate for DbUpdate { ) -> AppliedDiff<'_> { let mut diff = AppliedDiff::default(); - diff.person = cache.apply_diff_to_table::("person", &self.person); + diff.hand = cache.apply_diff_to_table::("hand", &self.hand); + diff.player = cache + .apply_diff_to_table::("player", &self.player) + .with_updates_by_pk(|row| &row.identity); + diff.wall = cache.apply_diff_to_table::("wall", &self.wall); diff } @@ -137,7 +171,9 @@ impl __sdk::DbUpdate for DbUpdate { #[allow(non_snake_case)] #[doc(hidden)] pub struct AppliedDiff<'r> { - person: __sdk::TableAppliedDiff<'r, Person>, + hand: __sdk::TableAppliedDiff<'r, Hand>, + player: __sdk::TableAppliedDiff<'r, Player>, + wall: __sdk::TableAppliedDiff<'r, Wall>, __unused: std::marker::PhantomData<&'r ()>, } @@ -151,7 +187,9 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { event: &EventContext, callbacks: &mut __sdk::DbCallbacks, ) { - callbacks.invoke_table_row_callbacks::("person", &self.person, event); + callbacks.invoke_table_row_callbacks::("hand", &self.hand, event); + callbacks.invoke_table_row_callbacks::("player", &self.player, event); + callbacks.invoke_table_row_callbacks::("wall", &self.wall, event); } } @@ -871,6 +909,8 @@ impl __sdk::SpacetimeModule for RemoteModule { type SubscriptionHandle = SubscriptionHandle; fn register_tables(client_cache: &mut __sdk::ClientCache) { - person_table::register_table(client_cache); + hand_table::register_table(client_cache); + player_table::register_table(client_cache); + wall_table::register_table(client_cache); } } diff --git a/module_bindings/person_table.rs b/module_bindings/person_table.rs deleted file mode 100644 index da3f64b..0000000 --- a/module_bindings/person_table.rs +++ /dev/null @@ -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::person_type::Person; -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -/// Table handle for the table `person`. -/// -/// Obtain a handle from the [`PersonTableAccess::person`] method on [`super::RemoteTables`], -/// like `ctx.db.person()`. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.person().on_insert(...)`. -pub struct PersonTableHandle<'ctx> { - imp: __sdk::TableHandle, - ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -#[allow(non_camel_case_types)] -/// Extension trait for access to the table `person`. -/// -/// Implemented for [`super::RemoteTables`]. -pub trait PersonTableAccess { - #[allow(non_snake_case)] - /// Obtain a [`PersonTableHandle`], which mediates access to the table `person`. - fn person(&self) -> PersonTableHandle<'_>; -} - -impl PersonTableAccess for super::RemoteTables { - fn person(&self) -> PersonTableHandle<'_> { - PersonTableHandle { - imp: self.imp.get_table::("person"), - ctx: std::marker::PhantomData, - } - } -} - -pub struct PersonInsertCallbackId(__sdk::CallbackId); -pub struct PersonDeleteCallbackId(__sdk::CallbackId); - -impl<'ctx> __sdk::Table for PersonTableHandle<'ctx> { - type Row = Person; - type EventContext = super::EventContext; - - fn count(&self) -> u64 { - self.imp.count() - } - fn iter(&self) -> impl Iterator + '_ { - self.imp.iter() - } - - type InsertCallbackId = PersonInsertCallbackId; - - fn on_insert( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> PersonInsertCallbackId { - PersonInsertCallbackId(self.imp.on_insert(Box::new(callback))) - } - - fn remove_on_insert(&self, callback: PersonInsertCallbackId) { - self.imp.remove_on_insert(callback.0) - } - - type DeleteCallbackId = PersonDeleteCallbackId; - - fn on_delete( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> PersonDeleteCallbackId { - PersonDeleteCallbackId(self.imp.on_delete(Box::new(callback))) - } - - fn remove_on_delete(&self, callback: PersonDeleteCallbackId) { - self.imp.remove_on_delete(callback.0) - } -} - -#[doc(hidden)] -pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { - let _table = client_cache.get_or_make_table::("person"); -} - -#[doc(hidden)] -pub(super) fn parse_table_update( - raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, -) -> __sdk::Result<__sdk::TableUpdate> { - __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { - __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") - .with_cause(e) - .into() - }) -} diff --git a/module_bindings/player_table.rs b/module_bindings/player_table.rs new file mode 100644 index 0000000..f876249 --- /dev/null +++ b/module_bindings/player_table.rs @@ -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_type::Player; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `player`. +/// +/// Obtain a handle from the [`PlayerTableAccess::player`] method on [`super::RemoteTables`], +/// like `ctx.db.player()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.player().on_insert(...)`. +pub struct PlayerTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `player`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait PlayerTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`PlayerTableHandle`], which mediates access to the table `player`. + fn player(&self) -> PlayerTableHandle<'_>; +} + +impl PlayerTableAccess for super::RemoteTables { + fn player(&self) -> PlayerTableHandle<'_> { + PlayerTableHandle { + imp: self.imp.get_table::("player"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct PlayerInsertCallbackId(__sdk::CallbackId); +pub struct PlayerDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for PlayerTableHandle<'ctx> { + type Row = Player; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = PlayerInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PlayerInsertCallbackId { + PlayerInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: PlayerInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = PlayerDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> PlayerDeleteCallbackId { + PlayerDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: PlayerDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("player"); + _table.add_unique_constraint::<__sdk::Identity>("identity", |row| &row.identity); +} +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)] +pub(super) fn parse_table_update( + raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .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, + 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 { + self.imp.find(col_val) + } +} diff --git a/module_bindings/player_type.rs b/module_bindings/player_type.rs new file mode 100644 index 0000000..59fa7f6 --- /dev/null +++ b/module_bindings/player_type.rs @@ -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 Player { + pub identity: __sdk::Identity, + pub id: u32, + pub name: Option, + pub host: bool, +} + +impl __sdk::InModule for Player { + type Module = super::RemoteModule; +} diff --git a/module_bindings/person_type.rs b/module_bindings/rank_type.rs similarity index 84% rename from module_bindings/person_type.rs rename to module_bindings/rank_type.rs index 56436ae..5b40b70 100644 --- a/module_bindings/person_type.rs +++ b/module_bindings/rank_type.rs @@ -6,10 +6,10 @@ 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 Person { - pub name: String, +pub struct Rank { + pub number: u8, } -impl __sdk::InModule for Person { +impl __sdk::InModule for Rank { type Module = super::RemoteModule; } diff --git a/module_bindings/add_reducer.rs b/module_bindings/set_name_reducer.rs similarity index 56% rename from module_bindings/add_reducer.rs rename to module_bindings/set_name_reducer.rs index 5bfecc3..cc9905d 100644 --- a/module_bindings/add_reducer.rs +++ b/module_bindings/set_name_reducer.rs @@ -6,65 +6,65 @@ 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 AddArgs { +pub(super) struct SetNameArgs { pub name: String, } -impl From for super::Reducer { - fn from(args: AddArgs) -> Self { - Self::Add { name: args.name } +impl From for super::Reducer { + fn from(args: SetNameArgs) -> Self { + Self::SetName { name: args.name } } } -impl __sdk::InModule for AddArgs { +impl __sdk::InModule for SetNameArgs { type Module = super::RemoteModule; } -pub struct AddCallbackId(__sdk::CallbackId); +pub struct SetNameCallbackId(__sdk::CallbackId); #[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `add`. +/// Extension trait for access to the reducer `set_name`. /// /// Implemented for [`super::RemoteReducers`]. -pub trait add { - /// Request that the remote module invoke the reducer `add` to run as soon as possible. +pub trait set_name { + /// Request that the remote module invoke the reducer `set_name` to run as soon as possible. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, - /// and its status can be observed by listening for [`Self::on_add`] callbacks. - fn add(&self, name: String) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `add`. + /// and its status can be observed by listening for [`Self::on_set_name`] callbacks. + fn set_name(&self, name: String) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `set_name`. /// /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] /// to determine the reducer's status. /// - /// The returned [`AddCallbackId`] can be passed to [`Self::remove_on_add`] + /// The returned [`SetNameCallbackId`] can be passed to [`Self::remove_on_set_name`] /// to cancel the callback. - fn on_add( + fn on_set_name( &self, callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, - ) -> AddCallbackId; - /// Cancel a callback previously registered by [`Self::on_add`], + ) -> SetNameCallbackId; + /// Cancel a callback previously registered by [`Self::on_set_name`], /// causing it not to run in the future. - fn remove_on_add(&self, callback: AddCallbackId); + fn remove_on_set_name(&self, callback: SetNameCallbackId); } -impl add for super::RemoteReducers { - fn add(&self, name: String) -> __sdk::Result<()> { - self.imp.call_reducer("add", AddArgs { name }) +impl set_name for super::RemoteReducers { + fn set_name(&self, name: String) -> __sdk::Result<()> { + self.imp.call_reducer("set_name", SetNameArgs { name }) } - fn on_add( + fn on_set_name( &self, mut callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, - ) -> AddCallbackId { - AddCallbackId(self.imp.on_reducer( - "add", + ) -> SetNameCallbackId { + SetNameCallbackId(self.imp.on_reducer( + "set_name", Box::new(move |ctx: &super::ReducerEventContext| { #[allow(irrefutable_let_patterns)] let super::ReducerEventContext { event: __sdk::ReducerEvent { - reducer: super::Reducer::Add { name }, + reducer: super::Reducer::SetName { name }, .. }, .. @@ -76,27 +76,27 @@ impl add for super::RemoteReducers { }), )) } - fn remove_on_add(&self, callback: AddCallbackId) { - self.imp.remove_on_reducer("add", callback.0) + fn remove_on_set_name(&self, callback: SetNameCallbackId) { + self.imp.remove_on_reducer("set_name", callback.0) } } #[allow(non_camel_case_types)] #[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `add`. +/// Extension trait for setting the call-flags for the reducer `set_name`. /// /// Implemented for [`super::SetReducerFlags`]. /// /// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_add { - /// Set the call-reducer flags for the reducer `add` to `flags`. +pub trait set_flags_for_set_name { + /// Set the call-reducer flags for the reducer `set_name` to `flags`. /// /// This type is currently unstable and may be removed without a major version bump. - fn add(&self, flags: __ws::CallReducerFlags); + fn set_name(&self, flags: __ws::CallReducerFlags); } -impl set_flags_for_add for super::SetReducerFlags { - fn add(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("add", flags); +impl set_flags_for_set_name for super::SetReducerFlags { + fn set_name(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("set_name", flags); } } diff --git a/module_bindings/identity_connected_reducer.rs b/module_bindings/shuffle_wall_reducer.rs similarity index 51% rename from module_bindings/identity_connected_reducer.rs rename to module_bindings/shuffle_wall_reducer.rs index 2eaaab0..4f86c24 100644 --- a/module_bindings/identity_connected_reducer.rs +++ b/module_bindings/shuffle_wall_reducer.rs @@ -6,64 +6,63 @@ 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 IdentityConnectedArgs {} +pub(super) struct ShuffleWallArgs {} -impl From for super::Reducer { - fn from(args: IdentityConnectedArgs) -> Self { - Self::IdentityConnected +impl From for super::Reducer { + fn from(args: ShuffleWallArgs) -> Self { + Self::ShuffleWall } } -impl __sdk::InModule for IdentityConnectedArgs { +impl __sdk::InModule for ShuffleWallArgs { type Module = super::RemoteModule; } -pub struct IdentityConnectedCallbackId(__sdk::CallbackId); +pub struct ShuffleWallCallbackId(__sdk::CallbackId); #[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `identity_connected`. +/// Extension trait for access to the reducer `shuffle_wall`. /// /// Implemented for [`super::RemoteReducers`]. -pub trait identity_connected { - /// Request that the remote module invoke the reducer `identity_connected` to run as soon as possible. +pub trait shuffle_wall { + /// Request that the remote module invoke the reducer `shuffle_wall` to run as soon as possible. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, - /// and its status can be observed by listening for [`Self::on_identity_connected`] callbacks. - fn identity_connected(&self) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `identity_connected`. + /// and its status can be observed by listening for [`Self::on_shuffle_wall`] callbacks. + fn shuffle_wall(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `shuffle_wall`. /// /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] /// to determine the reducer's status. /// - /// The returned [`IdentityConnectedCallbackId`] can be passed to [`Self::remove_on_identity_connected`] + /// The returned [`ShuffleWallCallbackId`] can be passed to [`Self::remove_on_shuffle_wall`] /// to cancel the callback. - fn on_identity_connected( + fn on_shuffle_wall( &self, callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> IdentityConnectedCallbackId; - /// Cancel a callback previously registered by [`Self::on_identity_connected`], + ) -> ShuffleWallCallbackId; + /// Cancel a callback previously registered by [`Self::on_shuffle_wall`], /// causing it not to run in the future. - fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId); + fn remove_on_shuffle_wall(&self, callback: ShuffleWallCallbackId); } -impl identity_connected for super::RemoteReducers { - fn identity_connected(&self) -> __sdk::Result<()> { - self.imp - .call_reducer("identity_connected", IdentityConnectedArgs {}) +impl shuffle_wall for super::RemoteReducers { + fn shuffle_wall(&self) -> __sdk::Result<()> { + self.imp.call_reducer("shuffle_wall", ShuffleWallArgs {}) } - fn on_identity_connected( + fn on_shuffle_wall( &self, mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> IdentityConnectedCallbackId { - IdentityConnectedCallbackId(self.imp.on_reducer( - "identity_connected", + ) -> ShuffleWallCallbackId { + ShuffleWallCallbackId(self.imp.on_reducer( + "shuffle_wall", Box::new(move |ctx: &super::ReducerEventContext| { #[allow(irrefutable_let_patterns)] let super::ReducerEventContext { event: __sdk::ReducerEvent { - reducer: super::Reducer::IdentityConnected {}, + reducer: super::Reducer::ShuffleWall {}, .. }, .. @@ -75,27 +74,27 @@ impl identity_connected for super::RemoteReducers { }), )) } - fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId) { - self.imp.remove_on_reducer("identity_connected", callback.0) + fn remove_on_shuffle_wall(&self, callback: ShuffleWallCallbackId) { + self.imp.remove_on_reducer("shuffle_wall", callback.0) } } #[allow(non_camel_case_types)] #[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `identity_connected`. +/// Extension trait for setting the call-flags for the reducer `shuffle_wall`. /// /// Implemented for [`super::SetReducerFlags`]. /// /// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_identity_connected { - /// Set the call-reducer flags for the reducer `identity_connected` to `flags`. +pub trait set_flags_for_shuffle_wall { + /// Set the call-reducer flags for the reducer `shuffle_wall` to `flags`. /// /// This type is currently unstable and may be removed without a major version bump. - fn identity_connected(&self, flags: __ws::CallReducerFlags); + fn shuffle_wall(&self, flags: __ws::CallReducerFlags); } -impl set_flags_for_identity_connected for super::SetReducerFlags { - fn identity_connected(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("identity_connected", flags); +impl set_flags_for_shuffle_wall for super::SetReducerFlags { + fn shuffle_wall(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("shuffle_wall", flags); } } diff --git a/module_bindings/say_hello_reducer.rs b/module_bindings/sort_hand_reducer.rs similarity index 56% rename from module_bindings/say_hello_reducer.rs rename to module_bindings/sort_hand_reducer.rs index d326602..5673374 100644 --- a/module_bindings/say_hello_reducer.rs +++ b/module_bindings/sort_hand_reducer.rs @@ -6,63 +6,63 @@ 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 SayHelloArgs {} +pub(super) struct SortHandArgs {} -impl From for super::Reducer { - fn from(args: SayHelloArgs) -> Self { - Self::SayHello +impl From for super::Reducer { + fn from(args: SortHandArgs) -> Self { + Self::SortHand } } -impl __sdk::InModule for SayHelloArgs { +impl __sdk::InModule for SortHandArgs { type Module = super::RemoteModule; } -pub struct SayHelloCallbackId(__sdk::CallbackId); +pub struct SortHandCallbackId(__sdk::CallbackId); #[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `say_hello`. +/// Extension trait for access to the reducer `sort_hand`. /// /// Implemented for [`super::RemoteReducers`]. -pub trait say_hello { - /// Request that the remote module invoke the reducer `say_hello` to run as soon as possible. +pub trait sort_hand { + /// Request that the remote module invoke the reducer `sort_hand` to run as soon as possible. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, - /// and its status can be observed by listening for [`Self::on_say_hello`] callbacks. - fn say_hello(&self) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `say_hello`. + /// and its status can be observed by listening for [`Self::on_sort_hand`] callbacks. + fn sort_hand(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `sort_hand`. /// /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] /// to determine the reducer's status. /// - /// The returned [`SayHelloCallbackId`] can be passed to [`Self::remove_on_say_hello`] + /// The returned [`SortHandCallbackId`] can be passed to [`Self::remove_on_sort_hand`] /// to cancel the callback. - fn on_say_hello( + fn on_sort_hand( &self, callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> SayHelloCallbackId; - /// Cancel a callback previously registered by [`Self::on_say_hello`], + ) -> SortHandCallbackId; + /// Cancel a callback previously registered by [`Self::on_sort_hand`], /// causing it not to run in the future. - fn remove_on_say_hello(&self, callback: SayHelloCallbackId); + fn remove_on_sort_hand(&self, callback: SortHandCallbackId); } -impl say_hello for super::RemoteReducers { - fn say_hello(&self) -> __sdk::Result<()> { - self.imp.call_reducer("say_hello", SayHelloArgs {}) +impl sort_hand for super::RemoteReducers { + fn sort_hand(&self) -> __sdk::Result<()> { + self.imp.call_reducer("sort_hand", SortHandArgs {}) } - fn on_say_hello( + fn on_sort_hand( &self, mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> SayHelloCallbackId { - SayHelloCallbackId(self.imp.on_reducer( - "say_hello", + ) -> SortHandCallbackId { + SortHandCallbackId(self.imp.on_reducer( + "sort_hand", Box::new(move |ctx: &super::ReducerEventContext| { #[allow(irrefutable_let_patterns)] let super::ReducerEventContext { event: __sdk::ReducerEvent { - reducer: super::Reducer::SayHello {}, + reducer: super::Reducer::SortHand {}, .. }, .. @@ -74,27 +74,27 @@ impl say_hello for super::RemoteReducers { }), )) } - fn remove_on_say_hello(&self, callback: SayHelloCallbackId) { - self.imp.remove_on_reducer("say_hello", callback.0) + fn remove_on_sort_hand(&self, callback: SortHandCallbackId) { + self.imp.remove_on_reducer("sort_hand", callback.0) } } #[allow(non_camel_case_types)] #[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `say_hello`. +/// Extension trait for setting the call-flags for the reducer `sort_hand`. /// /// Implemented for [`super::SetReducerFlags`]. /// /// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_say_hello { - /// Set the call-reducer flags for the reducer `say_hello` to `flags`. +pub trait set_flags_for_sort_hand { + /// Set the call-reducer flags for the reducer `sort_hand` to `flags`. /// /// This type is currently unstable and may be removed without a major version bump. - fn say_hello(&self, flags: __ws::CallReducerFlags); + fn sort_hand(&self, flags: __ws::CallReducerFlags); } -impl set_flags_for_say_hello for super::SetReducerFlags { - fn say_hello(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("say_hello", flags); +impl set_flags_for_sort_hand for super::SetReducerFlags { + fn sort_hand(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("sort_hand", flags); } } diff --git a/module_bindings/suit_type.rs b/module_bindings/suit_type.rs new file mode 100644 index 0000000..be17c21 --- /dev/null +++ b/module_bindings/suit_type.rs @@ -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; +} diff --git a/module_bindings/tile_type.rs b/module_bindings/tile_type.rs new file mode 100644 index 0000000..64b1919 --- /dev/null +++ b/module_bindings/tile_type.rs @@ -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; +} diff --git a/module_bindings/wall_table.rs b/module_bindings/wall_table.rs new file mode 100644 index 0000000..bd24f06 --- /dev/null +++ b/module_bindings/wall_table.rs @@ -0,0 +1,96 @@ +// 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::tile_type::Tile; +use super::wall_type::Wall; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `wall`. +/// +/// Obtain a handle from the [`WallTableAccess::wall`] method on [`super::RemoteTables`], +/// like `ctx.db.wall()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.wall().on_insert(...)`. +pub struct WallTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `wall`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait WallTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`WallTableHandle`], which mediates access to the table `wall`. + fn wall(&self) -> WallTableHandle<'_>; +} + +impl WallTableAccess for super::RemoteTables { + fn wall(&self) -> WallTableHandle<'_> { + WallTableHandle { + imp: self.imp.get_table::("wall"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct WallInsertCallbackId(__sdk::CallbackId); +pub struct WallDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for WallTableHandle<'ctx> { + type Row = Wall; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = WallInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> WallInsertCallbackId { + WallInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: WallInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = WallDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> WallDeleteCallbackId { + WallDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: WallDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("wall"); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} diff --git a/module_bindings/wall_type.rs b/module_bindings/wall_type.rs new file mode 100644 index 0000000..f50341c --- /dev/null +++ b/module_bindings/wall_type.rs @@ -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::tile_type::Tile; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct Wall { + pub tiles: Vec, +} + +impl __sdk::InModule for Wall { + type Module = super::RemoteModule; +} diff --git a/module_bindings/wind_type.rs b/module_bindings/wind_type.rs new file mode 100644 index 0000000..a1c3965 --- /dev/null +++ b/module_bindings/wind_type.rs @@ -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; +} diff --git a/spacetimedb/Cargo.toml b/spacetimedb/Cargo.toml index 4697101..3a7227d 100644 --- a/spacetimedb/Cargo.toml +++ b/spacetimedb/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["cdylib"] [dependencies] spacetimedb = { workspace = true } log = { workspace = true } -jong = { workspace = true } +jong-types = { workspace = true } diff --git a/spacetimedb/src/lib.rs b/spacetimedb/src/lib.rs index 3e45fc5..134a022 100644 --- a/spacetimedb/src/lib.rs +++ b/spacetimedb/src/lib.rs @@ -1,11 +1,13 @@ -use spacetimedb::{Identity, ReducerContext, Table, rand::Rng, reducer, table}; +use spacetimedb::{rand::seq::SliceRandom, reducer, table, Identity, ReducerContext, Table}; -use jong::tile::Tile; +use jong_types::*; #[table(name = player, public)] pub struct Player { #[primary_key] identity: Identity, + #[auto_inc] + id: u32, name: Option, host: bool, } @@ -15,20 +17,14 @@ pub struct Wall { tiles: Vec, } -#[reducer(init)] -pub fn init(_ctx: &ReducerContext) { - // Called when the module is initially published +#[table(name = hand)] +pub struct Hand { + player_id: u32, + tiles: Vec, } -#[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_player(ctx: &ReducerContext, name: Option) {} #[reducer] pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> { @@ -49,14 +45,31 @@ pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> { #[reducer] pub fn shuffle_wall(ctx: &ReducerContext) { let mut rng = ctx.rng(); - let mut tiles: Vec = todo(); - - // rng.fill(); - // let tiles = rng.sh; - - ctx.db.wall().insert(Wall {tiles}); + let mut tiles: Vec = tiles(); + tiles.shuffle(&mut rng); + ctx.db.wall().insert(Wall { tiles }); } +#[reducer] +pub fn sort_hand(ctx: &ReducerContext) { + todo!() +} + +// #[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 }); From 004aafd4ba43e605f2315094af266796e75d88a6 Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Sat, 7 Feb 2026 20:18:17 -0800 Subject: [PATCH 05/11] devenv --- .envrc | 17 +++--- .gitignore | 11 ++++ devenv.lock | 143 ++++++++++++++++++++++++++++++++++++++++++++ devenv.nix | 57 ++++++++++++++++++ devenv.yaml | 8 +++ justfile | 4 +- rust-toolchain.toml | 2 - 7 files changed, 231 insertions(+), 11 deletions(-) create mode 100644 devenv.lock create mode 100644 devenv.nix create mode 100644 devenv.yaml delete mode 100644 rust-toolchain.toml diff --git a/.envrc b/.envrc index 82b2b9e..cc5c18b 100644 --- a/.envrc +++ b/.envrc @@ -1,9 +1,12 @@ #!/usr/bin/env bash -# the shebang is ignored, but nice for editors -if type -P lorri &>/dev/null; then - eval "$(lorri direnv)" -else - echo 'while direnv evaluated .envrc, could not find the command "lorri" [https://github.com/nix-community/lorri]' - use nix -fi +export DIRENV_WARN_TIMEOUT=20s + +eval "$(devenv direnvrc)" + +# `use devenv` supports the same options as the `devenv shell` command. +# +# To silence all output, use `--quiet`. +# +# Example usage: use devenv --quiet --impure --option services.postgres.enable:bool true +use devenv diff --git a/.gitignore b/.gitignore index eb5a316..cbec1d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,12 @@ target + +# Devenv +.devenv* +devenv.local.nix +devenv.local.yaml + +# direnv +.direnv + +# pre-commit +.pre-commit-config.yaml diff --git a/devenv.lock b/devenv.lock new file mode 100644 index 0000000..dfdab03 --- /dev/null +++ b/devenv.lock @@ -0,0 +1,143 @@ +{ + "nodes": { + "devenv": { + "locked": { + "dir": "src/modules", + "lastModified": 1770399425, + "owner": "cachix", + "repo": "devenv", + "rev": "0f006b2e9f591cc44cf219048b5e33793530403b", + "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": 1770520253, + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "ebb8a141f60bb0ec33836333e0ca7928a072217f", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/devenv.nix b/devenv.nix new file mode 100644 index 0000000..f7dde90 --- /dev/null +++ b/devenv.nix @@ -0,0 +1,57 @@ +{ + pkgs, + lib, + config, + inputs, + ... +}: rec { + # https://devenv.sh/packages/ + packages = with pkgs; [ + pkg-config + + # spacetimedb + openssl + binaryen + + # 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"]; + }; + + # https://devenv.sh/processes/ + processes.spacetimedb_start.exec = "spacetime start"; + processes.spacetimedb_generate_bindings = { + exec = "spacetime dev --module-bindings-path module_bindings jongline"; + }; + + # 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/ +} diff --git a/devenv.yaml b/devenv.yaml new file mode 100644 index 0000000..37e8589 --- /dev/null +++ b/devenv.yaml @@ -0,0 +1,8 @@ +inputs: + nixpkgs: + url: github:cachix/devenv-nixpkgs/rolling + rust-overlay: + url: github:oxalica/rust-overlay + inputs: + nixpkgs: + follows: nixpkgs diff --git a/justfile b/justfile index f8f62e9..3950586 100644 --- a/justfile +++ b/justfile @@ -11,7 +11,7 @@ run-tui: update: cargo update - nix flake update + devenv update spacetime: - spacetime dev --module-bindings-path module_bindings fantastic-key-0909 + devenv up diff --git a/rust-toolchain.toml b/rust-toolchain.toml deleted file mode 100644 index 5d56faf..0000000 --- a/rust-toolchain.toml +++ /dev/null @@ -1,2 +0,0 @@ -[toolchain] -channel = "nightly" From 655123b0551b45c8351c6986b918bf1622780c66 Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Sat, 7 Feb 2026 22:45:43 -0800 Subject: [PATCH 06/11] integrate --- Cargo.lock | 27 +- Cargo.toml | 22 +- devenv.nix | 2 +- jong-types/Cargo.toml | 4 +- jong/Cargo.toml | 26 +- jong/src/game.rs | 8 + jong/src/lib.rs | 7 +- jong/src/main.rs | 10 +- .../src/stdb}/add_player_reducer.rs | 0 .../src/stdb/deal_hands_reducer.rs | 68 +- .../src/stdb}/dragon_type.rs | 0 .../src/stdb}/hand_table.rs | 49 + .../src/stdb}/hand_type.rs | 2 +- jong/src/stdb/insert_wall_reducer.rs | 105 +++ jong/src/stdb/join_or_create_lobby_reducer.rs | 105 +++ jong/src/stdb/lobby_table.rs | 142 +++ .../src/stdb/lobby_type.rs | 7 +- {module_bindings => jong/src/stdb}/mod.rs | 66 +- .../src/stdb}/player_table.rs | 0 .../src/stdb}/player_type.rs | 3 +- jong/src/stdb/pond_table.rs | 96 ++ jong/src/stdb/pond_type.rs | 17 + .../src/stdb}/rank_type.rs | 0 .../src/stdb}/set_name_reducer.rs | 0 .../src/stdb}/shuffle_wall_reducer.rs | 0 .../src/stdb}/sort_hand_reducer.rs | 0 .../src/stdb}/suit_type.rs | 0 .../src/stdb}/tile_type.rs | 0 .../src/stdb}/wall_table.rs | 47 + .../src/stdb}/wall_type.rs | 1 + .../src/stdb}/wind_type.rs | 0 spacetimedb/src/lib.rs | 59 +- src/module_bindings/add_reducer.rs | 102 -- .../identity_connected_reducer.rs | 101 -- .../identity_disconnected_reducer.rs | 103 -- src/module_bindings/mod.rs | 876 ------------------ src/module_bindings/person_table.rs | 95 -- 37 files changed, 765 insertions(+), 1385 deletions(-) rename {module_bindings => jong/src/stdb}/add_player_reducer.rs (100%) rename src/module_bindings/say_hello_reducer.rs => jong/src/stdb/deal_hands_reducer.rs (55%) rename {module_bindings => jong/src/stdb}/dragon_type.rs (100%) rename {module_bindings => jong/src/stdb}/hand_table.rs (62%) rename {module_bindings => jong/src/stdb}/hand_type.rs (92%) create mode 100644 jong/src/stdb/insert_wall_reducer.rs create mode 100644 jong/src/stdb/join_or_create_lobby_reducer.rs create mode 100644 jong/src/stdb/lobby_table.rs rename src/module_bindings/person_type.rs => jong/src/stdb/lobby_type.rs (79%) rename {module_bindings => jong/src/stdb}/mod.rs (91%) rename {module_bindings => jong/src/stdb}/player_table.rs (100%) rename {module_bindings => jong/src/stdb}/player_type.rs (93%) create mode 100644 jong/src/stdb/pond_table.rs create mode 100644 jong/src/stdb/pond_type.rs rename {module_bindings => jong/src/stdb}/rank_type.rs (100%) rename {module_bindings => jong/src/stdb}/set_name_reducer.rs (100%) rename {module_bindings => jong/src/stdb}/shuffle_wall_reducer.rs (100%) rename {module_bindings => jong/src/stdb}/sort_hand_reducer.rs (100%) rename {module_bindings => jong/src/stdb}/suit_type.rs (100%) rename {module_bindings => jong/src/stdb}/tile_type.rs (100%) rename {module_bindings => jong/src/stdb}/wall_table.rs (64%) rename {module_bindings => jong/src/stdb}/wall_type.rs (96%) rename {module_bindings => jong/src/stdb}/wind_type.rs (100%) delete mode 100644 src/module_bindings/add_reducer.rs delete mode 100644 src/module_bindings/identity_connected_reducer.rs delete mode 100644 src/module_bindings/identity_disconnected_reducer.rs delete mode 100644 src/module_bindings/mod.rs delete mode 100644 src/module_bindings/person_table.rs diff --git a/Cargo.lock b/Cargo.lock index dcae9e4..fef7adf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1694,7 +1694,7 @@ dependencies = [ "bitflags 2.10.0", "cexpr", "clang-sys", - "itertools 0.13.0", + "itertools 0.12.1", "proc-macro2", "quote", "regex", @@ -3680,15 +3680,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.14.0" @@ -3749,6 +3740,7 @@ dependencies = [ "rand 0.9.2", "ratatui", "spacetimedb", + "spacetimedb-sdk", "strum 0.27.2", "tracing", "tracing-subscriber", @@ -4676,15 +4668,6 @@ dependencies = [ "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]] name = "owned_ttf_parser" version = "0.25.1" @@ -6258,7 +6241,7 @@ dependencies = [ "nix 0.29.0", "num-derive", "num-traits", - "ordered-float 4.6.0", + "ordered-float", "pest", "pest_derive", "phf", @@ -7083,7 +7066,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f2ab60e120fd6eaa68d9567f3226e876684639d22a4219b313ff69ec0ccd5ac" dependencies = [ "log", - "ordered-float 4.6.0", + "ordered-float", "strsim", "thiserror 1.0.69", "wezterm-dynamic-derive", @@ -7229,7 +7212,7 @@ dependencies = [ "naga", "ndk-sys 0.6.0+11769913", "objc", - "ordered-float 5.0.0", + "ordered-float", "parking_lot", "portable-atomic", "portable-atomic-util", diff --git a/Cargo.toml b/Cargo.toml index 4c025c7..c283329 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,15 +3,28 @@ resolver = "3" 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" -strum = "0.27.2" +ratatui = "0.30.0" tracing = "0.1.44" tracing-subscriber = "0.3.22" -jong = { version = "0.1.0", path = "jong" } -jong-types = { version = "0.1.0", path = "jong-types" } -spacetimedb = "1.11.*" +tui-logger = "0.18.0" [profile.dev] opt-level = 1 @@ -21,3 +34,4 @@ opt-level = 3 [patch.crates-io] bevy_ratatui = { path = "/home/tao/clones/bevy_ratatui" } +# bevy_spacetimedb = { path = "/home/tao/clones/bevy_spacetimedb/bevy_spacetimedb" } diff --git a/devenv.nix b/devenv.nix index f7dde90..57c530b 100644 --- a/devenv.nix +++ b/devenv.nix @@ -44,7 +44,7 @@ # https://devenv.sh/processes/ processes.spacetimedb_start.exec = "spacetime start"; processes.spacetimedb_generate_bindings = { - exec = "spacetime dev --module-bindings-path module_bindings jongline"; + exec = "spacetime dev --module-bindings-path jong/src/stdb jongline --delete-data=always"; }; # https://devenv.sh/services/ diff --git a/jong-types/Cargo.toml b/jong-types/Cargo.toml index 216a8df..a32f1b8 100644 --- a/jong-types/Cargo.toml +++ b/jong-types/Cargo.toml @@ -6,8 +6,6 @@ edition = "2024" [lib] [dependencies] -bevy.version = "0.17.3" -bevy.default-features = false +bevy.workspace = true spacetimedb.workspace = true strum.workspace = true -strum.features = ["derive"] diff --git a/jong/Cargo.toml b/jong/Cargo.toml index bf1e58f..a579d2f 100644 --- a/jong/Cargo.toml +++ b/jong/Cargo.toml @@ -10,23 +10,21 @@ readme = false [lib] [dependencies] -# bevy_ratatui = { git = "https://github.com/kenianbei/bevy_ratatui.git", rev = "e4b022308e08ab360ef89eca8e9f8b1c969e9a56" } -# bevy_ratatui = { path = "/home/tao/clones/bevy_ratatui" } -bevy.features = ["dynamic_linking"] -bevy.version = "0.17.3" -bevy_ratatui = "0.10.0" -bevy_spacetimedb = "0.7" +jong-types.workspace = true + +bevy = { workspace = true, features = ["default", "dynamic_linking"] } +bevy_ratatui.workspace = true +bevy_spacetimedb.workspace = true clap = { workspace = true, features = ["derive"] } -jong-types = { version = "0.1.0", path = "../jong-types" } log = { workspace = true, features = [ "release_max_level_error", "max_level_trace", ] } -rand = { workspace = true } -ratatui = "0.30.0" +rand.workspace = true +ratatui.workspace = true +spacetimedb-sdk.workspace = true spacetimedb.workspace = true -strum = { workspace = true, features = ["derive"] } -tracing = { workspace = true } -tracing-subscriber = { workspace = true } -tui-logger.features = ["tracing-support", "crossterm"] -tui-logger.version = "0.18.0" +strum.workspace = true +tracing.workspace = true +tracing-subscriber.workspace = true +tui-logger = { workspace = true, features = ["tracing-support", "crossterm"] } diff --git a/jong/src/game.rs b/jong/src/game.rs index adeb5fd..759b0ee 100644 --- a/jong/src/game.rs +++ b/jong/src/game.rs @@ -1,4 +1,5 @@ use bevy::prelude::*; +use bevy_spacetimedb::StdbPlugin; use crate::{ game::{ @@ -7,6 +8,7 @@ use crate::{ round::{TurnState, Wind}, wall::Wall, }, + stdb::DbConnection, tile::{self}, }; @@ -43,6 +45,12 @@ impl GameMessage { pub struct Riichi; impl Plugin for Riichi { fn build(&self, app: &mut App) { + // app.add_plugins( + // StdbPlugin::default() + // .with_uri("http://localhost:3000") + // .with_module_name("jongline") + // .with_run_fn(DbConnection::run_threaded), + // ); app // start stopper .init_state::() diff --git a/jong/src/lib.rs b/jong/src/lib.rs index eaa491e..8e711a7 100644 --- a/jong/src/lib.rs +++ b/jong/src/lib.rs @@ -3,15 +3,14 @@ use bevy::prelude::*; use bevy_spacetimedb::StdbConnection; -// mod jongline_bindings; -// use jongline_bindings::*; - pub mod game; pub mod tile; pub mod yakus; +mod stdb; + trait EnumNextCycle { fn next(&self) -> Self; } -// pub type SpacetimeDb<'a> = Res<'a, StdbConnection>; +pub type SpacetimeDB<'a> = Res<'a, StdbConnection>; diff --git a/jong/src/main.rs b/jong/src/main.rs index 53ed662..b29e0e9 100644 --- a/jong/src/main.rs +++ b/jong/src/main.rs @@ -1,5 +1,5 @@ use bevy::{log::LogPlugin, prelude::*}; -use bevy_spacetimedb::{StdbConnection, StdbPlugin, TableMessages}; +use bevy_spacetimedb::{StdbConnection, StdbPlugin}; use clap::{Parser, Subcommand}; use tracing::Level; 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.run(); diff --git a/module_bindings/add_player_reducer.rs b/jong/src/stdb/add_player_reducer.rs similarity index 100% rename from module_bindings/add_player_reducer.rs rename to jong/src/stdb/add_player_reducer.rs diff --git a/src/module_bindings/say_hello_reducer.rs b/jong/src/stdb/deal_hands_reducer.rs similarity index 55% rename from src/module_bindings/say_hello_reducer.rs rename to jong/src/stdb/deal_hands_reducer.rs index d326602..cb67ec4 100644 --- a/src/module_bindings/say_hello_reducer.rs +++ b/jong/src/stdb/deal_hands_reducer.rs @@ -6,63 +6,63 @@ 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 SayHelloArgs {} +pub(super) struct DealHandsArgs {} -impl From for super::Reducer { - fn from(args: SayHelloArgs) -> Self { - Self::SayHello +impl From for super::Reducer { + fn from(args: DealHandsArgs) -> Self { + Self::DealHands } } -impl __sdk::InModule for SayHelloArgs { +impl __sdk::InModule for DealHandsArgs { type Module = super::RemoteModule; } -pub struct SayHelloCallbackId(__sdk::CallbackId); +pub struct DealHandsCallbackId(__sdk::CallbackId); #[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `say_hello`. +/// Extension trait for access to the reducer `deal_hands`. /// /// Implemented for [`super::RemoteReducers`]. -pub trait say_hello { - /// Request that the remote module invoke the reducer `say_hello` to run as soon as possible. +pub trait deal_hands { + /// Request that the remote module invoke the reducer `deal_hands` to run as soon as possible. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, - /// and its status can be observed by listening for [`Self::on_say_hello`] callbacks. - fn say_hello(&self) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `say_hello`. + /// and its status can be observed by listening for [`Self::on_deal_hands`] callbacks. + fn deal_hands(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `deal_hands`. /// /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] /// to determine the reducer's status. /// - /// The returned [`SayHelloCallbackId`] can be passed to [`Self::remove_on_say_hello`] + /// The returned [`DealHandsCallbackId`] can be passed to [`Self::remove_on_deal_hands`] /// to cancel the callback. - fn on_say_hello( + fn on_deal_hands( &self, callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> SayHelloCallbackId; - /// Cancel a callback previously registered by [`Self::on_say_hello`], + ) -> DealHandsCallbackId; + /// Cancel a callback previously registered by [`Self::on_deal_hands`], /// causing it not to run in the future. - fn remove_on_say_hello(&self, callback: SayHelloCallbackId); + fn remove_on_deal_hands(&self, callback: DealHandsCallbackId); } -impl say_hello for super::RemoteReducers { - fn say_hello(&self) -> __sdk::Result<()> { - self.imp.call_reducer("say_hello", SayHelloArgs {}) +impl deal_hands for super::RemoteReducers { + fn deal_hands(&self) -> __sdk::Result<()> { + self.imp.call_reducer("deal_hands", DealHandsArgs {}) } - fn on_say_hello( + fn on_deal_hands( &self, mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> SayHelloCallbackId { - SayHelloCallbackId(self.imp.on_reducer( - "say_hello", + ) -> DealHandsCallbackId { + DealHandsCallbackId(self.imp.on_reducer( + "deal_hands", Box::new(move |ctx: &super::ReducerEventContext| { #[allow(irrefutable_let_patterns)] let super::ReducerEventContext { event: __sdk::ReducerEvent { - reducer: super::Reducer::SayHello {}, + reducer: super::Reducer::DealHands {}, .. }, .. @@ -74,27 +74,27 @@ impl say_hello for super::RemoteReducers { }), )) } - fn remove_on_say_hello(&self, callback: SayHelloCallbackId) { - self.imp.remove_on_reducer("say_hello", callback.0) + fn remove_on_deal_hands(&self, callback: DealHandsCallbackId) { + self.imp.remove_on_reducer("deal_hands", callback.0) } } #[allow(non_camel_case_types)] #[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `say_hello`. +/// Extension trait for setting the call-flags for the reducer `deal_hands`. /// /// Implemented for [`super::SetReducerFlags`]. /// /// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_say_hello { - /// Set the call-reducer flags for the reducer `say_hello` to `flags`. +pub trait set_flags_for_deal_hands { + /// Set the call-reducer flags for the reducer `deal_hands` to `flags`. /// /// This type is currently unstable and may be removed without a major version bump. - fn say_hello(&self, flags: __ws::CallReducerFlags); + fn deal_hands(&self, flags: __ws::CallReducerFlags); } -impl set_flags_for_say_hello for super::SetReducerFlags { - fn say_hello(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("say_hello", flags); +impl set_flags_for_deal_hands for super::SetReducerFlags { + fn deal_hands(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("deal_hands", flags); } } diff --git a/module_bindings/dragon_type.rs b/jong/src/stdb/dragon_type.rs similarity index 100% rename from module_bindings/dragon_type.rs rename to jong/src/stdb/dragon_type.rs diff --git a/module_bindings/hand_table.rs b/jong/src/stdb/hand_table.rs similarity index 62% rename from module_bindings/hand_table.rs rename to jong/src/stdb/hand_table.rs index d648970..905ed76 100644 --- a/module_bindings/hand_table.rs +++ b/jong/src/stdb/hand_table.rs @@ -82,6 +82,23 @@ impl<'ctx> __sdk::Table for HandTableHandle<'ctx> { #[doc(hidden)] pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { let _table = client_cache.get_or_make_table::("hand"); + _table.add_unique_constraint::<__sdk::Identity>("player_ident", |row| &row.player_ident); +} +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)] @@ -94,3 +111,35 @@ pub(super) fn parse_table_update( .into() }) } + +/// Access to the `player_ident` unique index on the table `hand`, +/// which allows point queries on the field of the same name +/// via the [`HandPlayerIdentUnique::find`] method. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.hand().player_ident().find(...)`. +pub struct HandPlayerIdentUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +impl<'ctx> HandTableHandle<'ctx> { + /// Get a handle on the `player_ident` unique index on the table `hand`. + pub fn player_ident(&self) -> HandPlayerIdentUnique<'ctx> { + HandPlayerIdentUnique { + imp: self + .imp + .get_unique_constraint::<__sdk::Identity>("player_ident"), + phantom: std::marker::PhantomData, + } + } +} + +impl<'ctx> HandPlayerIdentUnique<'ctx> { + /// Find the subscribed row whose `player_ident` 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 { + self.imp.find(col_val) + } +} diff --git a/module_bindings/hand_type.rs b/jong/src/stdb/hand_type.rs similarity index 92% rename from module_bindings/hand_type.rs rename to jong/src/stdb/hand_type.rs index 0f0dd43..f12c3c9 100644 --- a/module_bindings/hand_type.rs +++ b/jong/src/stdb/hand_type.rs @@ -9,7 +9,7 @@ use super::tile_type::Tile; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct Hand { - pub player_id: u32, + pub player_ident: __sdk::Identity, pub tiles: Vec, } diff --git a/jong/src/stdb/insert_wall_reducer.rs b/jong/src/stdb/insert_wall_reducer.rs new file mode 100644 index 0000000..2189dae --- /dev/null +++ b/jong/src/stdb/insert_wall_reducer.rs @@ -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 InsertWallArgs { + pub player_ids: Vec, +} + +impl From for super::Reducer { + fn from(args: InsertWallArgs) -> Self { + Self::InsertWall { + player_ids: args.player_ids, + } + } +} + +impl __sdk::InModule for InsertWallArgs { + type Module = super::RemoteModule; +} + +pub struct InsertWallCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `insert_wall`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait insert_wall { + /// Request that the remote module invoke the reducer `insert_wall` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_insert_wall`] callbacks. + fn insert_wall(&self, player_ids: Vec) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `insert_wall`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`InsertWallCallbackId`] can be passed to [`Self::remove_on_insert_wall`] + /// to cancel the callback. + fn on_insert_wall( + &self, + callback: impl FnMut(&super::ReducerEventContext, &Vec) + Send + 'static, + ) -> InsertWallCallbackId; + /// Cancel a callback previously registered by [`Self::on_insert_wall`], + /// causing it not to run in the future. + fn remove_on_insert_wall(&self, callback: InsertWallCallbackId); +} + +impl insert_wall for super::RemoteReducers { + fn insert_wall(&self, player_ids: Vec) -> __sdk::Result<()> { + self.imp + .call_reducer("insert_wall", InsertWallArgs { player_ids }) + } + fn on_insert_wall( + &self, + mut callback: impl FnMut(&super::ReducerEventContext, &Vec) + Send + 'static, + ) -> InsertWallCallbackId { + InsertWallCallbackId(self.imp.on_reducer( + "insert_wall", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::InsertWall { player_ids }, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx, player_ids) + }), + )) + } + fn remove_on_insert_wall(&self, callback: InsertWallCallbackId) { + self.imp.remove_on_reducer("insert_wall", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `insert_wall`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_insert_wall { + /// Set the call-reducer flags for the reducer `insert_wall` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn insert_wall(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_insert_wall for super::SetReducerFlags { + fn insert_wall(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("insert_wall", flags); + } +} diff --git a/jong/src/stdb/join_or_create_lobby_reducer.rs b/jong/src/stdb/join_or_create_lobby_reducer.rs new file mode 100644 index 0000000..594b092 --- /dev/null +++ b/jong/src/stdb/join_or_create_lobby_reducer.rs @@ -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 JoinOrCreateLobbyArgs { + pub lobby: Option, +} + +impl From for super::Reducer { + fn from(args: JoinOrCreateLobbyArgs) -> Self { + Self::JoinOrCreateLobby { lobby: args.lobby } + } +} + +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: Option) -> __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, &Option) + 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: Option) -> __sdk::Result<()> { + self.imp + .call_reducer("join_or_create_lobby", JoinOrCreateLobbyArgs { lobby }) + } + fn on_join_or_create_lobby( + &self, + mut callback: impl FnMut(&super::ReducerEventContext, &Option) + 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 }, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx, lobby) + }), + )) + } + 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); + } +} diff --git a/jong/src/stdb/lobby_table.rs b/jong/src/stdb/lobby_table.rs new file mode 100644 index 0000000..53f11a7 --- /dev/null +++ b/jong/src/stdb/lobby_table.rs @@ -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::lobby_type::Lobby; +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, + 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"), + 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 + '_ { + 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) { + let _table = client_cache.get_or_make_table::("lobby"); + _table.add_unique_constraint::("id", |row| &row.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> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "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, + 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::("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 { + self.imp.find(col_val) + } +} diff --git a/src/module_bindings/person_type.rs b/jong/src/stdb/lobby_type.rs similarity index 79% rename from src/module_bindings/person_type.rs rename to jong/src/stdb/lobby_type.rs index 56436ae..fcb5045 100644 --- a/src/module_bindings/person_type.rs +++ b/jong/src/stdb/lobby_type.rs @@ -6,10 +6,11 @@ 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 Person { - pub name: String, +pub struct Lobby { + pub id: u32, + pub host: __sdk::Identity, } -impl __sdk::InModule for Person { +impl __sdk::InModule for Lobby { type Module = super::RemoteModule; } diff --git a/module_bindings/mod.rs b/jong/src/stdb/mod.rs similarity index 91% rename from module_bindings/mod.rs rename to jong/src/stdb/mod.rs index 664e7d9..e6d9a19 100644 --- a/module_bindings/mod.rs +++ b/jong/src/stdb/mod.rs @@ -7,11 +7,18 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; pub mod add_player_reducer; +pub mod deal_hands_reducer; pub mod dragon_type; pub mod hand_table; pub mod hand_type; +pub mod insert_wall_reducer; +pub mod join_or_create_lobby_reducer; +pub mod lobby_table; +pub mod lobby_type; pub mod player_table; pub mod player_type; +pub mod pond_table; +pub mod pond_type; pub mod rank_type; pub mod set_name_reducer; pub mod shuffle_wall_reducer; @@ -23,11 +30,20 @@ pub mod wall_type; pub mod wind_type; pub use add_player_reducer::{add_player, set_flags_for_add_player, AddPlayerCallbackId}; +pub use deal_hands_reducer::{deal_hands, set_flags_for_deal_hands, DealHandsCallbackId}; pub use dragon_type::Dragon; pub use hand_table::*; pub use hand_type::Hand; +pub use insert_wall_reducer::{insert_wall, set_flags_for_insert_wall, InsertWallCallbackId}; +pub use join_or_create_lobby_reducer::{ + join_or_create_lobby, set_flags_for_join_or_create_lobby, JoinOrCreateLobbyCallbackId, +}; +pub use lobby_table::*; +pub use lobby_type::Lobby; pub use player_table::*; pub use player_type::Player; +pub use pond_table::*; +pub use pond_type::Pond; pub use rank_type::Rank; pub use set_name_reducer::{set_flags_for_set_name, set_name, SetNameCallbackId}; pub use shuffle_wall_reducer::{set_flags_for_shuffle_wall, shuffle_wall, ShuffleWallCallbackId}; @@ -47,6 +63,9 @@ pub use wind_type::Wind; pub enum Reducer { AddPlayer { name: Option }, + DealHands, + InsertWall { player_ids: Vec }, + JoinOrCreateLobby { lobby: Option }, SetName { name: String }, ShuffleWall, SortHand, @@ -60,6 +79,9 @@ impl __sdk::Reducer for Reducer { fn reducer_name(&self) -> &'static str { match self { Reducer::AddPlayer { .. } => "add_player", + Reducer::DealHands => "deal_hands", + Reducer::InsertWall { .. } => "insert_wall", + Reducer::JoinOrCreateLobby { .. } => "join_or_create_lobby", Reducer::SetName { .. } => "set_name", Reducer::ShuffleWall => "shuffle_wall", Reducer::SortHand => "sort_hand", @@ -78,6 +100,24 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { )? .into(), ), + "deal_hands" => Ok( + __sdk::parse_reducer_args::( + "deal_hands", + &value.args, + )? + .into(), + ), + "insert_wall" => Ok( + __sdk::parse_reducer_args::( + "insert_wall", + &value.args, + )? + .into(), + ), + "join_or_create_lobby" => Ok(__sdk::parse_reducer_args::< + join_or_create_lobby_reducer::JoinOrCreateLobbyArgs, + >("join_or_create_lobby", &value.args)? + .into()), "set_name" => Ok(__sdk::parse_reducer_args::( "set_name", &value.args, @@ -112,7 +152,9 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { #[doc(hidden)] pub struct DbUpdate { hand: __sdk::TableUpdate, + lobby: __sdk::TableUpdate, player: __sdk::TableUpdate, + pond: __sdk::TableUpdate, wall: __sdk::TableUpdate, } @@ -125,9 +167,15 @@ impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { "hand" => db_update .hand .append(hand_table::parse_table_update(table_update)?), + "lobby" => db_update + .lobby + .append(lobby_table::parse_table_update(table_update)?), "player" => db_update .player .append(player_table::parse_table_update(table_update)?), + "pond" => db_update + .pond + .append(pond_table::parse_table_update(table_update)?), "wall" => db_update .wall .append(wall_table::parse_table_update(table_update)?), @@ -157,11 +205,19 @@ impl __sdk::DbUpdate for DbUpdate { ) -> AppliedDiff<'_> { let mut diff = AppliedDiff::default(); - diff.hand = cache.apply_diff_to_table::("hand", &self.hand); + diff.hand = cache + .apply_diff_to_table::("hand", &self.hand) + .with_updates_by_pk(|row| &row.player_ident); + diff.lobby = cache + .apply_diff_to_table::("lobby", &self.lobby) + .with_updates_by_pk(|row| &row.id); diff.player = cache .apply_diff_to_table::("player", &self.player) .with_updates_by_pk(|row| &row.identity); - diff.wall = cache.apply_diff_to_table::("wall", &self.wall); + diff.pond = cache.apply_diff_to_table::("pond", &self.pond); + diff.wall = cache + .apply_diff_to_table::("wall", &self.wall) + .with_updates_by_pk(|row| &row.id); diff } @@ -172,7 +228,9 @@ impl __sdk::DbUpdate for DbUpdate { #[doc(hidden)] pub struct AppliedDiff<'r> { hand: __sdk::TableAppliedDiff<'r, Hand>, + lobby: __sdk::TableAppliedDiff<'r, Lobby>, player: __sdk::TableAppliedDiff<'r, Player>, + pond: __sdk::TableAppliedDiff<'r, Pond>, wall: __sdk::TableAppliedDiff<'r, Wall>, __unused: std::marker::PhantomData<&'r ()>, } @@ -188,7 +246,9 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { callbacks: &mut __sdk::DbCallbacks, ) { callbacks.invoke_table_row_callbacks::("hand", &self.hand, event); + callbacks.invoke_table_row_callbacks::("lobby", &self.lobby, event); callbacks.invoke_table_row_callbacks::("player", &self.player, event); + callbacks.invoke_table_row_callbacks::("pond", &self.pond, event); callbacks.invoke_table_row_callbacks::("wall", &self.wall, event); } } @@ -910,7 +970,9 @@ impl __sdk::SpacetimeModule for RemoteModule { fn register_tables(client_cache: &mut __sdk::ClientCache) { hand_table::register_table(client_cache); + lobby_table::register_table(client_cache); player_table::register_table(client_cache); + pond_table::register_table(client_cache); wall_table::register_table(client_cache); } } diff --git a/module_bindings/player_table.rs b/jong/src/stdb/player_table.rs similarity index 100% rename from module_bindings/player_table.rs rename to jong/src/stdb/player_table.rs diff --git a/module_bindings/player_type.rs b/jong/src/stdb/player_type.rs similarity index 93% rename from module_bindings/player_type.rs rename to jong/src/stdb/player_type.rs index 59fa7f6..266df28 100644 --- a/module_bindings/player_type.rs +++ b/jong/src/stdb/player_type.rs @@ -8,9 +8,8 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; #[sats(crate = __lib)] pub struct Player { pub identity: __sdk::Identity, - pub id: u32, pub name: Option, - pub host: bool, + pub lobby_id: u32, } impl __sdk::InModule for Player { diff --git a/jong/src/stdb/pond_table.rs b/jong/src/stdb/pond_table.rs new file mode 100644 index 0000000..0230d77 --- /dev/null +++ b/jong/src/stdb/pond_table.rs @@ -0,0 +1,96 @@ +// 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::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, + 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"), + 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 + '_ { + 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) { + let _table = client_cache.get_or_make_table::("pond"); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} diff --git a/jong/src/stdb/pond_type.rs b/jong/src/stdb/pond_type.rs new file mode 100644 index 0000000..3cfbd3e --- /dev/null +++ b/jong/src/stdb/pond_type.rs @@ -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::tile_type::Tile; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct Pond { + pub tiles: Vec, +} + +impl __sdk::InModule for Pond { + type Module = super::RemoteModule; +} diff --git a/module_bindings/rank_type.rs b/jong/src/stdb/rank_type.rs similarity index 100% rename from module_bindings/rank_type.rs rename to jong/src/stdb/rank_type.rs diff --git a/module_bindings/set_name_reducer.rs b/jong/src/stdb/set_name_reducer.rs similarity index 100% rename from module_bindings/set_name_reducer.rs rename to jong/src/stdb/set_name_reducer.rs diff --git a/module_bindings/shuffle_wall_reducer.rs b/jong/src/stdb/shuffle_wall_reducer.rs similarity index 100% rename from module_bindings/shuffle_wall_reducer.rs rename to jong/src/stdb/shuffle_wall_reducer.rs diff --git a/module_bindings/sort_hand_reducer.rs b/jong/src/stdb/sort_hand_reducer.rs similarity index 100% rename from module_bindings/sort_hand_reducer.rs rename to jong/src/stdb/sort_hand_reducer.rs diff --git a/module_bindings/suit_type.rs b/jong/src/stdb/suit_type.rs similarity index 100% rename from module_bindings/suit_type.rs rename to jong/src/stdb/suit_type.rs diff --git a/module_bindings/tile_type.rs b/jong/src/stdb/tile_type.rs similarity index 100% rename from module_bindings/tile_type.rs rename to jong/src/stdb/tile_type.rs diff --git a/module_bindings/wall_table.rs b/jong/src/stdb/wall_table.rs similarity index 64% rename from module_bindings/wall_table.rs rename to jong/src/stdb/wall_table.rs index bd24f06..79cd408 100644 --- a/module_bindings/wall_table.rs +++ b/jong/src/stdb/wall_table.rs @@ -82,6 +82,23 @@ impl<'ctx> __sdk::Table for WallTableHandle<'ctx> { #[doc(hidden)] pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { let _table = client_cache.get_or_make_table::("wall"); + _table.add_unique_constraint::("id", |row| &row.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)] @@ -94,3 +111,33 @@ pub(super) fn parse_table_update( .into() }) } + +/// Access to the `id` unique index on the table `wall`, +/// which allows point queries on the field of the same name +/// via the [`WallIdUnique::find`] method. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.wall().id().find(...)`. +pub struct WallIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +impl<'ctx> WallTableHandle<'ctx> { + /// Get a handle on the `id` unique index on the table `wall`. + pub fn id(&self) -> WallIdUnique<'ctx> { + WallIdUnique { + imp: self.imp.get_unique_constraint::("id"), + phantom: std::marker::PhantomData, + } + } +} + +impl<'ctx> WallIdUnique<'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 { + self.imp.find(col_val) + } +} diff --git a/module_bindings/wall_type.rs b/jong/src/stdb/wall_type.rs similarity index 96% rename from module_bindings/wall_type.rs rename to jong/src/stdb/wall_type.rs index f50341c..88a1e5f 100644 --- a/module_bindings/wall_type.rs +++ b/jong/src/stdb/wall_type.rs @@ -9,6 +9,7 @@ use super::tile_type::Tile; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct Wall { + pub id: u32, pub tiles: Vec, } diff --git a/module_bindings/wind_type.rs b/jong/src/stdb/wind_type.rs similarity index 100% rename from module_bindings/wind_type.rs rename to jong/src/stdb/wind_type.rs diff --git a/spacetimedb/src/lib.rs b/spacetimedb/src/lib.rs index 134a022..8b21eb3 100644 --- a/spacetimedb/src/lib.rs +++ b/spacetimedb/src/lib.rs @@ -2,29 +2,55 @@ use spacetimedb::{rand::seq::SliceRandom, reducer, table, Identity, ReducerConte use jong_types::*; -#[table(name = player, public)] +#[table(name = player)] pub struct Player { #[primary_key] identity: Identity, + + name: Option, + lobby_id: u32, +} + +#[table(name = lobby, public)] +pub struct Lobby { + #[primary_key] #[auto_inc] id: u32, - name: Option, - host: bool, + + host: Identity, } #[table(name = wall)] pub struct Wall { + #[primary_key] + #[auto_inc] + id: u32, + tiles: Vec, } #[table(name = hand)] pub struct Hand { - player_id: u32, + #[primary_key] + player_ident: Identity, + + tiles: Vec, +} + +#[table(name = pond, public)] +pub struct Pond { tiles: Vec, } #[reducer] -pub fn add_player(ctx: &ReducerContext, name: Option) {} +pub fn add_player(ctx: &ReducerContext, name: Option) { + let identity = ctx.identity(); + ctx.db.player().insert(Player { + identity, + name, + lobby_id: 0, + }); +} #[reducer] pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> { @@ -42,12 +68,27 @@ pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> { } } +#[reducer] +pub fn join_or_create_lobby(ctx: &ReducerContext, lobby: Option) -> Result<(), String> { + let player = ctx.db.player().identity().find(ctx.sender).unwrap(); + + todo!() +} + +#[reducer] +pub fn insert_wall(ctx: &ReducerContext, player_ids: Vec) { + let tiles: Vec = tiles(); + ctx.db.wall().insert(Wall { id: 0, tiles }); +} + #[reducer] pub fn shuffle_wall(ctx: &ReducerContext) { - let mut rng = ctx.rng(); - let mut tiles: Vec = tiles(); - tiles.shuffle(&mut rng); - ctx.db.wall().insert(Wall { tiles }); + todo!() +} + +#[reducer] +pub fn deal_hands(ctx: &ReducerContext) { + todo!() } #[reducer] diff --git a/src/module_bindings/add_reducer.rs b/src/module_bindings/add_reducer.rs deleted file mode 100644 index 5bfecc3..0000000 --- a/src/module_bindings/add_reducer.rs +++ /dev/null @@ -1,102 +0,0 @@ -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. - -#![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] -#[sats(crate = __lib)] -pub(super) struct AddArgs { - pub name: String, -} - -impl From for super::Reducer { - fn from(args: AddArgs) -> Self { - Self::Add { name: args.name } - } -} - -impl __sdk::InModule for AddArgs { - type Module = super::RemoteModule; -} - -pub struct AddCallbackId(__sdk::CallbackId); - -#[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `add`. -/// -/// Implemented for [`super::RemoteReducers`]. -pub trait add { - /// Request that the remote module invoke the reducer `add` 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`] callbacks. - fn add(&self, name: String) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `add`. - /// - /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] - /// to determine the reducer's status. - /// - /// The returned [`AddCallbackId`] can be passed to [`Self::remove_on_add`] - /// to cancel the callback. - fn on_add( - &self, - callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, - ) -> AddCallbackId; - /// Cancel a callback previously registered by [`Self::on_add`], - /// causing it not to run in the future. - fn remove_on_add(&self, callback: AddCallbackId); -} - -impl add for super::RemoteReducers { - fn add(&self, name: String) -> __sdk::Result<()> { - self.imp.call_reducer("add", AddArgs { name }) - } - fn on_add( - &self, - mut callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, - ) -> AddCallbackId { - AddCallbackId(self.imp.on_reducer( - "add", - Box::new(move |ctx: &super::ReducerEventContext| { - #[allow(irrefutable_let_patterns)] - let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::Add { name }, - .. - }, - .. - } = ctx - else { - unreachable!() - }; - callback(ctx, name) - }), - )) - } - fn remove_on_add(&self, callback: AddCallbackId) { - self.imp.remove_on_reducer("add", callback.0) - } -} - -#[allow(non_camel_case_types)] -#[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `add`. -/// -/// Implemented for [`super::SetReducerFlags`]. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_add { - /// Set the call-reducer flags for the reducer `add` to `flags`. - /// - /// This type is currently unstable and may be removed without a major version bump. - fn add(&self, flags: __ws::CallReducerFlags); -} - -impl set_flags_for_add for super::SetReducerFlags { - fn add(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("add", flags); - } -} diff --git a/src/module_bindings/identity_connected_reducer.rs b/src/module_bindings/identity_connected_reducer.rs deleted file mode 100644 index 2eaaab0..0000000 --- a/src/module_bindings/identity_connected_reducer.rs +++ /dev/null @@ -1,101 +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 IdentityConnectedArgs {} - -impl From for super::Reducer { - fn from(args: IdentityConnectedArgs) -> Self { - Self::IdentityConnected - } -} - -impl __sdk::InModule for IdentityConnectedArgs { - type Module = super::RemoteModule; -} - -pub struct IdentityConnectedCallbackId(__sdk::CallbackId); - -#[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `identity_connected`. -/// -/// Implemented for [`super::RemoteReducers`]. -pub trait identity_connected { - /// Request that the remote module invoke the reducer `identity_connected` 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_connected`] callbacks. - fn identity_connected(&self) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `identity_connected`. - /// - /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] - /// to determine the reducer's status. - /// - /// The returned [`IdentityConnectedCallbackId`] can be passed to [`Self::remove_on_identity_connected`] - /// to cancel the callback. - fn on_identity_connected( - &self, - callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> IdentityConnectedCallbackId; - /// Cancel a callback previously registered by [`Self::on_identity_connected`], - /// causing it not to run in the future. - fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId); -} - -impl identity_connected for super::RemoteReducers { - fn identity_connected(&self) -> __sdk::Result<()> { - self.imp - .call_reducer("identity_connected", IdentityConnectedArgs {}) - } - fn on_identity_connected( - &self, - mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> IdentityConnectedCallbackId { - IdentityConnectedCallbackId(self.imp.on_reducer( - "identity_connected", - Box::new(move |ctx: &super::ReducerEventContext| { - #[allow(irrefutable_let_patterns)] - let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::IdentityConnected {}, - .. - }, - .. - } = ctx - else { - unreachable!() - }; - callback(ctx) - }), - )) - } - fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId) { - self.imp.remove_on_reducer("identity_connected", callback.0) - } -} - -#[allow(non_camel_case_types)] -#[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `identity_connected`. -/// -/// Implemented for [`super::SetReducerFlags`]. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_identity_connected { - /// Set the call-reducer flags for the reducer `identity_connected` to `flags`. - /// - /// This type is currently unstable and may be removed without a major version bump. - fn identity_connected(&self, flags: __ws::CallReducerFlags); -} - -impl set_flags_for_identity_connected for super::SetReducerFlags { - fn identity_connected(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("identity_connected", flags); - } -} diff --git a/src/module_bindings/identity_disconnected_reducer.rs b/src/module_bindings/identity_disconnected_reducer.rs deleted file mode 100644 index c2892ed..0000000 --- a/src/module_bindings/identity_disconnected_reducer.rs +++ /dev/null @@ -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 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); - } -} diff --git a/src/module_bindings/mod.rs b/src/module_bindings/mod.rs deleted file mode 100644 index e89f725..0000000 --- a/src/module_bindings/mod.rs +++ /dev/null @@ -1,876 +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. - -// This was generated using spacetimedb cli version 1.11.3 (commit 02449737ca3b29e7e39679fccbef541a50f32094). - -#![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -pub mod add_reducer; -pub mod identity_connected_reducer; -pub mod identity_disconnected_reducer; -pub mod person_table; -pub mod person_type; -pub mod say_hello_reducer; - -pub use add_reducer::{add, set_flags_for_add, AddCallbackId}; -pub use identity_connected_reducer::{ - identity_connected, set_flags_for_identity_connected, IdentityConnectedCallbackId, -}; -pub use identity_disconnected_reducer::{ - identity_disconnected, set_flags_for_identity_disconnected, IdentityDisconnectedCallbackId, -}; -pub use person_table::*; -pub use person_type::Person; -pub use say_hello_reducer::{say_hello, set_flags_for_say_hello, SayHelloCallbackId}; - -#[derive(Clone, PartialEq, Debug)] - -/// One of the reducers defined by this module. -/// -/// Contained within a [`__sdk::ReducerEvent`] in [`EventContext`]s for reducer events -/// to indicate which reducer caused the event. - -pub enum Reducer { - Add { name: String }, - IdentityConnected, - IdentityDisconnected, - SayHello, -} - -impl __sdk::InModule for Reducer { - type Module = RemoteModule; -} - -impl __sdk::Reducer for Reducer { - fn reducer_name(&self) -> &'static str { - match self { - Reducer::Add { .. } => "add", - Reducer::IdentityConnected => "identity_connected", - Reducer::IdentityDisconnected => "identity_disconnected", - Reducer::SayHello => "say_hello", - _ => unreachable!(), - } - } -} -impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { - type Error = __sdk::Error; - fn try_from(value: __ws::ReducerCallInfo<__ws::BsatnFormat>) -> __sdk::Result { - match &value.reducer_name[..] { - "add" => { - Ok(__sdk::parse_reducer_args::("add", &value.args)?.into()) - } - "identity_connected" => Ok(__sdk::parse_reducer_args::< - identity_connected_reducer::IdentityConnectedArgs, - >("identity_connected", &value.args)? - .into()), - "identity_disconnected" => Ok(__sdk::parse_reducer_args::< - identity_disconnected_reducer::IdentityDisconnectedArgs, - >("identity_disconnected", &value.args)? - .into()), - "say_hello" => Ok( - __sdk::parse_reducer_args::( - "say_hello", - &value.args, - )? - .into(), - ), - unknown => { - Err( - __sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo") - .into(), - ) - } - } - } -} - -#[derive(Default)] -#[allow(non_snake_case)] -#[doc(hidden)] -pub struct DbUpdate { - person: __sdk::TableUpdate, -} - -impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { - type Error = __sdk::Error; - fn try_from(raw: __ws::DatabaseUpdate<__ws::BsatnFormat>) -> Result { - let mut db_update = DbUpdate::default(); - for table_update in raw.tables { - match &table_update.table_name[..] { - "person" => db_update - .person - .append(person_table::parse_table_update(table_update)?), - - unknown => { - return Err(__sdk::InternalError::unknown_name( - "table", - unknown, - "DatabaseUpdate", - ) - .into()); - } - } - } - Ok(db_update) - } -} - -impl __sdk::InModule for DbUpdate { - type Module = RemoteModule; -} - -impl __sdk::DbUpdate for DbUpdate { - fn apply_to_client_cache( - &self, - cache: &mut __sdk::ClientCache, - ) -> AppliedDiff<'_> { - let mut diff = AppliedDiff::default(); - - diff.person = cache.apply_diff_to_table::("person", &self.person); - - diff - } -} - -#[derive(Default)] -#[allow(non_snake_case)] -#[doc(hidden)] -pub struct AppliedDiff<'r> { - person: __sdk::TableAppliedDiff<'r, Person>, - __unused: std::marker::PhantomData<&'r ()>, -} - -impl __sdk::InModule for AppliedDiff<'_> { - type Module = RemoteModule; -} - -impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { - fn invoke_row_callbacks( - &self, - event: &EventContext, - callbacks: &mut __sdk::DbCallbacks, - ) { - callbacks.invoke_table_row_callbacks::("person", &self.person, event); - } -} - -#[doc(hidden)] -pub struct RemoteModule; - -impl __sdk::InModule for RemoteModule { - type Module = Self; -} - -/// The `reducers` field of [`EventContext`] and [`DbConnection`], -/// with methods provided by extension traits for each reducer defined by the module. -pub struct RemoteReducers { - imp: __sdk::DbContextImpl, -} - -impl __sdk::InModule for RemoteReducers { - type Module = RemoteModule; -} - -/// The `procedures` field of [`DbConnection`] and other [`DbContext`] types, -/// with methods provided by extension traits for each procedure defined by the module. -pub struct RemoteProcedures { - imp: __sdk::DbContextImpl, -} - -impl __sdk::InModule for RemoteProcedures { - type Module = RemoteModule; -} - -#[doc(hidden)] -/// The `set_reducer_flags` field of [`DbConnection`], -/// with methods provided by extension traits for each reducer defined by the module. -/// Each method sets the flags for the reducer with the same name. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub struct SetReducerFlags { - imp: __sdk::DbContextImpl, -} - -impl __sdk::InModule for SetReducerFlags { - type Module = RemoteModule; -} - -/// The `db` field of [`EventContext`] and [`DbConnection`], -/// with methods provided by extension traits for each table defined by the module. -pub struct RemoteTables { - imp: __sdk::DbContextImpl, -} - -impl __sdk::InModule for RemoteTables { - type Module = RemoteModule; -} - -/// A connection to a remote module, including a materialized view of a subset of the database. -/// -/// Connect to a remote module by calling [`DbConnection::builder`] -/// and using the [`__sdk::DbConnectionBuilder`] builder-pattern constructor. -/// -/// You must explicitly advance the connection by calling any one of: -/// -/// - [`DbConnection::frame_tick`]. -/// - [`DbConnection::run_threaded`]. -/// - [`DbConnection::run_async`]. -/// - [`DbConnection::advance_one_message`]. -/// - [`DbConnection::advance_one_message_blocking`]. -/// - [`DbConnection::advance_one_message_async`]. -/// -/// Which of these methods you should call depends on the specific needs of your application, -/// but you must call one of them, or else the connection will never progress. -pub struct DbConnection { - /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. - pub db: RemoteTables, - /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. - pub reducers: RemoteReducers, - #[doc(hidden)] - /// Access to setting the call-flags of each reducer defined for each reducer defined by the module - /// via extension traits implemented for [`SetReducerFlags`]. - /// - /// This type is currently unstable and may be removed without a major version bump. - pub set_reducer_flags: SetReducerFlags, - - /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. - pub procedures: RemoteProcedures, - - imp: __sdk::DbContextImpl, -} - -impl __sdk::InModule for DbConnection { - type Module = RemoteModule; -} - -impl __sdk::DbContext for DbConnection { - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; - - fn db(&self) -> &Self::DbView { - &self.db - } - fn reducers(&self) -> &Self::Reducers { - &self.reducers - } - fn procedures(&self) -> &Self::Procedures { - &self.procedures - } - fn set_reducer_flags(&self) -> &Self::SetReducerFlags { - &self.set_reducer_flags - } - - fn is_active(&self) -> bool { - self.imp.is_active() - } - - fn disconnect(&self) -> __sdk::Result<()> { - self.imp.disconnect() - } - - type SubscriptionBuilder = __sdk::SubscriptionBuilder; - - fn subscription_builder(&self) -> Self::SubscriptionBuilder { - __sdk::SubscriptionBuilder::new(&self.imp) - } - - fn try_identity(&self) -> Option<__sdk::Identity> { - self.imp.try_identity() - } - fn connection_id(&self) -> __sdk::ConnectionId { - self.imp.connection_id() - } - fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { - self.imp.try_connection_id() - } -} - -impl DbConnection { - /// Builder-pattern constructor for a connection to a remote module. - /// - /// See [`__sdk::DbConnectionBuilder`] for required and optional configuration for the new connection. - pub fn builder() -> __sdk::DbConnectionBuilder { - __sdk::DbConnectionBuilder::new() - } - - /// If any WebSocket messages are waiting, process one of them. - /// - /// Returns `true` if a message was processed, or `false` if the queue is empty. - /// Callers should invoke this message in a loop until it returns `false` - /// or for as much time is available to process messages. - /// - /// Returns an error if the connection is disconnected. - /// If the disconnection in question was normal, - /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], - /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. - /// - /// This is a low-level primitive exposed for power users who need significant control over scheduling. - /// Most applications should call [`Self::frame_tick`] each frame - /// to fully exhaust the queue whenever time is available. - pub fn advance_one_message(&self) -> __sdk::Result { - self.imp.advance_one_message() - } - - /// Process one WebSocket message, potentially blocking the current thread until one is received. - /// - /// Returns an error if the connection is disconnected. - /// If the disconnection in question was normal, - /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], - /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. - /// - /// This is a low-level primitive exposed for power users who need significant control over scheduling. - /// Most applications should call [`Self::run_threaded`] to spawn a thread - /// which advances the connection automatically. - pub fn advance_one_message_blocking(&self) -> __sdk::Result<()> { - self.imp.advance_one_message_blocking() - } - - /// Process one WebSocket message, `await`ing until one is received. - /// - /// Returns an error if the connection is disconnected. - /// If the disconnection in question was normal, - /// i.e. the result of a call to [`__sdk::DbContext::disconnect`], - /// the returned error will be downcastable to [`__sdk::DisconnectedError`]. - /// - /// This is a low-level primitive exposed for power users who need significant control over scheduling. - /// Most applications should call [`Self::run_async`] to run an `async` loop - /// which advances the connection when polled. - pub async fn advance_one_message_async(&self) -> __sdk::Result<()> { - self.imp.advance_one_message_async().await - } - - /// Process all WebSocket messages waiting in the queue, - /// then return without `await`ing or blocking the current thread. - pub fn frame_tick(&self) -> __sdk::Result<()> { - self.imp.frame_tick() - } - - /// Spawn a thread which processes WebSocket messages as they are received. - pub fn run_threaded(&self) -> std::thread::JoinHandle<()> { - self.imp.run_threaded() - } - - /// Run an `async` loop which processes WebSocket messages when polled. - pub async fn run_async(&self) -> __sdk::Result<()> { - self.imp.run_async().await - } -} - -impl __sdk::DbConnection for DbConnection { - fn new(imp: __sdk::DbContextImpl) -> Self { - Self { - db: RemoteTables { imp: imp.clone() }, - reducers: RemoteReducers { imp: imp.clone() }, - procedures: RemoteProcedures { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, - imp, - } - } -} - -/// A handle on a subscribed query. -// TODO: Document this better after implementing the new subscription API. -#[derive(Clone)] -pub struct SubscriptionHandle { - imp: __sdk::SubscriptionHandleImpl, -} - -impl __sdk::InModule for SubscriptionHandle { - type Module = RemoteModule; -} - -impl __sdk::SubscriptionHandle for SubscriptionHandle { - fn new(imp: __sdk::SubscriptionHandleImpl) -> Self { - Self { imp } - } - - /// Returns true if this subscription has been terminated due to an unsubscribe call or an error. - fn is_ended(&self) -> bool { - self.imp.is_ended() - } - - /// Returns true if this subscription has been applied and has not yet been unsubscribed. - fn is_active(&self) -> bool { - self.imp.is_active() - } - - /// Unsubscribe from the query controlled by this `SubscriptionHandle`, - /// then run `on_end` when its rows are removed from the client cache. - fn unsubscribe_then(self, on_end: __sdk::OnEndedCallback) -> __sdk::Result<()> { - self.imp.unsubscribe_then(Some(on_end)) - } - - fn unsubscribe(self) -> __sdk::Result<()> { - self.imp.unsubscribe_then(None) - } -} - -/// Alias trait for a [`__sdk::DbContext`] connected to this module, -/// with that trait's associated types bounded to this module's concrete types. -/// -/// Users can use this trait as a boundary on definitions which should accept -/// either a [`DbConnection`] or an [`EventContext`] and operate on either. -pub trait RemoteDbContext: - __sdk::DbContext< - DbView = RemoteTables, - Reducers = RemoteReducers, - SetReducerFlags = SetReducerFlags, - SubscriptionBuilder = __sdk::SubscriptionBuilder, -> -{ -} -impl< - Ctx: __sdk::DbContext< - DbView = RemoteTables, - Reducers = RemoteReducers, - SetReducerFlags = SetReducerFlags, - SubscriptionBuilder = __sdk::SubscriptionBuilder, - >, - > RemoteDbContext for Ctx -{ -} - -/// An [`__sdk::DbContext`] augmented with a [`__sdk::Event`], -/// passed to [`__sdk::Table::on_insert`], [`__sdk::Table::on_delete`] and [`__sdk::TableWithPrimaryKey::on_update`] callbacks. -pub struct EventContext { - /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. - pub db: RemoteTables, - /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. - pub reducers: RemoteReducers, - /// Access to setting the call-flags of each reducer defined for each reducer defined by the module - /// via extension traits implemented for [`SetReducerFlags`]. - /// - /// This type is currently unstable and may be removed without a major version bump. - pub set_reducer_flags: SetReducerFlags, - /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. - pub procedures: RemoteProcedures, - /// The event which caused these callbacks to run. - pub event: __sdk::Event, - imp: __sdk::DbContextImpl, -} - -impl __sdk::AbstractEventContext for EventContext { - type Event = __sdk::Event; - fn event(&self) -> &Self::Event { - &self.event - } - fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { - Self { - db: RemoteTables { imp: imp.clone() }, - reducers: RemoteReducers { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, - procedures: RemoteProcedures { imp: imp.clone() }, - event, - imp, - } - } -} - -impl __sdk::InModule for EventContext { - type Module = RemoteModule; -} - -impl __sdk::DbContext for EventContext { - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; - - fn db(&self) -> &Self::DbView { - &self.db - } - fn reducers(&self) -> &Self::Reducers { - &self.reducers - } - fn procedures(&self) -> &Self::Procedures { - &self.procedures - } - fn set_reducer_flags(&self) -> &Self::SetReducerFlags { - &self.set_reducer_flags - } - - fn is_active(&self) -> bool { - self.imp.is_active() - } - - fn disconnect(&self) -> __sdk::Result<()> { - self.imp.disconnect() - } - - type SubscriptionBuilder = __sdk::SubscriptionBuilder; - - fn subscription_builder(&self) -> Self::SubscriptionBuilder { - __sdk::SubscriptionBuilder::new(&self.imp) - } - - fn try_identity(&self) -> Option<__sdk::Identity> { - self.imp.try_identity() - } - fn connection_id(&self) -> __sdk::ConnectionId { - self.imp.connection_id() - } - fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { - self.imp.try_connection_id() - } -} - -impl __sdk::EventContext for EventContext {} - -/// An [`__sdk::DbContext`] augmented with a [`__sdk::ReducerEvent`], -/// passed to on-reducer callbacks. -pub struct ReducerEventContext { - /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. - pub db: RemoteTables, - /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. - pub reducers: RemoteReducers, - /// Access to setting the call-flags of each reducer defined for each reducer defined by the module - /// via extension traits implemented for [`SetReducerFlags`]. - /// - /// This type is currently unstable and may be removed without a major version bump. - pub set_reducer_flags: SetReducerFlags, - /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. - pub procedures: RemoteProcedures, - /// The event which caused these callbacks to run. - pub event: __sdk::ReducerEvent, - imp: __sdk::DbContextImpl, -} - -impl __sdk::AbstractEventContext for ReducerEventContext { - type Event = __sdk::ReducerEvent; - fn event(&self) -> &Self::Event { - &self.event - } - fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { - Self { - db: RemoteTables { imp: imp.clone() }, - reducers: RemoteReducers { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, - procedures: RemoteProcedures { imp: imp.clone() }, - event, - imp, - } - } -} - -impl __sdk::InModule for ReducerEventContext { - type Module = RemoteModule; -} - -impl __sdk::DbContext for ReducerEventContext { - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; - - fn db(&self) -> &Self::DbView { - &self.db - } - fn reducers(&self) -> &Self::Reducers { - &self.reducers - } - fn procedures(&self) -> &Self::Procedures { - &self.procedures - } - fn set_reducer_flags(&self) -> &Self::SetReducerFlags { - &self.set_reducer_flags - } - - fn is_active(&self) -> bool { - self.imp.is_active() - } - - fn disconnect(&self) -> __sdk::Result<()> { - self.imp.disconnect() - } - - type SubscriptionBuilder = __sdk::SubscriptionBuilder; - - fn subscription_builder(&self) -> Self::SubscriptionBuilder { - __sdk::SubscriptionBuilder::new(&self.imp) - } - - fn try_identity(&self) -> Option<__sdk::Identity> { - self.imp.try_identity() - } - fn connection_id(&self) -> __sdk::ConnectionId { - self.imp.connection_id() - } - fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { - self.imp.try_connection_id() - } -} - -impl __sdk::ReducerEventContext for ReducerEventContext {} - -/// An [`__sdk::DbContext`] passed to procedure callbacks. -pub struct ProcedureEventContext { - /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. - pub db: RemoteTables, - /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. - pub reducers: RemoteReducers, - /// Access to setting the call-flags of each reducer defined for each reducer defined by the module - /// via extension traits implemented for [`SetReducerFlags`]. - /// - /// This type is currently unstable and may be removed without a major version bump. - pub set_reducer_flags: SetReducerFlags, - /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. - pub procedures: RemoteProcedures, - imp: __sdk::DbContextImpl, -} - -impl __sdk::AbstractEventContext for ProcedureEventContext { - type Event = (); - fn event(&self) -> &Self::Event { - &() - } - fn new(imp: __sdk::DbContextImpl, _event: Self::Event) -> Self { - Self { - db: RemoteTables { imp: imp.clone() }, - reducers: RemoteReducers { imp: imp.clone() }, - procedures: RemoteProcedures { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, - imp, - } - } -} - -impl __sdk::InModule for ProcedureEventContext { - type Module = RemoteModule; -} - -impl __sdk::DbContext for ProcedureEventContext { - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; - - fn db(&self) -> &Self::DbView { - &self.db - } - fn reducers(&self) -> &Self::Reducers { - &self.reducers - } - fn procedures(&self) -> &Self::Procedures { - &self.procedures - } - fn set_reducer_flags(&self) -> &Self::SetReducerFlags { - &self.set_reducer_flags - } - - fn is_active(&self) -> bool { - self.imp.is_active() - } - - fn disconnect(&self) -> __sdk::Result<()> { - self.imp.disconnect() - } - - type SubscriptionBuilder = __sdk::SubscriptionBuilder; - - fn subscription_builder(&self) -> Self::SubscriptionBuilder { - __sdk::SubscriptionBuilder::new(&self.imp) - } - - fn try_identity(&self) -> Option<__sdk::Identity> { - self.imp.try_identity() - } - fn connection_id(&self) -> __sdk::ConnectionId { - self.imp.connection_id() - } - fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { - self.imp.try_connection_id() - } -} - -impl __sdk::ProcedureEventContext for ProcedureEventContext {} - -/// An [`__sdk::DbContext`] passed to [`__sdk::SubscriptionBuilder::on_applied`] and [`SubscriptionHandle::unsubscribe_then`] callbacks. -pub struct SubscriptionEventContext { - /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. - pub db: RemoteTables, - /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. - pub reducers: RemoteReducers, - /// Access to setting the call-flags of each reducer defined for each reducer defined by the module - /// via extension traits implemented for [`SetReducerFlags`]. - /// - /// This type is currently unstable and may be removed without a major version bump. - pub set_reducer_flags: SetReducerFlags, - /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. - pub procedures: RemoteProcedures, - imp: __sdk::DbContextImpl, -} - -impl __sdk::AbstractEventContext for SubscriptionEventContext { - type Event = (); - fn event(&self) -> &Self::Event { - &() - } - fn new(imp: __sdk::DbContextImpl, _event: Self::Event) -> Self { - Self { - db: RemoteTables { imp: imp.clone() }, - reducers: RemoteReducers { imp: imp.clone() }, - procedures: RemoteProcedures { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, - imp, - } - } -} - -impl __sdk::InModule for SubscriptionEventContext { - type Module = RemoteModule; -} - -impl __sdk::DbContext for SubscriptionEventContext { - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; - - fn db(&self) -> &Self::DbView { - &self.db - } - fn reducers(&self) -> &Self::Reducers { - &self.reducers - } - fn procedures(&self) -> &Self::Procedures { - &self.procedures - } - fn set_reducer_flags(&self) -> &Self::SetReducerFlags { - &self.set_reducer_flags - } - - fn is_active(&self) -> bool { - self.imp.is_active() - } - - fn disconnect(&self) -> __sdk::Result<()> { - self.imp.disconnect() - } - - type SubscriptionBuilder = __sdk::SubscriptionBuilder; - - fn subscription_builder(&self) -> Self::SubscriptionBuilder { - __sdk::SubscriptionBuilder::new(&self.imp) - } - - fn try_identity(&self) -> Option<__sdk::Identity> { - self.imp.try_identity() - } - fn connection_id(&self) -> __sdk::ConnectionId { - self.imp.connection_id() - } - fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { - self.imp.try_connection_id() - } -} - -impl __sdk::SubscriptionEventContext for SubscriptionEventContext {} - -/// An [`__sdk::DbContext`] augmented with a [`__sdk::Error`], -/// passed to [`__sdk::DbConnectionBuilder::on_disconnect`], [`__sdk::DbConnectionBuilder::on_connect_error`] and [`__sdk::SubscriptionBuilder::on_error`] callbacks. -pub struct ErrorContext { - /// Access to tables defined by the module via extension traits implemented for [`RemoteTables`]. - pub db: RemoteTables, - /// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`]. - pub reducers: RemoteReducers, - /// Access to setting the call-flags of each reducer defined for each reducer defined by the module - /// via extension traits implemented for [`SetReducerFlags`]. - /// - /// This type is currently unstable and may be removed without a major version bump. - pub set_reducer_flags: SetReducerFlags, - /// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`]. - pub procedures: RemoteProcedures, - /// The event which caused these callbacks to run. - pub event: Option<__sdk::Error>, - imp: __sdk::DbContextImpl, -} - -impl __sdk::AbstractEventContext for ErrorContext { - type Event = Option<__sdk::Error>; - fn event(&self) -> &Self::Event { - &self.event - } - fn new(imp: __sdk::DbContextImpl, event: Self::Event) -> Self { - Self { - db: RemoteTables { imp: imp.clone() }, - reducers: RemoteReducers { imp: imp.clone() }, - set_reducer_flags: SetReducerFlags { imp: imp.clone() }, - procedures: RemoteProcedures { imp: imp.clone() }, - event, - imp, - } - } -} - -impl __sdk::InModule for ErrorContext { - type Module = RemoteModule; -} - -impl __sdk::DbContext for ErrorContext { - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type Procedures = RemoteProcedures; - type SetReducerFlags = SetReducerFlags; - - fn db(&self) -> &Self::DbView { - &self.db - } - fn reducers(&self) -> &Self::Reducers { - &self.reducers - } - fn procedures(&self) -> &Self::Procedures { - &self.procedures - } - fn set_reducer_flags(&self) -> &Self::SetReducerFlags { - &self.set_reducer_flags - } - - fn is_active(&self) -> bool { - self.imp.is_active() - } - - fn disconnect(&self) -> __sdk::Result<()> { - self.imp.disconnect() - } - - type SubscriptionBuilder = __sdk::SubscriptionBuilder; - - fn subscription_builder(&self) -> Self::SubscriptionBuilder { - __sdk::SubscriptionBuilder::new(&self.imp) - } - - fn try_identity(&self) -> Option<__sdk::Identity> { - self.imp.try_identity() - } - fn connection_id(&self) -> __sdk::ConnectionId { - self.imp.connection_id() - } - fn try_connection_id(&self) -> Option<__sdk::ConnectionId> { - self.imp.try_connection_id() - } -} - -impl __sdk::ErrorContext for ErrorContext {} - -impl __sdk::SpacetimeModule for RemoteModule { - type DbConnection = DbConnection; - type EventContext = EventContext; - type ReducerEventContext = ReducerEventContext; - type ProcedureEventContext = ProcedureEventContext; - type SubscriptionEventContext = SubscriptionEventContext; - type ErrorContext = ErrorContext; - type Reducer = Reducer; - type DbView = RemoteTables; - type Reducers = RemoteReducers; - type SetReducerFlags = SetReducerFlags; - type DbUpdate = DbUpdate; - type AppliedDiff<'r> = AppliedDiff<'r>; - type SubscriptionHandle = SubscriptionHandle; - - fn register_tables(client_cache: &mut __sdk::ClientCache) { - person_table::register_table(client_cache); - } -} diff --git a/src/module_bindings/person_table.rs b/src/module_bindings/person_table.rs deleted file mode 100644 index da3f64b..0000000 --- a/src/module_bindings/person_table.rs +++ /dev/null @@ -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::person_type::Person; -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -/// Table handle for the table `person`. -/// -/// Obtain a handle from the [`PersonTableAccess::person`] method on [`super::RemoteTables`], -/// like `ctx.db.person()`. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.person().on_insert(...)`. -pub struct PersonTableHandle<'ctx> { - imp: __sdk::TableHandle, - ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -#[allow(non_camel_case_types)] -/// Extension trait for access to the table `person`. -/// -/// Implemented for [`super::RemoteTables`]. -pub trait PersonTableAccess { - #[allow(non_snake_case)] - /// Obtain a [`PersonTableHandle`], which mediates access to the table `person`. - fn person(&self) -> PersonTableHandle<'_>; -} - -impl PersonTableAccess for super::RemoteTables { - fn person(&self) -> PersonTableHandle<'_> { - PersonTableHandle { - imp: self.imp.get_table::("person"), - ctx: std::marker::PhantomData, - } - } -} - -pub struct PersonInsertCallbackId(__sdk::CallbackId); -pub struct PersonDeleteCallbackId(__sdk::CallbackId); - -impl<'ctx> __sdk::Table for PersonTableHandle<'ctx> { - type Row = Person; - type EventContext = super::EventContext; - - fn count(&self) -> u64 { - self.imp.count() - } - fn iter(&self) -> impl Iterator + '_ { - self.imp.iter() - } - - type InsertCallbackId = PersonInsertCallbackId; - - fn on_insert( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> PersonInsertCallbackId { - PersonInsertCallbackId(self.imp.on_insert(Box::new(callback))) - } - - fn remove_on_insert(&self, callback: PersonInsertCallbackId) { - self.imp.remove_on_insert(callback.0) - } - - type DeleteCallbackId = PersonDeleteCallbackId; - - fn on_delete( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> PersonDeleteCallbackId { - PersonDeleteCallbackId(self.imp.on_delete(Box::new(callback))) - } - - fn remove_on_delete(&self, callback: PersonDeleteCallbackId) { - self.imp.remove_on_delete(callback.0) - } -} - -#[doc(hidden)] -pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { - let _table = client_cache.get_or_make_table::("person"); -} - -#[doc(hidden)] -pub(super) fn parse_table_update( - raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, -) -> __sdk::Result<__sdk::TableUpdate> { - __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { - __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") - .with_cause(e) - .into() - }) -} From 78c199b61efd846ef81ba001fdcfb1942365f395 Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Sun, 8 Feb 2026 00:10:10 -0800 Subject: [PATCH 07/11] basic lobby joinage logic --- jong/src/game.rs | 168 ++++++++++++------- jong/src/lib.rs | 5 + jong/src/stdb/add_bot_reducer.rs | 104 ++++++++++++ jong/src/stdb/bot_table.rs | 142 ++++++++++++++++ jong/src/stdb/bot_type.rs | 16 ++ jong/src/stdb/lobby_table.rs | 31 ++++ jong/src/stdb/lobby_type.rs | 2 +- jong/src/stdb/login_or_add_player_reducer.rs | 103 ++++++++++++ jong/src/stdb/mod.rs | 62 +++---- jong/src/stdb/player_table.rs | 31 ++++ jong/src/stdb/player_type.rs | 1 + jong/src/stdb/wall_table.rs | 31 ++++ jong/src/stdb/wall_type.rs | 1 + jong/src/tile.rs | 48 ------ spacetimedb/Cargo.toml | 2 +- spacetimedb/src/lib.rs | 128 ++++++++++---- 16 files changed, 708 insertions(+), 167 deletions(-) create mode 100644 jong/src/stdb/add_bot_reducer.rs create mode 100644 jong/src/stdb/bot_table.rs create mode 100644 jong/src/stdb/bot_type.rs create mode 100644 jong/src/stdb/login_or_add_player_reducer.rs diff --git a/jong/src/game.rs b/jong/src/game.rs index 759b0ee..02cbbef 100644 --- a/jong/src/game.rs +++ b/jong/src/game.rs @@ -1,6 +1,20 @@ -use bevy::prelude::*; -use bevy_spacetimedb::StdbPlugin; +#![allow(unused)] +use bevy::prelude::*; +use bevy_spacetimedb::{ + ReadInsertUpdateMessage, ReadStdbConnectedMessage, ReadStdbDisconnectedMessage, StdbPlugin, + TableMessages, +}; +use spacetimedb::Identity; +use spacetimedb_sdk::credentials; + +use crate::{ + SpacetimeDB, creds_store, + stdb::{ + self, DbConnection, LobbyTableAccess, PlayerTableAccess, RemoteTables, add_bot, + join_or_create_lobby, login_or_add_player, + }, +}; use crate::{ game::{ hand::{Hand, Pond}, @@ -8,7 +22,6 @@ use crate::{ round::{TurnState, Wind}, wall::Wall, }, - stdb::DbConnection, tile::{self}, }; @@ -24,6 +37,7 @@ pub enum GameState { Setup, Deal, Play, + Exit, } #[derive(Message)] @@ -33,77 +47,115 @@ pub enum GameMessage { Called { player: Entity, calltype: Entity }, } -impl GameMessage { - pub(crate) fn is_called(&self) -> bool { - match self { - GameMessage::Called { .. } => true, - _ => false, - } - } -} - pub struct Riichi; impl Plugin for Riichi { fn build(&self, app: &mut App) { - // app.add_plugins( - // StdbPlugin::default() - // .with_uri("http://localhost:3000") - // .with_module_name("jongline") - // .with_run_fn(DbConnection::run_threaded), - // ); - app - // start stopper + let mut plugins = StdbPlugin::default() + .with_uri("http://localhost:3000") + .with_module_name("jongline") + .with_run_fn(DbConnection::run_threaded) + // TODO change to partial no update or a subscription? + .add_table(RemoteTables::player); + 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::() - .add_sub_state::() - .init_resource::() - .init_resource::() - .add_message::() + // .add_sub_state::() + // .init_resource::() + // .init_resource::() + // .add_message::() .add_systems(Startup, tile::init_tiles) - .add_systems(OnEnter(GameState::Setup), setup) - .add_systems(OnEnter(GameState::Deal), hand::shuffle_deal) - .add_systems(Update, hand::sort_hands.run_if(in_state(GameState::Play))) - .add_systems(OnEnter(TurnState::Tsumo), round::tsumo) - .add_systems(OnEnter(TurnState::Menzen), round::menzen) - .add_systems(Update, round::riichi_kan.run_if(in_state(TurnState::RiichiKan))) - .add_systems(Update, round::discard.run_if(in_state(TurnState::Discard))) - .add_systems(OnEnter(TurnState::RonChiiPonKan), round::notify_callable) - .add_systems(Update, round::ron_chi_pon_kan.run_if(in_state(TurnState::RonChiiPonKan)).after(round::notify_callable)) - .add_systems(OnEnter(TurnState::End), round::end) + // .add_systems(OnEnter(GameState::Setup), setup) + // .add_systems(OnEnter(GameState::Deal), hand::shuffle_deal) + // .add_systems(Update, hand::sort_hands.run_if(in_state(GameState::Play))) + // .add_systems(OnEnter(TurnState::Tsumo), round::tsumo) + // .add_systems(OnEnter(TurnState::Menzen), round::menzen) + // .add_systems(Update, round::riichi_kan.run_if(in_state(TurnState::RiichiKan))) + // .add_systems(Update, round::discard.run_if(in_state(TurnState::Discard))) + // .add_systems(OnEnter(TurnState::RonChiiPonKan), round::notify_callable) + // .add_systems(Update, round::ron_chi_pon_kan.run_if(in_state(TurnState::RonChiiPonKan)).after(round::notify_callable)) + // .add_systems(OnEnter(TurnState::End), round::end) + // stdb + .add_systems(Update, on_connect) + .add_systems(Update, on_disconnect) + .add_systems(Update, on_player_insert_update) + .add_systems(OnEnter(GameState::Setup), join_or_create_lobby) + .add_systems(OnEnter(GameState::Deal), ||todo!()) // semicolon stopper ; } } -pub(crate) fn setup( +#[derive(Resource, Deref)] +struct Player(stdb::Player); + +// TODO or reconnect? +fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage) { + 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"); + + // FIXME delet this in future + stdb.subscription_builder().subscribe_to_all_tables(); + } +} + +fn on_disconnect(stdb: SpacetimeDB, mut messages: ReadStdbDisconnectedMessage) { + for msg in messages.read() { + warn!("lost connection: {:#?}", msg.err); + } +} + +fn on_player_insert_update( + stdb: SpacetimeDB, + mut messages: ReadInsertUpdateMessage, mut commands: Commands, - matchsettings: Res, - // mut compass: ResMut - // tiles: Query>, - mut next_gamestate: ResMut>, + player: Option>, ) { - for i in 1..=matchsettings.player_count { - let player = player::Player { - name: format!("Player {}", i), - }; - let points = player::Points(matchsettings.starting_points); - - let bundle = ( - player, - points, - Hand, - Pond, - Wind::from_repr((i - 1) as usize).unwrap(), - ); - - if i == 1 { - let player = commands.spawn((bundle, MainPlayer, CurrentPlayer)).id(); - // commands.insert_resource(CurrentPlayer(player)); + for msg in messages.read() { + if player.is_some() { + if msg.new.lobby_id != 0 { + info!("joined lobby {}", msg.new.lobby_id); + for _ in 0..3 { + stdb.reducers().add_bot(msg.new.lobby_id).unwrap() + } + } + } else if let Some(player) = stdb.db().player().identity().find(&stdb.identity()) { + commands.insert_resource(Player(player)); + trace!("logged in"); } else { - commands.spawn(bundle); + debug!( + "received player insert update msg: {:?} -> {:?}", + msg.old, msg.new + ) } } +} - commands.spawn(Wall); +fn join_or_create_lobby( + stdb: SpacetimeDB, + player: Res, + mut next_gamestate: ResMut>, +) { + if player.lobby_id == 0 { + stdb.reducers().join_or_create_lobby(None).unwrap(); + stdb.subscription_builder() + .on_applied(|_| trace!("subbed to lobby table")) + .on_error(|_, err| error!("sub to lobby table failed: {}", err)) + .subscribe(["SELECT l.* FROM lobby l JOIN player p ON l.host_id = p.id"]); + } else { + debug!("already in lobby") + } + // TODO how can this trigger with a reducer or automatically after all players join/ready next_gamestate.set(GameState::Deal); } diff --git a/jong/src/lib.rs b/jong/src/lib.rs index 8e711a7..8981acd 100644 --- a/jong/src/lib.rs +++ b/jong/src/lib.rs @@ -2,6 +2,7 @@ use bevy::prelude::*; use bevy_spacetimedb::StdbConnection; +use spacetimedb_sdk::credentials; pub mod game; pub mod tile; @@ -14,3 +15,7 @@ trait EnumNextCycle { } pub type SpacetimeDB<'a> = Res<'a, StdbConnection>; + +fn creds_store() -> credentials::File { + credentials::File::new("jongline") +} diff --git a/jong/src/stdb/add_bot_reducer.rs b/jong/src/stdb/add_bot_reducer.rs new file mode 100644 index 0000000..eccf63a --- /dev/null +++ b/jong/src/stdb/add_bot_reducer.rs @@ -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 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); + } +} diff --git a/jong/src/stdb/bot_table.rs b/jong/src/stdb/bot_table.rs new file mode 100644 index 0000000..9e4c080 --- /dev/null +++ b/jong/src/stdb/bot_table.rs @@ -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, + 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"), + 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 + '_ { + 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) { + let _table = client_cache.get_or_make_table::("bot"); + _table.add_unique_constraint::("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> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "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, + 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::("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 { + self.imp.find(col_val) + } +} diff --git a/jong/src/stdb/bot_type.rs b/jong/src/stdb/bot_type.rs new file mode 100644 index 0000000..ba15e53 --- /dev/null +++ b/jong/src/stdb/bot_type.rs @@ -0,0 +1,16 @@ +// 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, +} + +impl __sdk::InModule for Bot { + type Module = super::RemoteModule; +} diff --git a/jong/src/stdb/lobby_table.rs b/jong/src/stdb/lobby_table.rs index 53f11a7..62a0aeb 100644 --- a/jong/src/stdb/lobby_table.rs +++ b/jong/src/stdb/lobby_table.rs @@ -82,6 +82,7 @@ impl<'ctx> __sdk::Table for LobbyTableHandle<'ctx> { pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { let _table = client_cache.get_or_make_table::("lobby"); _table.add_unique_constraint::("id", |row| &row.id); + _table.add_unique_constraint::("host_id", |row| &row.host_id); } pub struct LobbyUpdateCallbackId(__sdk::CallbackId); @@ -140,3 +141,33 @@ impl<'ctx> LobbyIdUnique<'ctx> { self.imp.find(col_val) } } + +/// Access to the `host_id` unique index on the table `lobby`, +/// which allows point queries on the field of the same name +/// via the [`LobbyHostIdUnique::find`] method. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.lobby().host_id().find(...)`. +pub struct LobbyHostIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +impl<'ctx> LobbyTableHandle<'ctx> { + /// Get a handle on the `host_id` unique index on the table `lobby`. + pub fn host_id(&self) -> LobbyHostIdUnique<'ctx> { + LobbyHostIdUnique { + imp: self.imp.get_unique_constraint::("host_id"), + phantom: std::marker::PhantomData, + } + } +} + +impl<'ctx> LobbyHostIdUnique<'ctx> { + /// Find the subscribed row whose `host_id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u32) -> Option { + self.imp.find(col_val) + } +} diff --git a/jong/src/stdb/lobby_type.rs b/jong/src/stdb/lobby_type.rs index fcb5045..6117233 100644 --- a/jong/src/stdb/lobby_type.rs +++ b/jong/src/stdb/lobby_type.rs @@ -8,7 +8,7 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; #[sats(crate = __lib)] pub struct Lobby { pub id: u32, - pub host: __sdk::Identity, + pub host_id: u32, } impl __sdk::InModule for Lobby { diff --git a/jong/src/stdb/login_or_add_player_reducer.rs b/jong/src/stdb/login_or_add_player_reducer.rs new file mode 100644 index 0000000..f94c20f --- /dev/null +++ b/jong/src/stdb/login_or_add_player_reducer.rs @@ -0,0 +1,103 @@ +// 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 LoginOrAddPlayerArgs {} + +impl From for super::Reducer { + fn from(args: LoginOrAddPlayerArgs) -> Self { + Self::LoginOrAddPlayer + } +} + +impl __sdk::InModule for LoginOrAddPlayerArgs { + type Module = super::RemoteModule; +} + +pub struct LoginOrAddPlayerCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `login_or_add_player`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait login_or_add_player { + /// 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. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_login_or_add_player`] callbacks. + fn login_or_add_player(&self) -> __sdk::Result<()>; + /// 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`] + /// to determine the reducer's status. + /// + /// The returned [`LoginOrAddPlayerCallbackId`] can be passed to [`Self::remove_on_login_or_add_player`] + /// to cancel the callback. + fn on_login_or_add_player( + &self, + callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> LoginOrAddPlayerCallbackId; + /// Cancel a callback previously registered by [`Self::on_login_or_add_player`], + /// causing it not to run in the future. + fn remove_on_login_or_add_player(&self, callback: LoginOrAddPlayerCallbackId); +} + +impl login_or_add_player for super::RemoteReducers { + fn login_or_add_player(&self) -> __sdk::Result<()> { + self.imp + .call_reducer("login_or_add_player", LoginOrAddPlayerArgs {}) + } + fn on_login_or_add_player( + &self, + mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> LoginOrAddPlayerCallbackId { + LoginOrAddPlayerCallbackId(self.imp.on_reducer( + "login_or_add_player", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::LoginOrAddPlayer {}, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx) + }), + )) + } + fn remove_on_login_or_add_player(&self, callback: LoginOrAddPlayerCallbackId) { + self.imp + .remove_on_reducer("login_or_add_player", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `login_or_add_player`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_login_or_add_player { + /// 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. + fn login_or_add_player(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_login_or_add_player for super::SetReducerFlags { + fn login_or_add_player(&self, flags: __ws::CallReducerFlags) { + self.imp + .set_call_reducer_flags("login_or_add_player", flags); + } +} diff --git a/jong/src/stdb/mod.rs b/jong/src/stdb/mod.rs index e6d9a19..3061c2c 100644 --- a/jong/src/stdb/mod.rs +++ b/jong/src/stdb/mod.rs @@ -6,21 +6,22 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; -pub mod add_player_reducer; +pub mod add_bot_reducer; +pub mod bot_table; +pub mod bot_type; pub mod deal_hands_reducer; pub mod dragon_type; pub mod hand_table; pub mod hand_type; -pub mod insert_wall_reducer; pub mod join_or_create_lobby_reducer; pub mod lobby_table; pub mod lobby_type; +pub mod login_or_add_player_reducer; pub mod player_table; pub mod player_type; pub mod pond_table; pub mod pond_type; pub mod rank_type; -pub mod set_name_reducer; pub mod shuffle_wall_reducer; pub mod sort_hand_reducer; pub mod suit_type; @@ -29,23 +30,26 @@ pub mod wall_table; pub mod wall_type; pub mod wind_type; -pub use add_player_reducer::{add_player, set_flags_for_add_player, AddPlayerCallbackId}; +pub use add_bot_reducer::{add_bot, set_flags_for_add_bot, AddBotCallbackId}; +pub use bot_table::*; +pub use bot_type::Bot; pub use deal_hands_reducer::{deal_hands, set_flags_for_deal_hands, DealHandsCallbackId}; pub use dragon_type::Dragon; pub use hand_table::*; pub use hand_type::Hand; -pub use insert_wall_reducer::{insert_wall, set_flags_for_insert_wall, InsertWallCallbackId}; pub use join_or_create_lobby_reducer::{ join_or_create_lobby, set_flags_for_join_or_create_lobby, JoinOrCreateLobbyCallbackId, }; pub use lobby_table::*; 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_table::*; pub use player_type::Player; pub use pond_table::*; pub use pond_type::Pond; pub use rank_type::Rank; -pub use set_name_reducer::{set_flags_for_set_name, set_name, SetNameCallbackId}; pub use shuffle_wall_reducer::{set_flags_for_shuffle_wall, shuffle_wall, ShuffleWallCallbackId}; pub use sort_hand_reducer::{set_flags_for_sort_hand, sort_hand, SortHandCallbackId}; pub use suit_type::Suit; @@ -62,11 +66,10 @@ pub use wind_type::Wind; /// to indicate which reducer caused the event. pub enum Reducer { - AddPlayer { name: Option }, + AddBot { lobby_id: u32 }, DealHands, - InsertWall { player_ids: Vec }, JoinOrCreateLobby { lobby: Option }, - SetName { name: String }, + LoginOrAddPlayer, ShuffleWall, SortHand, } @@ -78,11 +81,10 @@ impl __sdk::InModule for Reducer { impl __sdk::Reducer for Reducer { fn reducer_name(&self) -> &'static str { match self { - Reducer::AddPlayer { .. } => "add_player", + Reducer::AddBot { .. } => "add_bot", Reducer::DealHands => "deal_hands", - Reducer::InsertWall { .. } => "insert_wall", Reducer::JoinOrCreateLobby { .. } => "join_or_create_lobby", - Reducer::SetName { .. } => "set_name", + Reducer::LoginOrAddPlayer => "login_or_add_player", Reducer::ShuffleWall => "shuffle_wall", Reducer::SortHand => "sort_hand", _ => unreachable!(), @@ -93,13 +95,11 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { type Error = __sdk::Error; fn try_from(value: __ws::ReducerCallInfo<__ws::BsatnFormat>) -> __sdk::Result { match &value.reducer_name[..] { - "add_player" => Ok( - __sdk::parse_reducer_args::( - "add_player", - &value.args, - )? - .into(), - ), + "add_bot" => Ok(__sdk::parse_reducer_args::( + "add_bot", + &value.args, + )? + .into()), "deal_hands" => Ok( __sdk::parse_reducer_args::( "deal_hands", @@ -107,21 +107,13 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { )? .into(), ), - "insert_wall" => Ok( - __sdk::parse_reducer_args::( - "insert_wall", - &value.args, - )? - .into(), - ), "join_or_create_lobby" => Ok(__sdk::parse_reducer_args::< join_or_create_lobby_reducer::JoinOrCreateLobbyArgs, >("join_or_create_lobby", &value.args)? .into()), - "set_name" => Ok(__sdk::parse_reducer_args::( - "set_name", - &value.args, - )? + "login_or_add_player" => Ok(__sdk::parse_reducer_args::< + login_or_add_player_reducer::LoginOrAddPlayerArgs, + >("login_or_add_player", &value.args)? .into()), "shuffle_wall" => Ok( __sdk::parse_reducer_args::( @@ -151,6 +143,7 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { #[allow(non_snake_case)] #[doc(hidden)] pub struct DbUpdate { + bot: __sdk::TableUpdate, hand: __sdk::TableUpdate, lobby: __sdk::TableUpdate, player: __sdk::TableUpdate, @@ -164,6 +157,9 @@ impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { let mut db_update = DbUpdate::default(); for table_update in raw.tables { match &table_update.table_name[..] { + "bot" => db_update + .bot + .append(bot_table::parse_table_update(table_update)?), "hand" => db_update .hand .append(hand_table::parse_table_update(table_update)?), @@ -205,6 +201,9 @@ impl __sdk::DbUpdate for DbUpdate { ) -> AppliedDiff<'_> { let mut diff = AppliedDiff::default(); + diff.bot = cache + .apply_diff_to_table::("bot", &self.bot) + .with_updates_by_pk(|row| &row.id); diff.hand = cache .apply_diff_to_table::("hand", &self.hand) .with_updates_by_pk(|row| &row.player_ident); @@ -227,6 +226,7 @@ impl __sdk::DbUpdate for DbUpdate { #[allow(non_snake_case)] #[doc(hidden)] pub struct AppliedDiff<'r> { + bot: __sdk::TableAppliedDiff<'r, Bot>, hand: __sdk::TableAppliedDiff<'r, Hand>, lobby: __sdk::TableAppliedDiff<'r, Lobby>, player: __sdk::TableAppliedDiff<'r, Player>, @@ -245,6 +245,7 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { event: &EventContext, callbacks: &mut __sdk::DbCallbacks, ) { + callbacks.invoke_table_row_callbacks::("bot", &self.bot, event); callbacks.invoke_table_row_callbacks::("hand", &self.hand, event); callbacks.invoke_table_row_callbacks::("lobby", &self.lobby, event); callbacks.invoke_table_row_callbacks::("player", &self.player, event); @@ -969,6 +970,7 @@ impl __sdk::SpacetimeModule for RemoteModule { type SubscriptionHandle = SubscriptionHandle; fn register_tables(client_cache: &mut __sdk::ClientCache) { + bot_table::register_table(client_cache); hand_table::register_table(client_cache); lobby_table::register_table(client_cache); player_table::register_table(client_cache); diff --git a/jong/src/stdb/player_table.rs b/jong/src/stdb/player_table.rs index f876249..93eb034 100644 --- a/jong/src/stdb/player_table.rs +++ b/jong/src/stdb/player_table.rs @@ -82,6 +82,7 @@ impl<'ctx> __sdk::Table for PlayerTableHandle<'ctx> { pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { let _table = client_cache.get_or_make_table::("player"); _table.add_unique_constraint::<__sdk::Identity>("identity", |row| &row.identity); + _table.add_unique_constraint::("id", |row| &row.id); } pub struct PlayerUpdateCallbackId(__sdk::CallbackId); @@ -142,3 +143,33 @@ impl<'ctx> PlayerIdentityUnique<'ctx> { 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, + 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::("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 { + self.imp.find(col_val) + } +} diff --git a/jong/src/stdb/player_type.rs b/jong/src/stdb/player_type.rs index 266df28..278ed9e 100644 --- a/jong/src/stdb/player_type.rs +++ b/jong/src/stdb/player_type.rs @@ -8,6 +8,7 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; #[sats(crate = __lib)] pub struct Player { pub identity: __sdk::Identity, + pub id: u32, pub name: Option, pub lobby_id: u32, } diff --git a/jong/src/stdb/wall_table.rs b/jong/src/stdb/wall_table.rs index 79cd408..4a06950 100644 --- a/jong/src/stdb/wall_table.rs +++ b/jong/src/stdb/wall_table.rs @@ -83,6 +83,7 @@ impl<'ctx> __sdk::Table for WallTableHandle<'ctx> { pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { let _table = client_cache.get_or_make_table::("wall"); _table.add_unique_constraint::("id", |row| &row.id); + _table.add_unique_constraint::("lobby_id", |row| &row.lobby_id); } pub struct WallUpdateCallbackId(__sdk::CallbackId); @@ -141,3 +142,33 @@ impl<'ctx> WallIdUnique<'ctx> { self.imp.find(col_val) } } + +/// 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, + 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::("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 { + self.imp.find(col_val) + } +} diff --git a/jong/src/stdb/wall_type.rs b/jong/src/stdb/wall_type.rs index 88a1e5f..732dbea 100644 --- a/jong/src/stdb/wall_type.rs +++ b/jong/src/stdb/wall_type.rs @@ -10,6 +10,7 @@ use super::tile_type::Tile; #[sats(crate = __lib)] pub struct Wall { pub id: u32, + pub lobby_id: u32, pub tiles: Vec, } diff --git a/jong/src/tile.rs b/jong/src/tile.rs index 34b73c5..3c4267c 100644 --- a/jong/src/tile.rs +++ b/jong/src/tile.rs @@ -1,55 +1,7 @@ use bevy::prelude::*; -// use spacetimedb::SpacetimeType; -// use strum::FromRepr; use jong_types::*; -// #[derive(Component, Debug, Clone, Copy, SpacetimeType)] -// pub struct Tile { -// pub suit: Suit, -// } - -// #[derive(/* MapEntities, */ Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] -// pub enum Suit { -// Man(Rank), -// Pin(Rank), -// Sou(Rank), -// Wind(Wind), -// Dragon(Dragon), -// } - -// impl Suit { -// pub fn rank(&self) -> Option { -// match self { -// Suit::Man(rank) => Some(*rank), -// Suit::Pin(rank) => Some(*rank), -// Suit::Sou(rank) => Some(*rank), -// // Suit::Wind(wind) | Suit::Dragon(dragon) => None, -// _ => None, -// } -// } -// } - -// #[derive(Deref, DerefMut, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] -// pub struct Rank { -// pub number: u8, -// } - -// #[derive(FromRepr, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] -// pub enum Wind { -// Ton, -// Nan, -// Shaa, -// Pei, -// } - -// #[derive(Debug, FromRepr, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] -// pub enum Dragon { -// Haku, -// Hatsu, -// Chun, -// } - #[derive(Component)] pub struct Dora; diff --git a/spacetimedb/Cargo.toml b/spacetimedb/Cargo.toml index 3a7227d..60070ef 100644 --- a/spacetimedb/Cargo.toml +++ b/spacetimedb/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "jongline" version = "0.1.0" -edition = "2021" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/spacetimedb/src/lib.rs b/spacetimedb/src/lib.rs index 8b21eb3..f8c1f9b 100644 --- a/spacetimedb/src/lib.rs +++ b/spacetimedb/src/lib.rs @@ -1,23 +1,45 @@ -use spacetimedb::{rand::seq::SliceRandom, reducer, table, Identity, ReducerContext, Table}; +use log::info; +use spacetimedb::{Identity, ReducerContext, Table, rand::seq::SliceRandom, reducer, table}; use jong_types::*; -#[table(name = player)] +#[derive(Debug)] +#[table(name = player, public)] pub struct Player { #[primary_key] identity: Identity, + #[auto_inc] + #[index(direct)] + #[unique] + id: u32, + name: Option, + + #[index(btree)] lobby_id: u32, } +#[table(name = bot)] +pub struct Bot { + #[primary_key] + #[auto_inc] + id: u32, + + #[index(btree)] + lobby_id: u32, +} + +#[derive(Debug)] #[table(name = lobby, public)] pub struct Lobby { #[primary_key] #[auto_inc] id: u32, - host: Identity, + #[index(direct)] + #[unique] + host_id: u32, } #[table(name = wall)] @@ -26,6 +48,10 @@ pub struct Wall { #[auto_inc] id: u32, + #[index(direct)] + #[unique] + lobby_id: u32, + tiles: Vec, } @@ -42,47 +68,75 @@ pub struct Pond { tiles: Vec, } -#[reducer] -pub fn add_player(ctx: &ReducerContext, name: Option) { - let identity = ctx.identity(); - ctx.db.player().insert(Player { - identity, - name, - lobby_id: 0, - }); -} +#[reducer(client_connected)] +pub fn login_or_add_player(ctx: &ReducerContext) { + let identity = ctx.sender; -#[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(()) + // TODO remove player on disconnect + if let Ok(player) = ctx.db.player().try_insert(Player { + identity, + id: 0, + name: None, + lobby_id: 0, + }) { + info!("added player: {:?}", player); } else { - Err("Cannot set name for unknown user".into()) + let player = ctx.db.player().identity().find(identity).unwrap(); + info!("player {:?} has reconnected", player) } } #[reducer] pub fn join_or_create_lobby(ctx: &ReducerContext, lobby: Option) -> Result<(), String> { - let player = ctx.db.player().identity().find(ctx.sender).unwrap(); + let mut player = ctx + .db + .player() + .identity() + .find(ctx.sender) + .ok_or(format!("cannot find player {}", ctx.sender))?; - todo!() + let lobby_id = lobby.unwrap_or_else(|| { + let lobby = ctx.db.lobby().insert(Lobby { + id: 0, + host_id: player.id, + }); + info!("created lobby: {:?}", lobby); + + 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 insert_wall(ctx: &ReducerContext, player_ids: Vec) { - let tiles: Vec = tiles(); - ctx.db.wall().insert(Wall { id: 0, tiles }); +pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> { + if lobby_id == 0 { + Err("cannot add a bot without a lobby".into()) + } else if let Some(lobby) = ctx.db.lobby().id().find(lobby_id) + && (ctx.db.player().lobby_id().filter(lobby_id).count() + + ctx.db.bot().lobby_id().filter(lobby_id).count() + <= 4) + { + let bot = ctx.db.bot().insert(Bot { id: 0, lobby_id }); + info!("added bot {} to lobby {}", bot.id, lobby_id); + Ok(()) + } else { + Err("lobby doesn't exist".into()) + } } #[reducer] pub fn shuffle_wall(ctx: &ReducerContext) { + // if let Some(wall) = + + // let mut rng = ctx.rng(); + // let mut wall = tiles(); + // wall.shuffle(&mut rng); todo!() } @@ -123,3 +177,19 @@ pub fn sort_hand(ctx: &ReducerContext) { // } // 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()) +// } +// } From 6cd10329df2aa3630f0f20042a282828052d8fa0 Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Sun, 8 Feb 2026 18:15:09 -0800 Subject: [PATCH 08/11] extract GameState --- Cargo.lock | 16 +++++++++++ jong-types/Cargo.toml | 2 ++ jong-types/rustfmt.toml | 2 ++ jong-types/src/lib.rs | 47 ++++++++++++++++++++++++++++---- jong/src/game.rs | 28 ++++++++----------- jong/src/stdb/game_state_type.rs | 24 ++++++++++++++++ jong/src/stdb/lobby_table.rs | 1 + jong/src/stdb/lobby_type.rs | 3 ++ jong/src/stdb/mod.rs | 2 ++ jong/src/tui.rs | 11 ++++---- jong/src/tui/input/keyboard.rs | 3 +- justfile | 3 ++ rustfmt.toml | 1 + spacetimedb/src/lib.rs | 3 ++ 14 files changed, 118 insertions(+), 28 deletions(-) create mode 100644 jong-types/rustfmt.toml create mode 100644 jong/src/stdb/game_state_type.rs create mode 100644 rustfmt.toml diff --git a/Cargo.lock b/Cargo.lock index fef7adf..fa24bf0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2531,6 +2531,21 @@ dependencies = [ "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]] name = "derive_more" version = "0.99.20" @@ -3752,6 +3767,7 @@ name = "jong-types" version = "0.1.0" dependencies = [ "bevy", + "derive_aliases", "spacetimedb", "strum 0.27.2", ] diff --git a/jong-types/Cargo.toml b/jong-types/Cargo.toml index a32f1b8..e4d5d42 100644 --- a/jong-types/Cargo.toml +++ b/jong-types/Cargo.toml @@ -7,5 +7,7 @@ edition = "2024" [dependencies] bevy.workspace = true +bevy.features = ["bevy_state"] +derive_aliases = "0.4.7" spacetimedb.workspace = true strum.workspace = true diff --git a/jong-types/rustfmt.toml b/jong-types/rustfmt.toml new file mode 100644 index 0000000..0973eba --- /dev/null +++ b/jong-types/rustfmt.toml @@ -0,0 +1,2 @@ +unstable_features = true +merge_derives = false diff --git a/jong-types/src/lib.rs b/jong-types/src/lib.rs index 91d3444..bc2c1b4 100644 --- a/jong-types/src/lib.rs +++ b/jong-types/src/lib.rs @@ -1,13 +1,37 @@ +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(Component, Debug, Clone, Copy, SpacetimeType)] +#[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(/* MapEntities, */ Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +#[derive(..Base)] +#[derive(SpacetimeType)] pub enum Suit { Man(Rank), Pin(Rank), @@ -28,12 +52,21 @@ impl Suit { } } -#[derive(Deref, DerefMut, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +#[derive( + ..Base, + Deref, + DerefMut, +)] +#[derive(SpacetimeType)] pub struct Rank { pub number: u8, } -#[derive(FromRepr, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +#[derive( + ..Base, + FromRepr, +)] +#[derive(SpacetimeType)] pub enum Wind { Ton, Nan, @@ -41,7 +74,11 @@ pub enum Wind { Pei, } -#[derive(Debug, FromRepr, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, SpacetimeType)] +#[derive( + ..Base, + FromRepr, +)] +#[derive(SpacetimeType)] pub enum Dragon { Haku, Hatsu, diff --git a/jong/src/game.rs b/jong/src/game.rs index 02cbbef..05679a2 100644 --- a/jong/src/game.rs +++ b/jong/src/game.rs @@ -24,22 +24,13 @@ use crate::{ }, tile::{self}, }; +use jong_types::GameState; pub mod hand; pub mod player; pub mod round; pub mod wall; -#[derive(States, Default, Hash, Clone, Eq, Debug, PartialEq, Copy)] -pub enum GameState { - #[default] - None, - Setup, - Deal, - Play, - Exit, -} - #[derive(Message)] pub enum GameMessage { Discarded(Entity), @@ -85,6 +76,7 @@ impl Plugin for Riichi { .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(OnEnter(GameState::Deal), ||todo!()) // semicolon stopper @@ -148,14 +140,18 @@ fn join_or_create_lobby( ) { if player.lobby_id == 0 { stdb.reducers().join_or_create_lobby(None).unwrap(); - stdb.subscription_builder() - .on_applied(|_| trace!("subbed to lobby table")) + let sub = stdb + .subscription_builder() + .on_applied(|ctx| trace!("subbed to lobby table")) .on_error(|_, err| error!("sub to lobby table failed: {}", err)) - .subscribe(["SELECT l.* FROM lobby l JOIN player p ON l.host_id = p.id"]); + // JOIN player p ON l.host_id = p.id + .subscribe([format!( + "SELECT l.* + FROM lobby l + WHERE l.host_id = {}", + player.id + )]); } else { debug!("already in lobby") } - - // TODO how can this trigger with a reducer or automatically after all players join/ready - next_gamestate.set(GameState::Deal); } diff --git a/jong/src/stdb/game_state_type.rs b/jong/src/stdb/game_state_type.rs new file mode 100644 index 0000000..2e26076 --- /dev/null +++ b/jong/src/stdb/game_state_type.rs @@ -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; +} diff --git a/jong/src/stdb/lobby_table.rs b/jong/src/stdb/lobby_table.rs index 62a0aeb..45ee487 100644 --- a/jong/src/stdb/lobby_table.rs +++ b/jong/src/stdb/lobby_table.rs @@ -2,6 +2,7 @@ // 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 spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; diff --git a/jong/src/stdb/lobby_type.rs b/jong/src/stdb/lobby_type.rs index 6117233..3b32b90 100644 --- a/jong/src/stdb/lobby_type.rs +++ b/jong/src/stdb/lobby_type.rs @@ -4,11 +4,14 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::game_state_type::GameState; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct Lobby { pub id: u32, pub host_id: u32, + pub game_state: GameState, } impl __sdk::InModule for Lobby { diff --git a/jong/src/stdb/mod.rs b/jong/src/stdb/mod.rs index 3061c2c..68ddd4a 100644 --- a/jong/src/stdb/mod.rs +++ b/jong/src/stdb/mod.rs @@ -11,6 +11,7 @@ pub mod bot_table; pub mod bot_type; pub mod deal_hands_reducer; pub mod dragon_type; +pub mod game_state_type; pub mod hand_table; pub mod hand_type; pub mod join_or_create_lobby_reducer; @@ -35,6 +36,7 @@ pub use bot_table::*; pub use bot_type::Bot; pub use deal_hands_reducer::{deal_hands, set_flags_for_deal_hands, DealHandsCallbackId}; pub use dragon_type::Dragon; +pub use game_state_type::GameState; pub use hand_table::*; pub use hand_type::Hand; pub use join_or_create_lobby_reducer::{ diff --git a/jong/src/tui.rs b/jong/src/tui.rs index f166fb2..b0d60d4 100644 --- a/jong/src/tui.rs +++ b/jong/src/tui.rs @@ -2,14 +2,15 @@ use std::time::Duration; use bevy::{app::ScheduleRunnerPlugin, prelude::*, state::app::StatesPlugin}; use bevy_ratatui::RatatuiPlugins; -use jong::game::{ - GameMessage, GameState, - hand::{Drawn, Hand}, - player::{CurrentPlayer, Player}, -}; use tui_logger::TuiWidgetState; use crate::tui::{input::ConfirmSelect, states::ConsoleWidget}; +use jong::game::{ + GameMessage, + hand::{Drawn, Hand}, + player::{CurrentPlayer, Player}, +}; +use jong_types::GameState; mod input; mod layout; diff --git a/jong/src/tui/input/keyboard.rs b/jong/src/tui/input/keyboard.rs index b879f77..d2415bc 100644 --- a/jong/src/tui/input/keyboard.rs +++ b/jong/src/tui/input/keyboard.rs @@ -4,11 +4,10 @@ use bevy_ratatui::event::KeyMessage; // use ratatui::crossterm::event::KeyCode; use tui_logger::TuiWidgetEvent; -use jong::game::GameState; - use crate::tui::layout::Overlays; use crate::tui::states::ConsoleWidget; use crate::tui::states::TuiState; +use jong_types::GameState; pub(crate) fn keyboard( mut messages: MessageReader, diff --git a/justfile b/justfile index 3950586..c55cca1 100644 --- a/justfile +++ b/justfile @@ -15,3 +15,6 @@ update: spacetime: devenv up + +generate-bindings: + spacetime generate --lang rust --out-dir jong/src/stdb --project-path spacetimedb diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..e1f312a --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +unstable_features = true diff --git a/spacetimedb/src/lib.rs b/spacetimedb/src/lib.rs index f8c1f9b..4c96c59 100644 --- a/spacetimedb/src/lib.rs +++ b/spacetimedb/src/lib.rs @@ -40,6 +40,8 @@ pub struct Lobby { #[index(direct)] #[unique] host_id: u32, + + game_state: GameState, } #[table(name = wall)] @@ -99,6 +101,7 @@ pub fn join_or_create_lobby(ctx: &ReducerContext, lobby: Option) -> Result< let lobby = ctx.db.lobby().insert(Lobby { id: 0, host_id: player.id, + game_state: GameState::None, }); info!("created lobby: {:?}", lobby); From d0c79377aa6b445d41cf430a6b7f34ce7faf9560 Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Sun, 8 Feb 2026 20:21:23 -0800 Subject: [PATCH 09/11] squash --- jong/src/game.rs | 152 +++++++++++++----- jong/src/stdb/bot_hand_type.rs | 18 +++ jong/src/stdb/bothand_table.rs | 143 ++++++++++++++++ jong/src/stdb/hand_table.rs | 22 +-- jong/src/stdb/hand_type.rs | 2 +- jong/src/stdb/join_or_create_lobby_reducer.rs | 20 +-- jong/src/stdb/lobby_setup_reducer.rs | 100 ++++++++++++ jong/src/stdb/lobby_table.rs | 22 +-- jong/src/stdb/lobby_type.rs | 2 +- jong/src/stdb/mod.rs | 60 ++++--- jong/src/stdb/setup_game_reducer.rs | 105 ++++++++++++ jong/src/stdb/view_hand_table.rs | 96 +++++++++++ jong/src/stdb/view_player_hand_table.rs | 96 +++++++++++ jong/src/stdb/wall_table.rs | 31 ---- jong/src/stdb/wall_type.rs | 1 - spacetimedb/src/lib.rs | 103 +++++++++--- 16 files changed, 824 insertions(+), 149 deletions(-) create mode 100644 jong/src/stdb/bot_hand_type.rs create mode 100644 jong/src/stdb/bothand_table.rs create mode 100644 jong/src/stdb/lobby_setup_reducer.rs create mode 100644 jong/src/stdb/setup_game_reducer.rs create mode 100644 jong/src/stdb/view_hand_table.rs create mode 100644 jong/src/stdb/view_player_hand_table.rs diff --git a/jong/src/game.rs b/jong/src/game.rs index 05679a2..6b6b470 100644 --- a/jong/src/game.rs +++ b/jong/src/game.rs @@ -6,13 +6,13 @@ use bevy_spacetimedb::{ TableMessages, }; use spacetimedb::Identity; -use spacetimedb_sdk::credentials; +use spacetimedb_sdk::{DbContext, credentials}; use crate::{ SpacetimeDB, creds_store, stdb::{ - self, DbConnection, LobbyTableAccess, PlayerTableAccess, RemoteTables, add_bot, - join_or_create_lobby, login_or_add_player, + self, DbConnection, HandTableAccess, LobbyTableAccess, PlayerTableAccess, RemoteTables, + add_bot, join_or_create_lobby, login_or_add_player, setup_game, }, }; use crate::{ @@ -45,8 +45,14 @@ impl Plugin for Riichi { .with_uri("http://localhost:3000") .with_module_name("jongline") .with_run_fn(DbConnection::run_threaded) - // TODO change to partial no update or a subscription? - .add_table(RemoteTables::player); + + // 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? @@ -73,22 +79,31 @@ impl Plugin for Riichi { // .add_systems(Update, round::ron_chi_pon_kan.run_if(in_state(TurnState::RonChiiPonKan)).after(round::notify_callable)) // .add_systems(OnEnter(TurnState::End), round::end) // stdb + .init_resource::() .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(Update, on_lobby_insert_update) .add_systems(OnEnter(GameState::Setup), join_or_create_lobby) - .add_systems(OnEnter(GameState::Deal), ||todo!()) + .add_systems(Update, (view_hand).run_if(in_state(GameState::Play))) // semicolon stopper ; } } +fn view_hand(stdb: SpacetimeDB) { + // stdb.db() + // .hand() + // .player_identity() + // .find(&stdb.identity()) + // .unwrap(); +} + #[derive(Resource, Deref)] struct Player(stdb::Player); // TODO or reconnect? -fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage) { +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()); @@ -96,8 +111,15 @@ fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage) { .save(&msg.access_token) .expect("i/o error saving token"); - // FIXME delet this in future - stdb.subscription_builder().subscribe_to_all_tables(); + stdb.subscription_builder() + .on_applied(|ctx| { + trace!("subbed to player table"); + }) + .on_error(|_, err| error!("sub to player failed: {err}")) + .subscribe(format!( + "SELECT * FROM player p WHERE p.identity = '{}'", + stdb.identity() + )); } } @@ -110,48 +132,100 @@ fn on_disconnect(stdb: SpacetimeDB, mut messages: ReadStdbDisconnectedMessage) { fn on_player_insert_update( stdb: SpacetimeDB, mut messages: ReadInsertUpdateMessage, + mut commands: Commands, - player: Option>, ) { for msg in messages.read() { - if player.is_some() { + debug!( + "player_insert_update msg:\n{:#?} -> \n{:#?}", + msg.old, msg.new + ); + + if msg.new.identity == stdb.identity() { + commands.insert_resource(Player(msg.new.clone())); + // TODO add bots elsewhere if msg.new.lobby_id != 0 { info!("joined lobby {}", msg.new.lobby_id); for _ in 0..3 { stdb.reducers().add_bot(msg.new.lobby_id).unwrap() } } - } else if let Some(player) = stdb.db().player().identity().find(&stdb.identity()) { - commands.insert_resource(Player(player)); - trace!("logged in"); - } else { - debug!( - "received player insert update msg: {:?} -> {:?}", - msg.old, msg.new - ) } } } -fn join_or_create_lobby( - stdb: SpacetimeDB, - player: Res, - mut next_gamestate: ResMut>, -) { - if player.lobby_id == 0 { - stdb.reducers().join_or_create_lobby(None).unwrap(); - let sub = stdb - .subscription_builder() - .on_applied(|ctx| trace!("subbed to lobby table")) - .on_error(|_, err| error!("sub to lobby table failed: {}", err)) - // JOIN player p ON l.host_id = p.id - .subscribe([format!( - "SELECT l.* +fn join_or_create_lobby(stdb: SpacetimeDB, player: Res, mut lobby_id: ResMut) { + let sub = stdb + .subscription_builder() + .on_applied(|_| { + trace!("subbed to lobby table"); + }) + .on_error(|_, err| error!("sub to lobby table failed: {err}")) + .subscribe([format!( + "SELECT l.* FROM lobby l - WHERE l.host_id = {}", - player.id - )]); - } else { - debug!("already in lobby") + WHERE l.host_player_id = {}", + player.id + )]); + + let mut player = player.clone(); + + if player.lobby_id == 0 { + stdb.reducers().join_or_create_lobby(0).unwrap(); + player.lobby_id = stdb + .db() + .lobby() + .host_player_id() + .find(&player.id) + .unwrap_or_else(|| panic!("can't find player with id {}", player.id)) + .id; + } + + if let Some(lobby) = stdb.db().lobby().id().find(&player.lobby_id) + && lobby.host_player_id == player.id + && matches!(lobby.game_state.into(), GameState::None) + { + debug!("setup_game({})", lobby.id); + stdb.reducers().setup_game(lobby.id).unwrap() + } + + *lobby_id = LobbyId(player.lobby_id); + stdb.reducers().setup_game(**lobby_id).unwrap(); + + stdb.subscription_builder() + .on_applied(|_| trace!("subbed to view_hand")) + .subscribe("SELECT * FROM view_hand"); +} + +impl From for GameState { + fn from(value: stdb::GameState) -> Self { + match value { + stdb::GameState::None => Self::None, + stdb::GameState::Setup => Self::Setup, + stdb::GameState::Deal => Self::Deal, + stdb::GameState::Play => Self::Play, + stdb::GameState::Exit => Self::Exit, + } + } +} + +#[derive(Resource, Default, Deref)] +struct LobbyId(u32); + +fn on_lobby_insert_update( + stdb: SpacetimeDB, + mut messages: ReadInsertUpdateMessage, + + mut commands: Commands, + mut next_gamestate: ResMut>, + + lobby_id: Res, +) { + for msg in messages.read() { + // TODO should this be an assert? + if msg.new.id == **lobby_id { + debug!("lobby: {:?}", msg.new); + next_gamestate.set(msg.new.game_state.into()); + } } } diff --git a/jong/src/stdb/bot_hand_type.rs b/jong/src/stdb/bot_hand_type.rs new file mode 100644 index 0000000..d2aeefb --- /dev/null +++ b/jong/src/stdb/bot_hand_type.rs @@ -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}; + +use super::tile_type::Tile; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct BotHand { + pub bot_id: u32, + pub tiles: Vec, +} + +impl __sdk::InModule for BotHand { + type Module = super::RemoteModule; +} diff --git a/jong/src/stdb/bothand_table.rs b/jong/src/stdb/bothand_table.rs new file mode 100644 index 0000000..b2307c4 --- /dev/null +++ b/jong/src/stdb/bothand_table.rs @@ -0,0 +1,143 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use super::bot_hand_type::BotHand; +use super::tile_type::Tile; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `bothand`. +/// +/// Obtain a handle from the [`BothandTableAccess::bothand`] method on [`super::RemoteTables`], +/// like `ctx.db.bothand()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.bothand().on_insert(...)`. +pub struct BothandTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `bothand`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait BothandTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`BothandTableHandle`], which mediates access to the table `bothand`. + fn bothand(&self) -> BothandTableHandle<'_>; +} + +impl BothandTableAccess for super::RemoteTables { + fn bothand(&self) -> BothandTableHandle<'_> { + BothandTableHandle { + imp: self.imp.get_table::("bothand"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct BothandInsertCallbackId(__sdk::CallbackId); +pub struct BothandDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for BothandTableHandle<'ctx> { + type Row = BotHand; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = BothandInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> BothandInsertCallbackId { + BothandInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: BothandInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = BothandDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> BothandDeleteCallbackId { + BothandDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: BothandDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("bothand"); + _table.add_unique_constraint::("bot_id", |row| &row.bot_id); +} +pub struct BothandUpdateCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableWithPrimaryKey for BothandTableHandle<'ctx> { + type UpdateCallbackId = BothandUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> BothandUpdateCallbackId { + BothandUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: BothandUpdateCallbackId) { + self.imp.remove_on_update(callback.0) + } +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} + +/// Access to the `bot_id` unique index on the table `bothand`, +/// which allows point queries on the field of the same name +/// via the [`BothandBotIdUnique::find`] method. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.bothand().bot_id().find(...)`. +pub struct BothandBotIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +impl<'ctx> BothandTableHandle<'ctx> { + /// Get a handle on the `bot_id` unique index on the table `bothand`. + pub fn bot_id(&self) -> BothandBotIdUnique<'ctx> { + BothandBotIdUnique { + imp: self.imp.get_unique_constraint::("bot_id"), + phantom: std::marker::PhantomData, + } + } +} + +impl<'ctx> BothandBotIdUnique<'ctx> { + /// Find the subscribed row whose `bot_id` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u32) -> Option { + self.imp.find(col_val) + } +} diff --git a/jong/src/stdb/hand_table.rs b/jong/src/stdb/hand_table.rs index 905ed76..e72e3a0 100644 --- a/jong/src/stdb/hand_table.rs +++ b/jong/src/stdb/hand_table.rs @@ -82,7 +82,7 @@ impl<'ctx> __sdk::Table for HandTableHandle<'ctx> { #[doc(hidden)] pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { let _table = client_cache.get_or_make_table::("hand"); - _table.add_unique_constraint::<__sdk::Identity>("player_ident", |row| &row.player_ident); + _table.add_unique_constraint::<__sdk::Identity>("player_identity", |row| &row.player_identity); } pub struct HandUpdateCallbackId(__sdk::CallbackId); @@ -112,32 +112,32 @@ pub(super) fn parse_table_update( }) } -/// Access to the `player_ident` unique index on the table `hand`, +/// Access to the `player_identity` unique index on the table `hand`, /// which allows point queries on the field of the same name -/// via the [`HandPlayerIdentUnique::find`] method. +/// via the [`HandPlayerIdentityUnique::find`] method. /// /// Users are encouraged not to explicitly reference this type, /// but to directly chain method calls, -/// like `ctx.db.hand().player_ident().find(...)`. -pub struct HandPlayerIdentUnique<'ctx> { +/// like `ctx.db.hand().player_identity().find(...)`. +pub struct HandPlayerIdentityUnique<'ctx> { imp: __sdk::UniqueConstraintHandle, phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, } impl<'ctx> HandTableHandle<'ctx> { - /// Get a handle on the `player_ident` unique index on the table `hand`. - pub fn player_ident(&self) -> HandPlayerIdentUnique<'ctx> { - HandPlayerIdentUnique { + /// Get a handle on the `player_identity` unique index on the table `hand`. + pub fn player_identity(&self) -> HandPlayerIdentityUnique<'ctx> { + HandPlayerIdentityUnique { imp: self .imp - .get_unique_constraint::<__sdk::Identity>("player_ident"), + .get_unique_constraint::<__sdk::Identity>("player_identity"), phantom: std::marker::PhantomData, } } } -impl<'ctx> HandPlayerIdentUnique<'ctx> { - /// Find the subscribed row whose `player_ident` column value is equal to `col_val`, +impl<'ctx> HandPlayerIdentityUnique<'ctx> { + /// Find the subscribed row whose `player_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 { self.imp.find(col_val) diff --git a/jong/src/stdb/hand_type.rs b/jong/src/stdb/hand_type.rs index f12c3c9..427b7c6 100644 --- a/jong/src/stdb/hand_type.rs +++ b/jong/src/stdb/hand_type.rs @@ -9,7 +9,7 @@ use super::tile_type::Tile; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct Hand { - pub player_ident: __sdk::Identity, + pub player_identity: __sdk::Identity, pub tiles: Vec, } diff --git a/jong/src/stdb/join_or_create_lobby_reducer.rs b/jong/src/stdb/join_or_create_lobby_reducer.rs index 594b092..2545903 100644 --- a/jong/src/stdb/join_or_create_lobby_reducer.rs +++ b/jong/src/stdb/join_or_create_lobby_reducer.rs @@ -7,12 +7,14 @@ 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: Option, + pub lobby_id: u32, } impl From for super::Reducer { fn from(args: JoinOrCreateLobbyArgs) -> Self { - Self::JoinOrCreateLobby { lobby: args.lobby } + Self::JoinOrCreateLobby { + lobby_id: args.lobby_id, + } } } @@ -32,7 +34,7 @@ pub trait join_or_create_lobby { /// 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: Option) -> __sdk::Result<()>; + 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`] @@ -42,7 +44,7 @@ pub trait join_or_create_lobby { /// to cancel the callback. fn on_join_or_create_lobby( &self, - callback: impl FnMut(&super::ReducerEventContext, &Option) + Send + 'static, + 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. @@ -50,13 +52,13 @@ pub trait join_or_create_lobby { } impl join_or_create_lobby for super::RemoteReducers { - fn join_or_create_lobby(&self, lobby: Option) -> __sdk::Result<()> { + fn join_or_create_lobby(&self, lobby_id: u32) -> __sdk::Result<()> { self.imp - .call_reducer("join_or_create_lobby", JoinOrCreateLobbyArgs { lobby }) + .call_reducer("join_or_create_lobby", JoinOrCreateLobbyArgs { lobby_id }) } fn on_join_or_create_lobby( &self, - mut callback: impl FnMut(&super::ReducerEventContext, &Option) + Send + 'static, + mut callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static, ) -> JoinOrCreateLobbyCallbackId { JoinOrCreateLobbyCallbackId(self.imp.on_reducer( "join_or_create_lobby", @@ -65,7 +67,7 @@ impl join_or_create_lobby for super::RemoteReducers { let super::ReducerEventContext { event: __sdk::ReducerEvent { - reducer: super::Reducer::JoinOrCreateLobby { lobby }, + reducer: super::Reducer::JoinOrCreateLobby { lobby_id }, .. }, .. @@ -73,7 +75,7 @@ impl join_or_create_lobby for super::RemoteReducers { else { unreachable!() }; - callback(ctx, lobby) + callback(ctx, lobby_id) }), )) } diff --git a/jong/src/stdb/lobby_setup_reducer.rs b/jong/src/stdb/lobby_setup_reducer.rs new file mode 100644 index 0000000..c54de7d --- /dev/null +++ b/jong/src/stdb/lobby_setup_reducer.rs @@ -0,0 +1,100 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct LobbySetupArgs {} + +impl From for super::Reducer { + fn from(args: LobbySetupArgs) -> Self { + Self::LobbySetup + } +} + +impl __sdk::InModule for LobbySetupArgs { + type Module = super::RemoteModule; +} + +pub struct LobbySetupCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `lobby_setup`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait lobby_setup { + /// Request that the remote module invoke the reducer `lobby_setup` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed by listening for [`Self::on_lobby_setup`] callbacks. + fn lobby_setup(&self) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `lobby_setup`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`LobbySetupCallbackId`] can be passed to [`Self::remove_on_lobby_setup`] + /// to cancel the callback. + fn on_lobby_setup( + &self, + callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> LobbySetupCallbackId; + /// Cancel a callback previously registered by [`Self::on_lobby_setup`], + /// causing it not to run in the future. + fn remove_on_lobby_setup(&self, callback: LobbySetupCallbackId); +} + +impl lobby_setup for super::RemoteReducers { + fn lobby_setup(&self) -> __sdk::Result<()> { + self.imp.call_reducer("lobby_setup", LobbySetupArgs {}) + } + fn on_lobby_setup( + &self, + mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, + ) -> LobbySetupCallbackId { + LobbySetupCallbackId(self.imp.on_reducer( + "lobby_setup", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::LobbySetup {}, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx) + }), + )) + } + fn remove_on_lobby_setup(&self, callback: LobbySetupCallbackId) { + self.imp.remove_on_reducer("lobby_setup", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `lobby_setup`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_lobby_setup { + /// Set the call-reducer flags for the reducer `lobby_setup` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn lobby_setup(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_lobby_setup for super::SetReducerFlags { + fn lobby_setup(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("lobby_setup", flags); + } +} diff --git a/jong/src/stdb/lobby_table.rs b/jong/src/stdb/lobby_table.rs index 45ee487..4249c91 100644 --- a/jong/src/stdb/lobby_table.rs +++ b/jong/src/stdb/lobby_table.rs @@ -83,7 +83,7 @@ impl<'ctx> __sdk::Table for LobbyTableHandle<'ctx> { pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { let _table = client_cache.get_or_make_table::("lobby"); _table.add_unique_constraint::("id", |row| &row.id); - _table.add_unique_constraint::("host_id", |row| &row.host_id); + _table.add_unique_constraint::("host_player_id", |row| &row.host_player_id); } pub struct LobbyUpdateCallbackId(__sdk::CallbackId); @@ -143,30 +143,30 @@ impl<'ctx> LobbyIdUnique<'ctx> { } } -/// Access to the `host_id` unique index on the table `lobby`, +/// 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 [`LobbyHostIdUnique::find`] method. +/// 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_id().find(...)`. -pub struct LobbyHostIdUnique<'ctx> { +/// like `ctx.db.lobby().host_player_id().find(...)`. +pub struct LobbyHostPlayerIdUnique<'ctx> { imp: __sdk::UniqueConstraintHandle, phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, } impl<'ctx> LobbyTableHandle<'ctx> { - /// Get a handle on the `host_id` unique index on the table `lobby`. - pub fn host_id(&self) -> LobbyHostIdUnique<'ctx> { - LobbyHostIdUnique { - imp: self.imp.get_unique_constraint::("host_id"), + /// 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::("host_player_id"), phantom: std::marker::PhantomData, } } } -impl<'ctx> LobbyHostIdUnique<'ctx> { - /// Find the subscribed row whose `host_id` column value is equal to `col_val`, +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 { self.imp.find(col_val) diff --git a/jong/src/stdb/lobby_type.rs b/jong/src/stdb/lobby_type.rs index 3b32b90..8d7b094 100644 --- a/jong/src/stdb/lobby_type.rs +++ b/jong/src/stdb/lobby_type.rs @@ -10,7 +10,7 @@ use super::game_state_type::GameState; #[sats(crate = __lib)] pub struct Lobby { pub id: u32, - pub host_id: u32, + pub host_player_id: u32, pub game_state: GameState, } diff --git a/jong/src/stdb/mod.rs b/jong/src/stdb/mod.rs index 68ddd4a..888635d 100644 --- a/jong/src/stdb/mod.rs +++ b/jong/src/stdb/mod.rs @@ -7,9 +7,10 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; pub mod add_bot_reducer; +pub mod bot_hand_type; pub mod bot_table; pub mod bot_type; -pub mod deal_hands_reducer; +pub mod bothand_table; pub mod dragon_type; pub mod game_state_type; pub mod hand_table; @@ -23,18 +24,20 @@ pub mod player_type; pub mod pond_table; pub mod pond_type; pub mod rank_type; -pub mod shuffle_wall_reducer; +pub mod setup_game_reducer; pub mod sort_hand_reducer; pub mod suit_type; pub mod tile_type; +pub mod view_player_hand_table; pub mod wall_table; pub mod wall_type; pub mod wind_type; pub use add_bot_reducer::{add_bot, set_flags_for_add_bot, AddBotCallbackId}; +pub use bot_hand_type::BotHand; pub use bot_table::*; pub use bot_type::Bot; -pub use deal_hands_reducer::{deal_hands, set_flags_for_deal_hands, DealHandsCallbackId}; +pub use bothand_table::*; pub use dragon_type::Dragon; pub use game_state_type::GameState; pub use hand_table::*; @@ -52,10 +55,11 @@ pub use player_type::Player; pub use pond_table::*; pub use pond_type::Pond; pub use rank_type::Rank; -pub use shuffle_wall_reducer::{set_flags_for_shuffle_wall, shuffle_wall, ShuffleWallCallbackId}; +pub use setup_game_reducer::{set_flags_for_setup_game, setup_game, SetupGameCallbackId}; pub use sort_hand_reducer::{set_flags_for_sort_hand, sort_hand, SortHandCallbackId}; pub use suit_type::Suit; pub use tile_type::Tile; +pub use view_player_hand_table::*; pub use wall_table::*; pub use wall_type::Wall; pub use wind_type::Wind; @@ -69,10 +73,9 @@ pub use wind_type::Wind; pub enum Reducer { AddBot { lobby_id: u32 }, - DealHands, - JoinOrCreateLobby { lobby: Option }, + JoinOrCreateLobby { lobby_id: u32 }, LoginOrAddPlayer, - ShuffleWall, + SetupGame { lobby_id: u32 }, SortHand, } @@ -84,10 +87,9 @@ impl __sdk::Reducer for Reducer { fn reducer_name(&self) -> &'static str { match self { Reducer::AddBot { .. } => "add_bot", - Reducer::DealHands => "deal_hands", Reducer::JoinOrCreateLobby { .. } => "join_or_create_lobby", Reducer::LoginOrAddPlayer => "login_or_add_player", - Reducer::ShuffleWall => "shuffle_wall", + Reducer::SetupGame { .. } => "setup_game", Reducer::SortHand => "sort_hand", _ => unreachable!(), } @@ -102,13 +104,6 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { &value.args, )? .into()), - "deal_hands" => Ok( - __sdk::parse_reducer_args::( - "deal_hands", - &value.args, - )? - .into(), - ), "join_or_create_lobby" => Ok(__sdk::parse_reducer_args::< join_or_create_lobby_reducer::JoinOrCreateLobbyArgs, >("join_or_create_lobby", &value.args)? @@ -117,9 +112,9 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { login_or_add_player_reducer::LoginOrAddPlayerArgs, >("login_or_add_player", &value.args)? .into()), - "shuffle_wall" => Ok( - __sdk::parse_reducer_args::( - "shuffle_wall", + "setup_game" => Ok( + __sdk::parse_reducer_args::( + "setup_game", &value.args, )? .into(), @@ -146,10 +141,12 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { #[doc(hidden)] pub struct DbUpdate { bot: __sdk::TableUpdate, + bothand: __sdk::TableUpdate, hand: __sdk::TableUpdate, lobby: __sdk::TableUpdate, player: __sdk::TableUpdate, pond: __sdk::TableUpdate, + view_player_hand: __sdk::TableUpdate, wall: __sdk::TableUpdate, } @@ -162,6 +159,9 @@ impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { "bot" => db_update .bot .append(bot_table::parse_table_update(table_update)?), + "bothand" => db_update + .bothand + .append(bothand_table::parse_table_update(table_update)?), "hand" => db_update .hand .append(hand_table::parse_table_update(table_update)?), @@ -174,6 +174,9 @@ impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { "pond" => db_update .pond .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 .append(wall_table::parse_table_update(table_update)?), @@ -206,9 +209,12 @@ impl __sdk::DbUpdate for DbUpdate { diff.bot = cache .apply_diff_to_table::("bot", &self.bot) .with_updates_by_pk(|row| &row.id); + diff.bothand = cache + .apply_diff_to_table::("bothand", &self.bothand) + .with_updates_by_pk(|row| &row.bot_id); diff.hand = cache .apply_diff_to_table::("hand", &self.hand) - .with_updates_by_pk(|row| &row.player_ident); + .with_updates_by_pk(|row| &row.player_identity); diff.lobby = cache .apply_diff_to_table::("lobby", &self.lobby) .with_updates_by_pk(|row| &row.id); @@ -218,7 +224,9 @@ impl __sdk::DbUpdate for DbUpdate { diff.pond = cache.apply_diff_to_table::("pond", &self.pond); diff.wall = cache .apply_diff_to_table::("wall", &self.wall) - .with_updates_by_pk(|row| &row.id); + .with_updates_by_pk(|row| &row.lobby_id); + diff.view_player_hand = + cache.apply_diff_to_table::("view_player_hand", &self.view_player_hand); diff } @@ -229,10 +237,12 @@ impl __sdk::DbUpdate for DbUpdate { #[doc(hidden)] pub struct AppliedDiff<'r> { bot: __sdk::TableAppliedDiff<'r, Bot>, + bothand: __sdk::TableAppliedDiff<'r, BotHand>, hand: __sdk::TableAppliedDiff<'r, Hand>, lobby: __sdk::TableAppliedDiff<'r, Lobby>, player: __sdk::TableAppliedDiff<'r, Player>, pond: __sdk::TableAppliedDiff<'r, Pond>, + view_player_hand: __sdk::TableAppliedDiff<'r, Hand>, wall: __sdk::TableAppliedDiff<'r, Wall>, __unused: std::marker::PhantomData<&'r ()>, } @@ -248,10 +258,16 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { callbacks: &mut __sdk::DbCallbacks, ) { callbacks.invoke_table_row_callbacks::("bot", &self.bot, event); + callbacks.invoke_table_row_callbacks::("bothand", &self.bothand, event); callbacks.invoke_table_row_callbacks::("hand", &self.hand, event); callbacks.invoke_table_row_callbacks::("lobby", &self.lobby, event); callbacks.invoke_table_row_callbacks::("player", &self.player, event); callbacks.invoke_table_row_callbacks::("pond", &self.pond, event); + callbacks.invoke_table_row_callbacks::( + "view_player_hand", + &self.view_player_hand, + event, + ); callbacks.invoke_table_row_callbacks::("wall", &self.wall, event); } } @@ -973,10 +989,12 @@ impl __sdk::SpacetimeModule for RemoteModule { fn register_tables(client_cache: &mut __sdk::ClientCache) { bot_table::register_table(client_cache); + bothand_table::register_table(client_cache); hand_table::register_table(client_cache); lobby_table::register_table(client_cache); player_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); } } diff --git a/jong/src/stdb/setup_game_reducer.rs b/jong/src/stdb/setup_game_reducer.rs new file mode 100644 index 0000000..3380b89 --- /dev/null +++ b/jong/src/stdb/setup_game_reducer.rs @@ -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 SetupGameArgs { + pub lobby_id: u32, +} + +impl From for super::Reducer { + fn from(args: SetupGameArgs) -> Self { + Self::SetupGame { + lobby_id: args.lobby_id, + } + } +} + +impl __sdk::InModule for SetupGameArgs { + type Module = super::RemoteModule; +} + +pub struct SetupGameCallbackId(__sdk::CallbackId); + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `setup_game`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait setup_game { + /// Request that the remote module invoke the reducer `setup_game` 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_setup_game`] callbacks. + fn setup_game(&self, lobby_id: u32) -> __sdk::Result<()>; + /// Register a callback to run whenever we are notified of an invocation of the reducer `setup_game`. + /// + /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] + /// to determine the reducer's status. + /// + /// The returned [`SetupGameCallbackId`] can be passed to [`Self::remove_on_setup_game`] + /// to cancel the callback. + fn on_setup_game( + &self, + callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static, + ) -> SetupGameCallbackId; + /// Cancel a callback previously registered by [`Self::on_setup_game`], + /// causing it not to run in the future. + fn remove_on_setup_game(&self, callback: SetupGameCallbackId); +} + +impl setup_game for super::RemoteReducers { + fn setup_game(&self, lobby_id: u32) -> __sdk::Result<()> { + self.imp + .call_reducer("setup_game", SetupGameArgs { lobby_id }) + } + fn on_setup_game( + &self, + mut callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static, + ) -> SetupGameCallbackId { + SetupGameCallbackId(self.imp.on_reducer( + "setup_game", + Box::new(move |ctx: &super::ReducerEventContext| { + #[allow(irrefutable_let_patterns)] + let super::ReducerEventContext { + event: + __sdk::ReducerEvent { + reducer: super::Reducer::SetupGame { lobby_id }, + .. + }, + .. + } = ctx + else { + unreachable!() + }; + callback(ctx, lobby_id) + }), + )) + } + fn remove_on_setup_game(&self, callback: SetupGameCallbackId) { + self.imp.remove_on_reducer("setup_game", callback.0) + } +} + +#[allow(non_camel_case_types)] +#[doc(hidden)] +/// Extension trait for setting the call-flags for the reducer `setup_game`. +/// +/// Implemented for [`super::SetReducerFlags`]. +/// +/// This type is currently unstable and may be removed without a major version bump. +pub trait set_flags_for_setup_game { + /// Set the call-reducer flags for the reducer `setup_game` to `flags`. + /// + /// This type is currently unstable and may be removed without a major version bump. + fn setup_game(&self, flags: __ws::CallReducerFlags); +} + +impl set_flags_for_setup_game for super::SetReducerFlags { + fn setup_game(&self, flags: __ws::CallReducerFlags) { + self.imp.set_call_reducer_flags("setup_game", flags); + } +} diff --git a/jong/src/stdb/view_hand_table.rs b/jong/src/stdb/view_hand_table.rs new file mode 100644 index 0000000..a9927c9 --- /dev/null +++ b/jong/src/stdb/view_hand_table.rs @@ -0,0 +1,96 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use super::hand_type::Hand; +use super::tile_type::Tile; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `view_hand`. +/// +/// Obtain a handle from the [`ViewHandTableAccess::view_hand`] method on [`super::RemoteTables`], +/// like `ctx.db.view_hand()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.view_hand().on_insert(...)`. +pub struct ViewHandTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `view_hand`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait ViewHandTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`ViewHandTableHandle`], which mediates access to the table `view_hand`. + fn view_hand(&self) -> ViewHandTableHandle<'_>; +} + +impl ViewHandTableAccess for super::RemoteTables { + fn view_hand(&self) -> ViewHandTableHandle<'_> { + ViewHandTableHandle { + imp: self.imp.get_table::("view_hand"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct ViewHandInsertCallbackId(__sdk::CallbackId); +pub struct ViewHandDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::Table for ViewHandTableHandle<'ctx> { + type Row = Hand; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = ViewHandInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> ViewHandInsertCallbackId { + ViewHandInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: ViewHandInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = ViewHandDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> ViewHandDeleteCallbackId { + ViewHandDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: ViewHandDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = client_cache.get_or_make_table::("view_hand"); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} diff --git a/jong/src/stdb/view_player_hand_table.rs b/jong/src/stdb/view_player_hand_table.rs new file mode 100644 index 0000000..37429bd --- /dev/null +++ b/jong/src/stdb/view_player_hand_table.rs @@ -0,0 +1,96 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use super::hand_type::Hand; +use super::tile_type::Tile; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `view_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, + 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::("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 + '_ { + 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) { + let _table = client_cache.get_or_make_table::("view_player_hand"); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} diff --git a/jong/src/stdb/wall_table.rs b/jong/src/stdb/wall_table.rs index 4a06950..92a737e 100644 --- a/jong/src/stdb/wall_table.rs +++ b/jong/src/stdb/wall_table.rs @@ -82,7 +82,6 @@ impl<'ctx> __sdk::Table for WallTableHandle<'ctx> { #[doc(hidden)] pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { let _table = client_cache.get_or_make_table::("wall"); - _table.add_unique_constraint::("id", |row| &row.id); _table.add_unique_constraint::("lobby_id", |row| &row.lobby_id); } pub struct WallUpdateCallbackId(__sdk::CallbackId); @@ -113,36 +112,6 @@ pub(super) fn parse_table_update( }) } -/// Access to the `id` unique index on the table `wall`, -/// which allows point queries on the field of the same name -/// via the [`WallIdUnique::find`] method. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.wall().id().find(...)`. -pub struct WallIdUnique<'ctx> { - imp: __sdk::UniqueConstraintHandle, - phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -impl<'ctx> WallTableHandle<'ctx> { - /// Get a handle on the `id` unique index on the table `wall`. - pub fn id(&self) -> WallIdUnique<'ctx> { - WallIdUnique { - imp: self.imp.get_unique_constraint::("id"), - phantom: std::marker::PhantomData, - } - } -} - -impl<'ctx> WallIdUnique<'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 { - self.imp.find(col_val) - } -} - /// 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. diff --git a/jong/src/stdb/wall_type.rs b/jong/src/stdb/wall_type.rs index 732dbea..2398ef1 100644 --- a/jong/src/stdb/wall_type.rs +++ b/jong/src/stdb/wall_type.rs @@ -9,7 +9,6 @@ use super::tile_type::Tile; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct Wall { - pub id: u32, pub lobby_id: u32, pub tiles: Vec, } diff --git a/spacetimedb/src/lib.rs b/spacetimedb/src/lib.rs index 4c96c59..efd08f2 100644 --- a/spacetimedb/src/lib.rs +++ b/spacetimedb/src/lib.rs @@ -1,5 +1,7 @@ -use log::info; -use spacetimedb::{Identity, ReducerContext, Table, rand::seq::SliceRandom, reducer, table}; +use log::{debug, info}; +use spacetimedb::{ + Identity, ReducerContext, Table, ViewContext, rand::seq::SliceRandom, reducer, table, view, +}; use jong_types::*; @@ -30,7 +32,7 @@ pub struct Bot { lobby_id: u32, } -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] #[table(name = lobby, public)] pub struct Lobby { #[primary_key] @@ -39,19 +41,18 @@ pub struct Lobby { #[index(direct)] #[unique] - host_id: u32, + host_player_id: u32, game_state: GameState, } #[table(name = wall)] pub struct Wall { + // #[auto_inc] + // id: u32, #[primary_key] - #[auto_inc] - id: u32, - - #[index(direct)] - #[unique] + // #[index(direct)] + // #[unique] lobby_id: u32, tiles: Vec, @@ -60,7 +61,15 @@ pub struct Wall { #[table(name = hand)] pub struct Hand { #[primary_key] - player_ident: Identity, + player_identity: Identity, + + tiles: Vec, +} + +#[table(name = bothand)] +pub struct BotHand { + #[primary_key] + bot_id: u32, tiles: Vec, } @@ -89,7 +98,7 @@ pub fn login_or_add_player(ctx: &ReducerContext) { } #[reducer] -pub fn join_or_create_lobby(ctx: &ReducerContext, lobby: Option) -> Result<(), String> { +pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<(), String> { let mut player = ctx .db .player() @@ -97,16 +106,16 @@ pub fn join_or_create_lobby(ctx: &ReducerContext, lobby: Option) -> Result< .find(ctx.sender) .ok_or(format!("cannot find player {}", ctx.sender))?; - let lobby_id = lobby.unwrap_or_else(|| { + if lobby_id == 0 { let lobby = ctx.db.lobby().insert(Lobby { id: 0, - host_id: player.id, + host_player_id: player.id, game_state: GameState::None, }); info!("created lobby: {:?}", lobby); - lobby.id - }); + lobby_id = lobby.id; + } player.lobby_id = lobby_id; @@ -134,18 +143,64 @@ pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> { } #[reducer] -pub fn shuffle_wall(ctx: &ReducerContext) { - // if let Some(wall) = +pub fn setup_game(ctx: &ReducerContext, lobby_id: u32) { + debug!("lobby_id: {lobby_id}"); + let mut lobby = ctx.db.lobby().id().find(lobby_id).unwrap(); + lobby.game_state = GameState::Setup; - // let mut rng = ctx.rng(); - // let mut wall = tiles(); - // wall.shuffle(&mut rng); - todo!() + ctx.db.lobby().id().update(lobby); + + let tiles = new_shuffled_wall(ctx); + ctx.db.wall().insert(Wall { + // id: 0, + lobby_id, + tiles, + }); + + lobby.game_state = GameState::Deal; + ctx.db.lobby().id().update(lobby); + + deal_hands(ctx, lobby_id); + lobby.game_state = GameState::Play; + ctx.db.lobby().id().update(lobby); } -#[reducer] -pub fn deal_hands(ctx: &ReducerContext) { - todo!() +pub fn new_shuffled_wall(ctx: &ReducerContext) -> Vec { + let mut rng = ctx.rng(); + let mut wall = tiles(); + wall.shuffle(&mut rng); + + wall +} + +pub fn deal_hands(ctx: &ReducerContext, lobby_id: u32) { + let players = ctx.db.player().lobby_id().filter(lobby_id); + let bots = ctx.db.bot().lobby_id().filter(lobby_id); + + let mut wall = ctx.db.wall().lobby_id().find(lobby_id).unwrap(); + + // FIXME rectify deal orders + for player in players { + let tiles = wall.tiles.split_off(wall.tiles.len() - 13); + wall = ctx.db.wall().lobby_id().update(wall); + ctx.db.hand().insert(Hand { + player_identity: player.identity, + tiles, + }); + } + for bot in bots { + let tiles = wall.tiles.split_off(wall.tiles.len() - 13); + wall = ctx.db.wall().lobby_id().update(wall); + ctx.db.bothand().insert(BotHand { + bot_id: bot.id, + tiles, + }); + } +} + +#[view(name = view_player_hand, public)] +pub fn view_player_hand(ctx: &ViewContext) -> Option { + ctx.db.hand().player_identity().find(ctx.sender) } #[reducer] From 9f6a5b6423c767b3b90ce8d329e381476d284cad Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Sun, 8 Feb 2026 23:05:22 -0800 Subject: [PATCH 10/11] temporarily sub all, then react --- jong/src/game.rs | 110 ++++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 69 deletions(-) diff --git a/jong/src/game.rs b/jong/src/game.rs index 6b6b470..d00e50c 100644 --- a/jong/src/game.rs +++ b/jong/src/game.rs @@ -66,7 +66,7 @@ impl Plugin for Riichi { // .add_sub_state::() // .init_resource::() // .init_resource::() - // .add_message::() + .add_message::() .add_systems(Startup, tile::init_tiles) // .add_systems(OnEnter(GameState::Setup), setup) // .add_systems(OnEnter(GameState::Deal), hand::shuffle_deal) @@ -79,30 +79,24 @@ impl Plugin for Riichi { // .add_systems(Update, round::ron_chi_pon_kan.run_if(in_state(TurnState::RonChiiPonKan)).after(round::notify_callable)) // .add_systems(OnEnter(TurnState::End), round::end) // stdb - .init_resource::() + .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(Update, (on_player_insert_update, on_lobby_insert_update).chain()) .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 ; } } -fn view_hand(stdb: SpacetimeDB) { - // stdb.db() - // .hand() - // .player_identity() - // .find(&stdb.identity()) - // .unwrap(); +fn sub_to_all(stdb: SpacetimeDB) { + stdb.subscription_builder() + .on_applied(|_| trace!("made all subs!")) + .on_error(|_, err| error!("sub failed: {err}")) + .subscribe_to_all_tables(); } -#[derive(Resource, Deref)] -struct Player(stdb::Player); - -// TODO or reconnect? fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage, mut commands: Commands) { for msg in messages.read() { info!("you're now jongline"); @@ -110,25 +104,19 @@ fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage, mut com creds_store() .save(&msg.access_token) .expect("i/o error saving token"); - - stdb.subscription_builder() - .on_applied(|ctx| { - trace!("subbed to player table"); - }) - .on_error(|_, err| error!("sub to player failed: {err}")) - .subscribe(format!( - "SELECT * FROM player p WHERE p.identity = '{}'", - stdb.identity() - )); } } +// 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, @@ -154,47 +142,14 @@ fn on_player_insert_update( } } -fn join_or_create_lobby(stdb: SpacetimeDB, player: Res, mut lobby_id: ResMut) { - let sub = stdb - .subscription_builder() - .on_applied(|_| { - trace!("subbed to lobby table"); - }) - .on_error(|_, err| error!("sub to lobby table failed: {err}")) - .subscribe([format!( - "SELECT l.* - FROM lobby l - WHERE l.host_player_id = {}", - player.id - )]); - +fn join_or_create_lobby(stdb: SpacetimeDB, player: Res) { let mut player = player.clone(); if player.lobby_id == 0 { stdb.reducers().join_or_create_lobby(0).unwrap(); - player.lobby_id = stdb - .db() - .lobby() - .host_player_id() - .find(&player.id) - .unwrap_or_else(|| panic!("can't find player with id {}", player.id)) - .id; + } else { + info!("in lobby: {}", player.lobby_id) } - - if let Some(lobby) = stdb.db().lobby().id().find(&player.lobby_id) - && lobby.host_player_id == player.id - && matches!(lobby.game_state.into(), GameState::None) - { - debug!("setup_game({})", lobby.id); - stdb.reducers().setup_game(lobby.id).unwrap() - } - - *lobby_id = LobbyId(player.lobby_id); - stdb.reducers().setup_game(**lobby_id).unwrap(); - - stdb.subscription_builder() - .on_applied(|_| trace!("subbed to view_hand")) - .subscribe("SELECT * FROM view_hand"); } impl From for GameState { @@ -209,23 +164,40 @@ impl From for GameState { } } -#[derive(Resource, Default, Deref)] -struct LobbyId(u32); - fn on_lobby_insert_update( stdb: SpacetimeDB, mut messages: ReadInsertUpdateMessage, + player: Option>, + mut commands: Commands, mut next_gamestate: ResMut>, - - lobby_id: Res, ) { for msg in messages.read() { - // TODO should this be an assert? - if msg.new.id == **lobby_id { - debug!("lobby: {:?}", msg.new); + if let Some(player) = player.as_ref() + && player.lobby_id == msg.new.id + { + debug!("on_lobby_insert_update: {:#?}", msg.new); next_gamestate.set(msg.new.game_state.into()); + + match msg.new.game_state { + stdb::GameState::None => { + trace!("setup game"); + stdb.reducers().setup_game(player.lobby_id).unwrap(); + } + stdb::GameState::Setup => { + trace!("game entered setup"); + } + stdb::GameState::Deal => { + trace!("game entered deal") + } + stdb::GameState::Play => { + trace!("game entered play") + } + stdb::GameState::Exit => { + trace!("game enetered exit") + } + } } } } From ce84478376a9f6e02356caf571fbd801f4ed97dc Mon Sep 17 00:00:00 2001 From: Tao Tien <29749622+taotien@users.noreply.github.com> Date: Sun, 8 Feb 2026 23:47:57 -0800 Subject: [PATCH 11/11] hack for player-lobby and Res race? --- devenv.lock | 8 +- devenv.nix | 23 ++- devenv.yaml | 1 + jong/src/game.rs | 119 +++++------ jong/src/game/hand.rs | 39 ---- jong/src/lib.rs | 52 +++++ jong/src/stdb/add_player_reducer.rs | 102 ---------- jong/src/stdb/bot_type.rs | 2 + jong/src/stdb/bothand_table.rs | 143 ------------- jong/src/stdb/deal_hands_reducer.rs | 100 --------- jong/src/stdb/hand_table.rs | 29 ++- jong/src/stdb/hand_type.rs | 5 +- jong/src/stdb/insert_wall_reducer.rs | 105 ---------- jong/src/stdb/lobby_setup_reducer.rs | 100 --------- jong/src/stdb/lobby_table.rs | 1 + jong/src/stdb/lobby_type.rs | 2 + jong/src/stdb/mod.rs | 47 ++--- ...bot_hand_type.rs => player_or_bot_type.rs} | 11 +- jong/src/stdb/player_type.rs | 2 + jong/src/stdb/pond_table.rs | 48 +++++ jong/src/stdb/pond_type.rs | 3 + jong/src/stdb/set_name_reducer.rs | 102 ---------- ...ame_reducer.rs => shuffle_deal_reducer.rs} | 68 +++---- jong/src/stdb/shuffle_wall_reducer.rs | 100 --------- jong/src/stdb/sort_hand_reducer.rs | 100 --------- jong/src/stdb/view_hand_table.rs | 96 --------- jong/src/stdb/view_player_hand_table.rs | 1 + justfile | 8 +- mprocs.log | 6 + spacetimedb/src/game.rs | 60 ++++++ spacetimedb/src/game/hand.rs | 53 +++++ spacetimedb/src/game/wall.rs | 36 ++++ spacetimedb/src/lib.rs | 191 +----------------- spacetimedb/src/tables.rs | 84 ++++++++ 34 files changed, 517 insertions(+), 1330 deletions(-) delete mode 100644 jong/src/stdb/add_player_reducer.rs delete mode 100644 jong/src/stdb/bothand_table.rs delete mode 100644 jong/src/stdb/deal_hands_reducer.rs delete mode 100644 jong/src/stdb/insert_wall_reducer.rs delete mode 100644 jong/src/stdb/lobby_setup_reducer.rs rename jong/src/stdb/{bot_hand_type.rs => player_or_bot_type.rs} (75%) delete mode 100644 jong/src/stdb/set_name_reducer.rs rename jong/src/stdb/{setup_game_reducer.rs => shuffle_deal_reducer.rs} (54%) delete mode 100644 jong/src/stdb/shuffle_wall_reducer.rs delete mode 100644 jong/src/stdb/sort_hand_reducer.rs delete mode 100644 jong/src/stdb/view_hand_table.rs create mode 100644 mprocs.log create mode 100644 spacetimedb/src/game.rs create mode 100644 spacetimedb/src/game/hand.rs create mode 100644 spacetimedb/src/game/wall.rs create mode 100644 spacetimedb/src/tables.rs diff --git a/devenv.lock b/devenv.lock index dfdab03..9711b70 100644 --- a/devenv.lock +++ b/devenv.lock @@ -3,10 +3,10 @@ "devenv": { "locked": { "dir": "src/modules", - "lastModified": 1770399425, + "lastModified": 1770666213, "owner": "cachix", "repo": "devenv", - "rev": "0f006b2e9f591cc44cf219048b5e33793530403b", + "rev": "d4ffee46c9088df6e000470b998a2d2c16517f62", "type": "github" }, "original": { @@ -125,10 +125,10 @@ ] }, "locked": { - "lastModified": 1770520253, + "lastModified": 1770606655, "owner": "oxalica", "repo": "rust-overlay", - "rev": "ebb8a141f60bb0ec33836333e0ca7928a072217f", + "rev": "11a396520bf911e4ed01e78e11633d3fc63b350e", "type": "github" }, "original": { diff --git a/devenv.nix b/devenv.nix index 57c530b..89cd3ec 100644 --- a/devenv.nix +++ b/devenv.nix @@ -1,17 +1,29 @@ { pkgs, lib, - config, - inputs, ... }: 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) @@ -41,10 +53,9 @@ components = ["rust-src" "rust-docs" "rustc-codegen-cranelift" "rust-analyzer" "rustfmt"]; }; - # 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"; + process.manager.implementation = "mprocs"; + process.managers.mprocs.settings = { + server = "127.0.0.1:4050"; }; # https://devenv.sh/services/ diff --git a/devenv.yaml b/devenv.yaml index 37e8589..48e1844 100644 --- a/devenv.yaml +++ b/devenv.yaml @@ -1,3 +1,4 @@ +allowUnfree: true inputs: nixpkgs: url: github:cachix/devenv-nixpkgs/rolling diff --git a/jong/src/game.rs b/jong/src/game.rs index d00e50c..bb308f5 100644 --- a/jong/src/game.rs +++ b/jong/src/game.rs @@ -6,13 +6,14 @@ use bevy_spacetimedb::{ TableMessages, }; use spacetimedb::Identity; -use spacetimedb_sdk::{DbContext, credentials}; +use spacetimedb_sdk::{DbContext, Table, credentials}; use crate::{ - SpacetimeDB, creds_store, + SpacetimeDB, creds_store, game, stdb::{ self, DbConnection, HandTableAccess, LobbyTableAccess, PlayerTableAccess, RemoteTables, - add_bot, join_or_create_lobby, login_or_add_player, setup_game, + ViewPlayerHandTableAccess, add_bot, join_or_create_lobby, login_or_add_player, + shuffle_deal, }, }; use crate::{ @@ -24,7 +25,7 @@ use crate::{ }, tile::{self}, }; -use jong_types::GameState; +use jong_types::*; pub mod hand; pub mod player; @@ -68,8 +69,6 @@ impl Plugin for Riichi { // .init_resource::() .add_message::() .add_systems(Startup, tile::init_tiles) - // .add_systems(OnEnter(GameState::Setup), setup) - // .add_systems(OnEnter(GameState::Deal), hand::shuffle_deal) // .add_systems(Update, hand::sort_hands.run_if(in_state(GameState::Play))) // .add_systems(OnEnter(TurnState::Tsumo), round::tsumo) // .add_systems(OnEnter(TurnState::Menzen), round::menzen) @@ -82,19 +81,32 @@ impl Plugin for Riichi { .add_systems(Startup, sub_to_all) .add_systems(Update, on_connect) .add_systems(Update, on_disconnect) - .add_systems(Update, (on_player_insert_update, on_lobby_insert_update).chain()) + .add_systems(Update, on_player_insert_update) + .add_systems(Update, on_lobby_insert_update) .add_systems(OnEnter(GameState::Setup), join_or_create_lobby) + .add_systems(Update, view_hand.run_if(in_state(GameState::Play))) // .add_systems(Update, (view_hand).run_if(in_state(GameState::Play))) // semicolon stopper ; } } +fn view_hand(stdb: SpacetimeDB, mut commands: Commands) { + if let Some(hand) = stdb.db().view_player_hand().iter().next() {} +} + fn sub_to_all(stdb: SpacetimeDB) { stdb.subscription_builder() .on_applied(|_| trace!("made all subs!")) .on_error(|_, err| error!("sub failed: {err}")) - .subscribe_to_all_tables(); + .subscribe([ + format!( + "SELECT * FROM player p WHERE p.identity = '{}'", + stdb.identity() + ), + "SELECT l.* FROM lobby l JOIN player p ON l.host_player_id = p.id".into(), + ]); + // .subscribe_to_all_tables(); } fn on_connect(stdb: SpacetimeDB, mut messages: ReadStdbConnectedMessage, mut commands: Commands) { @@ -124,21 +136,8 @@ fn on_player_insert_update( mut commands: Commands, ) { for msg in messages.read() { - debug!( - "player_insert_update msg:\n{:#?} -> \n{:#?}", - msg.old, msg.new - ); - - if msg.new.identity == stdb.identity() { - commands.insert_resource(Player(msg.new.clone())); - // TODO add bots elsewhere - if msg.new.lobby_id != 0 { - info!("joined lobby {}", msg.new.lobby_id); - for _ in 0..3 { - stdb.reducers().add_bot(msg.new.lobby_id).unwrap() - } - } - } + debug!("player_insert_update msg:\n{:#?}", msg.new); + commands.insert_resource(Player(msg.new.clone())); } } @@ -152,52 +151,58 @@ fn join_or_create_lobby(stdb: SpacetimeDB, player: Res) { } } -impl From for GameState { - fn from(value: stdb::GameState) -> Self { - match value { - stdb::GameState::None => Self::None, - stdb::GameState::Setup => Self::Setup, - stdb::GameState::Deal => Self::Deal, - stdb::GameState::Play => Self::Play, - stdb::GameState::Exit => Self::Exit, - } - } -} - fn on_lobby_insert_update( stdb: SpacetimeDB, mut messages: ReadInsertUpdateMessage, - player: Option>, - mut commands: Commands, mut next_gamestate: ResMut>, ) { for msg in messages.read() { - if let Some(player) = player.as_ref() - && player.lobby_id == msg.new.id - { - debug!("on_lobby_insert_update: {:#?}", msg.new); - next_gamestate.set(msg.new.game_state.into()); + trace!("on_lobby_insert_update msg:\n{:#?}", msg.new); - match msg.new.game_state { - stdb::GameState::None => { - trace!("setup game"); - stdb.reducers().setup_game(player.lobby_id).unwrap(); + next_gamestate.set(msg.new.game_state.into()); + match msg.new.game_state { + stdb::GameState::None => { + trace!("game entered none"); + } + stdb::GameState::Setup => { + trace!("game entered setup"); + + let player = stdb + .db() + .player() + .identity() + .find(&stdb.identity()) + .unwrap(); + + if player.lobby_id == msg.new.id { + stdb.reducers().shuffle_deal(player.lobby_id).unwrap(); + for _ in 0..3 { + stdb.reducers().add_bot(player.lobby_id).unwrap(); + } + } else { + trace!("no player but game in setup") } - stdb::GameState::Setup => { - trace!("game entered setup"); - } - stdb::GameState::Deal => { - trace!("game entered deal") - } - stdb::GameState::Play => { - trace!("game entered play") - } - stdb::GameState::Exit => { - trace!("game enetered exit") + } + 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::>(); + commands.spawn(Hand).add_children(&tiles); } } + stdb::GameState::Exit => { + trace!("game enetered exit"); + } } } } diff --git a/jong/src/game/hand.rs b/jong/src/game/hand.rs index 26f81c1..4e89c13 100644 --- a/jong/src/game/hand.rs +++ b/jong/src/game/hand.rs @@ -25,45 +25,6 @@ pub struct Discarded; // Manual, // } -pub(crate) fn sort_hands( - tiles: Query<&Tile>, - hands: Query<&mut Children, (Changed, With, Without)>, -) -> 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>, - players: Populated>, - wall_ent: Single>, - mut next_gamestate: ResMut>, -) { - 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 pub(crate) fn check_wincon(hand: &[Tile; 14], melds: &[&[Tile]]) -> bool { // 4x3 + pair diff --git a/jong/src/lib.rs b/jong/src/lib.rs index 8981acd..ac78c87 100644 --- a/jong/src/lib.rs +++ b/jong/src/lib.rs @@ -19,3 +19,55 @@ pub type SpacetimeDB<'a> = Res<'a, StdbConnection>; fn creds_store() -> credentials::File { credentials::File::new("jongline") } + +impl From 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 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 for jong_types::Rank { + fn from(value: stdb::Rank) -> Self { + Self { + number: value.number, + } + } +} + +impl From for jong_types::Wind { + fn from(value: stdb::Wind) -> Self { + Self::from_repr(value as usize).unwrap() + } +} + +impl From for jong_types::Dragon { + fn from(value: stdb::Dragon) -> Self { + Self::from_repr(value as usize).unwrap() + } +} diff --git a/jong/src/stdb/add_player_reducer.rs b/jong/src/stdb/add_player_reducer.rs deleted file mode 100644 index 757a0b6..0000000 --- a/jong/src/stdb/add_player_reducer.rs +++ /dev/null @@ -1,102 +0,0 @@ -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. - -#![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] -#[sats(crate = __lib)] -pub(super) struct AddPlayerArgs { - pub name: Option, -} - -impl From for super::Reducer { - fn from(args: AddPlayerArgs) -> Self { - Self::AddPlayer { name: args.name } - } -} - -impl __sdk::InModule for AddPlayerArgs { - type Module = super::RemoteModule; -} - -pub struct AddPlayerCallbackId(__sdk::CallbackId); - -#[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `add_player`. -/// -/// Implemented for [`super::RemoteReducers`]. -pub trait add_player { - /// Request that the remote module invoke the reducer `add_player` to run as soon as possible. - /// - /// This method returns immediately, and errors only if we are unable to send the request. - /// The reducer will run asynchronously in the future, - /// and its status can be observed by listening for [`Self::on_add_player`] callbacks. - fn add_player(&self, name: Option) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `add_player`. - /// - /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] - /// to determine the reducer's status. - /// - /// The returned [`AddPlayerCallbackId`] can be passed to [`Self::remove_on_add_player`] - /// to cancel the callback. - fn on_add_player( - &self, - callback: impl FnMut(&super::ReducerEventContext, &Option) + Send + 'static, - ) -> AddPlayerCallbackId; - /// Cancel a callback previously registered by [`Self::on_add_player`], - /// causing it not to run in the future. - fn remove_on_add_player(&self, callback: AddPlayerCallbackId); -} - -impl add_player for super::RemoteReducers { - fn add_player(&self, name: Option) -> __sdk::Result<()> { - self.imp.call_reducer("add_player", AddPlayerArgs { name }) - } - fn on_add_player( - &self, - mut callback: impl FnMut(&super::ReducerEventContext, &Option) + Send + 'static, - ) -> AddPlayerCallbackId { - AddPlayerCallbackId(self.imp.on_reducer( - "add_player", - Box::new(move |ctx: &super::ReducerEventContext| { - #[allow(irrefutable_let_patterns)] - let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::AddPlayer { name }, - .. - }, - .. - } = ctx - else { - unreachable!() - }; - callback(ctx, name) - }), - )) - } - fn remove_on_add_player(&self, callback: AddPlayerCallbackId) { - self.imp.remove_on_reducer("add_player", callback.0) - } -} - -#[allow(non_camel_case_types)] -#[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `add_player`. -/// -/// Implemented for [`super::SetReducerFlags`]. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_add_player { - /// Set the call-reducer flags for the reducer `add_player` to `flags`. - /// - /// This type is currently unstable and may be removed without a major version bump. - fn add_player(&self, flags: __ws::CallReducerFlags); -} - -impl set_flags_for_add_player for super::SetReducerFlags { - fn add_player(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("add_player", flags); - } -} diff --git a/jong/src/stdb/bot_type.rs b/jong/src/stdb/bot_type.rs index ba15e53..0d4fd2c 100644 --- a/jong/src/stdb/bot_type.rs +++ b/jong/src/stdb/bot_type.rs @@ -9,6 +9,8 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; pub struct Bot { pub id: u32, pub lobby_id: u32, + pub hand_id: u32, + pub pond_id: u32, } impl __sdk::InModule for Bot { diff --git a/jong/src/stdb/bothand_table.rs b/jong/src/stdb/bothand_table.rs deleted file mode 100644 index b2307c4..0000000 --- a/jong/src/stdb/bothand_table.rs +++ /dev/null @@ -1,143 +0,0 @@ -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. - -#![allow(unused, clippy::all)] -use super::bot_hand_type::BotHand; -use super::tile_type::Tile; -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -/// Table handle for the table `bothand`. -/// -/// Obtain a handle from the [`BothandTableAccess::bothand`] method on [`super::RemoteTables`], -/// like `ctx.db.bothand()`. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.bothand().on_insert(...)`. -pub struct BothandTableHandle<'ctx> { - imp: __sdk::TableHandle, - ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -#[allow(non_camel_case_types)] -/// Extension trait for access to the table `bothand`. -/// -/// Implemented for [`super::RemoteTables`]. -pub trait BothandTableAccess { - #[allow(non_snake_case)] - /// Obtain a [`BothandTableHandle`], which mediates access to the table `bothand`. - fn bothand(&self) -> BothandTableHandle<'_>; -} - -impl BothandTableAccess for super::RemoteTables { - fn bothand(&self) -> BothandTableHandle<'_> { - BothandTableHandle { - imp: self.imp.get_table::("bothand"), - ctx: std::marker::PhantomData, - } - } -} - -pub struct BothandInsertCallbackId(__sdk::CallbackId); -pub struct BothandDeleteCallbackId(__sdk::CallbackId); - -impl<'ctx> __sdk::Table for BothandTableHandle<'ctx> { - type Row = BotHand; - type EventContext = super::EventContext; - - fn count(&self) -> u64 { - self.imp.count() - } - fn iter(&self) -> impl Iterator + '_ { - self.imp.iter() - } - - type InsertCallbackId = BothandInsertCallbackId; - - fn on_insert( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> BothandInsertCallbackId { - BothandInsertCallbackId(self.imp.on_insert(Box::new(callback))) - } - - fn remove_on_insert(&self, callback: BothandInsertCallbackId) { - self.imp.remove_on_insert(callback.0) - } - - type DeleteCallbackId = BothandDeleteCallbackId; - - fn on_delete( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> BothandDeleteCallbackId { - BothandDeleteCallbackId(self.imp.on_delete(Box::new(callback))) - } - - fn remove_on_delete(&self, callback: BothandDeleteCallbackId) { - self.imp.remove_on_delete(callback.0) - } -} - -#[doc(hidden)] -pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { - let _table = client_cache.get_or_make_table::("bothand"); - _table.add_unique_constraint::("bot_id", |row| &row.bot_id); -} -pub struct BothandUpdateCallbackId(__sdk::CallbackId); - -impl<'ctx> __sdk::TableWithPrimaryKey for BothandTableHandle<'ctx> { - type UpdateCallbackId = BothandUpdateCallbackId; - - fn on_update( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, - ) -> BothandUpdateCallbackId { - BothandUpdateCallbackId(self.imp.on_update(Box::new(callback))) - } - - fn remove_on_update(&self, callback: BothandUpdateCallbackId) { - self.imp.remove_on_update(callback.0) - } -} - -#[doc(hidden)] -pub(super) fn parse_table_update( - raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, -) -> __sdk::Result<__sdk::TableUpdate> { - __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { - __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") - .with_cause(e) - .into() - }) -} - -/// Access to the `bot_id` unique index on the table `bothand`, -/// which allows point queries on the field of the same name -/// via the [`BothandBotIdUnique::find`] method. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.bothand().bot_id().find(...)`. -pub struct BothandBotIdUnique<'ctx> { - imp: __sdk::UniqueConstraintHandle, - phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -impl<'ctx> BothandTableHandle<'ctx> { - /// Get a handle on the `bot_id` unique index on the table `bothand`. - pub fn bot_id(&self) -> BothandBotIdUnique<'ctx> { - BothandBotIdUnique { - imp: self.imp.get_unique_constraint::("bot_id"), - phantom: std::marker::PhantomData, - } - } -} - -impl<'ctx> BothandBotIdUnique<'ctx> { - /// Find the subscribed row whose `bot_id` column value is equal to `col_val`, - /// if such a row is present in the client cache. - pub fn find(&self, col_val: &u32) -> Option { - self.imp.find(col_val) - } -} diff --git a/jong/src/stdb/deal_hands_reducer.rs b/jong/src/stdb/deal_hands_reducer.rs deleted file mode 100644 index cb67ec4..0000000 --- a/jong/src/stdb/deal_hands_reducer.rs +++ /dev/null @@ -1,100 +0,0 @@ -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. - -#![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] -#[sats(crate = __lib)] -pub(super) struct DealHandsArgs {} - -impl From for super::Reducer { - fn from(args: DealHandsArgs) -> Self { - Self::DealHands - } -} - -impl __sdk::InModule for DealHandsArgs { - type Module = super::RemoteModule; -} - -pub struct DealHandsCallbackId(__sdk::CallbackId); - -#[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `deal_hands`. -/// -/// Implemented for [`super::RemoteReducers`]. -pub trait deal_hands { - /// Request that the remote module invoke the reducer `deal_hands` to run as soon as possible. - /// - /// This method returns immediately, and errors only if we are unable to send the request. - /// The reducer will run asynchronously in the future, - /// and its status can be observed by listening for [`Self::on_deal_hands`] callbacks. - fn deal_hands(&self) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `deal_hands`. - /// - /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] - /// to determine the reducer's status. - /// - /// The returned [`DealHandsCallbackId`] can be passed to [`Self::remove_on_deal_hands`] - /// to cancel the callback. - fn on_deal_hands( - &self, - callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> DealHandsCallbackId; - /// Cancel a callback previously registered by [`Self::on_deal_hands`], - /// causing it not to run in the future. - fn remove_on_deal_hands(&self, callback: DealHandsCallbackId); -} - -impl deal_hands for super::RemoteReducers { - fn deal_hands(&self) -> __sdk::Result<()> { - self.imp.call_reducer("deal_hands", DealHandsArgs {}) - } - fn on_deal_hands( - &self, - mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> DealHandsCallbackId { - DealHandsCallbackId(self.imp.on_reducer( - "deal_hands", - Box::new(move |ctx: &super::ReducerEventContext| { - #[allow(irrefutable_let_patterns)] - let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::DealHands {}, - .. - }, - .. - } = ctx - else { - unreachable!() - }; - callback(ctx) - }), - )) - } - fn remove_on_deal_hands(&self, callback: DealHandsCallbackId) { - self.imp.remove_on_reducer("deal_hands", callback.0) - } -} - -#[allow(non_camel_case_types)] -#[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `deal_hands`. -/// -/// Implemented for [`super::SetReducerFlags`]. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_deal_hands { - /// Set the call-reducer flags for the reducer `deal_hands` to `flags`. - /// - /// This type is currently unstable and may be removed without a major version bump. - fn deal_hands(&self, flags: __ws::CallReducerFlags); -} - -impl set_flags_for_deal_hands for super::SetReducerFlags { - fn deal_hands(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("deal_hands", flags); - } -} diff --git a/jong/src/stdb/hand_table.rs b/jong/src/stdb/hand_table.rs index e72e3a0..d967559 100644 --- a/jong/src/stdb/hand_table.rs +++ b/jong/src/stdb/hand_table.rs @@ -3,6 +3,7 @@ #![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}; @@ -82,7 +83,7 @@ impl<'ctx> __sdk::Table for HandTableHandle<'ctx> { #[doc(hidden)] pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { let _table = client_cache.get_or_make_table::("hand"); - _table.add_unique_constraint::<__sdk::Identity>("player_identity", |row| &row.player_identity); + _table.add_unique_constraint::("id", |row| &row.id); } pub struct HandUpdateCallbackId(__sdk::CallbackId); @@ -112,34 +113,32 @@ pub(super) fn parse_table_update( }) } -/// Access to the `player_identity` unique index on the table `hand`, +/// Access to the `id` unique index on the table `hand`, /// which allows point queries on the field of the same name -/// via the [`HandPlayerIdentityUnique::find`] method. +/// via the [`HandIdUnique::find`] method. /// /// Users are encouraged not to explicitly reference this type, /// but to directly chain method calls, -/// like `ctx.db.hand().player_identity().find(...)`. -pub struct HandPlayerIdentityUnique<'ctx> { - imp: __sdk::UniqueConstraintHandle, +/// like `ctx.db.hand().id().find(...)`. +pub struct HandIdUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, } impl<'ctx> HandTableHandle<'ctx> { - /// Get a handle on the `player_identity` unique index on the table `hand`. - pub fn player_identity(&self) -> HandPlayerIdentityUnique<'ctx> { - HandPlayerIdentityUnique { - imp: self - .imp - .get_unique_constraint::<__sdk::Identity>("player_identity"), + /// 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::("id"), phantom: std::marker::PhantomData, } } } -impl<'ctx> HandPlayerIdentityUnique<'ctx> { - /// Find the subscribed row whose `player_identity` column value is equal to `col_val`, +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: &__sdk::Identity) -> Option { + pub fn find(&self, col_val: &u32) -> Option { self.imp.find(col_val) } } diff --git a/jong/src/stdb/hand_type.rs b/jong/src/stdb/hand_type.rs index 427b7c6..2c4f86b 100644 --- a/jong/src/stdb/hand_type.rs +++ b/jong/src/stdb/hand_type.rs @@ -4,12 +4,15 @@ #![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 player_identity: __sdk::Identity, + pub id: u32, + pub owner: PlayerOrBot, + pub sort: bool, pub tiles: Vec, } diff --git a/jong/src/stdb/insert_wall_reducer.rs b/jong/src/stdb/insert_wall_reducer.rs deleted file mode 100644 index 2189dae..0000000 --- a/jong/src/stdb/insert_wall_reducer.rs +++ /dev/null @@ -1,105 +0,0 @@ -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. - -#![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] -#[sats(crate = __lib)] -pub(super) struct InsertWallArgs { - pub player_ids: Vec, -} - -impl From for super::Reducer { - fn from(args: InsertWallArgs) -> Self { - Self::InsertWall { - player_ids: args.player_ids, - } - } -} - -impl __sdk::InModule for InsertWallArgs { - type Module = super::RemoteModule; -} - -pub struct InsertWallCallbackId(__sdk::CallbackId); - -#[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `insert_wall`. -/// -/// Implemented for [`super::RemoteReducers`]. -pub trait insert_wall { - /// Request that the remote module invoke the reducer `insert_wall` to run as soon as possible. - /// - /// This method returns immediately, and errors only if we are unable to send the request. - /// The reducer will run asynchronously in the future, - /// and its status can be observed by listening for [`Self::on_insert_wall`] callbacks. - fn insert_wall(&self, player_ids: Vec) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `insert_wall`. - /// - /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] - /// to determine the reducer's status. - /// - /// The returned [`InsertWallCallbackId`] can be passed to [`Self::remove_on_insert_wall`] - /// to cancel the callback. - fn on_insert_wall( - &self, - callback: impl FnMut(&super::ReducerEventContext, &Vec) + Send + 'static, - ) -> InsertWallCallbackId; - /// Cancel a callback previously registered by [`Self::on_insert_wall`], - /// causing it not to run in the future. - fn remove_on_insert_wall(&self, callback: InsertWallCallbackId); -} - -impl insert_wall for super::RemoteReducers { - fn insert_wall(&self, player_ids: Vec) -> __sdk::Result<()> { - self.imp - .call_reducer("insert_wall", InsertWallArgs { player_ids }) - } - fn on_insert_wall( - &self, - mut callback: impl FnMut(&super::ReducerEventContext, &Vec) + Send + 'static, - ) -> InsertWallCallbackId { - InsertWallCallbackId(self.imp.on_reducer( - "insert_wall", - Box::new(move |ctx: &super::ReducerEventContext| { - #[allow(irrefutable_let_patterns)] - let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::InsertWall { player_ids }, - .. - }, - .. - } = ctx - else { - unreachable!() - }; - callback(ctx, player_ids) - }), - )) - } - fn remove_on_insert_wall(&self, callback: InsertWallCallbackId) { - self.imp.remove_on_reducer("insert_wall", callback.0) - } -} - -#[allow(non_camel_case_types)] -#[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `insert_wall`. -/// -/// Implemented for [`super::SetReducerFlags`]. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_insert_wall { - /// Set the call-reducer flags for the reducer `insert_wall` to `flags`. - /// - /// This type is currently unstable and may be removed without a major version bump. - fn insert_wall(&self, flags: __ws::CallReducerFlags); -} - -impl set_flags_for_insert_wall for super::SetReducerFlags { - fn insert_wall(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("insert_wall", flags); - } -} diff --git a/jong/src/stdb/lobby_setup_reducer.rs b/jong/src/stdb/lobby_setup_reducer.rs deleted file mode 100644 index c54de7d..0000000 --- a/jong/src/stdb/lobby_setup_reducer.rs +++ /dev/null @@ -1,100 +0,0 @@ -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. - -#![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] -#[sats(crate = __lib)] -pub(super) struct LobbySetupArgs {} - -impl From for super::Reducer { - fn from(args: LobbySetupArgs) -> Self { - Self::LobbySetup - } -} - -impl __sdk::InModule for LobbySetupArgs { - type Module = super::RemoteModule; -} - -pub struct LobbySetupCallbackId(__sdk::CallbackId); - -#[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `lobby_setup`. -/// -/// Implemented for [`super::RemoteReducers`]. -pub trait lobby_setup { - /// Request that the remote module invoke the reducer `lobby_setup` to run as soon as possible. - /// - /// This method returns immediately, and errors only if we are unable to send the request. - /// The reducer will run asynchronously in the future, - /// and its status can be observed by listening for [`Self::on_lobby_setup`] callbacks. - fn lobby_setup(&self) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `lobby_setup`. - /// - /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] - /// to determine the reducer's status. - /// - /// The returned [`LobbySetupCallbackId`] can be passed to [`Self::remove_on_lobby_setup`] - /// to cancel the callback. - fn on_lobby_setup( - &self, - callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> LobbySetupCallbackId; - /// Cancel a callback previously registered by [`Self::on_lobby_setup`], - /// causing it not to run in the future. - fn remove_on_lobby_setup(&self, callback: LobbySetupCallbackId); -} - -impl lobby_setup for super::RemoteReducers { - fn lobby_setup(&self) -> __sdk::Result<()> { - self.imp.call_reducer("lobby_setup", LobbySetupArgs {}) - } - fn on_lobby_setup( - &self, - mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> LobbySetupCallbackId { - LobbySetupCallbackId(self.imp.on_reducer( - "lobby_setup", - Box::new(move |ctx: &super::ReducerEventContext| { - #[allow(irrefutable_let_patterns)] - let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::LobbySetup {}, - .. - }, - .. - } = ctx - else { - unreachable!() - }; - callback(ctx) - }), - )) - } - fn remove_on_lobby_setup(&self, callback: LobbySetupCallbackId) { - self.imp.remove_on_reducer("lobby_setup", callback.0) - } -} - -#[allow(non_camel_case_types)] -#[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `lobby_setup`. -/// -/// Implemented for [`super::SetReducerFlags`]. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_lobby_setup { - /// Set the call-reducer flags for the reducer `lobby_setup` to `flags`. - /// - /// This type is currently unstable and may be removed without a major version bump. - fn lobby_setup(&self, flags: __ws::CallReducerFlags); -} - -impl set_flags_for_lobby_setup for super::SetReducerFlags { - fn lobby_setup(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("lobby_setup", flags); - } -} diff --git a/jong/src/stdb/lobby_table.rs b/jong/src/stdb/lobby_table.rs index 4249c91..ab1d881 100644 --- a/jong/src/stdb/lobby_table.rs +++ b/jong/src/stdb/lobby_table.rs @@ -4,6 +4,7 @@ #![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`. diff --git a/jong/src/stdb/lobby_type.rs b/jong/src/stdb/lobby_type.rs index 8d7b094..110a274 100644 --- a/jong/src/stdb/lobby_type.rs +++ b/jong/src/stdb/lobby_type.rs @@ -5,12 +5,14 @@ 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, pub game_state: GameState, } diff --git a/jong/src/stdb/mod.rs b/jong/src/stdb/mod.rs index 888635d..6c87060 100644 --- a/jong/src/stdb/mod.rs +++ b/jong/src/stdb/mod.rs @@ -7,10 +7,8 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; pub mod add_bot_reducer; -pub mod bot_hand_type; pub mod bot_table; pub mod bot_type; -pub mod bothand_table; pub mod dragon_type; pub mod game_state_type; pub mod hand_table; @@ -19,13 +17,13 @@ pub mod join_or_create_lobby_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_type; pub mod pond_table; pub mod pond_type; pub mod rank_type; -pub mod setup_game_reducer; -pub mod sort_hand_reducer; +pub mod shuffle_deal_reducer; pub mod suit_type; pub mod tile_type; pub mod view_player_hand_table; @@ -34,10 +32,8 @@ pub mod wall_type; pub mod wind_type; pub use add_bot_reducer::{add_bot, set_flags_for_add_bot, AddBotCallbackId}; -pub use bot_hand_type::BotHand; pub use bot_table::*; pub use bot_type::Bot; -pub use bothand_table::*; pub use dragon_type::Dragon; pub use game_state_type::GameState; pub use hand_table::*; @@ -50,13 +46,13 @@ 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_type::Player; pub use pond_table::*; pub use pond_type::Pond; pub use rank_type::Rank; -pub use setup_game_reducer::{set_flags_for_setup_game, setup_game, SetupGameCallbackId}; -pub use sort_hand_reducer::{set_flags_for_sort_hand, sort_hand, SortHandCallbackId}; +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::*; @@ -75,8 +71,7 @@ pub enum Reducer { AddBot { lobby_id: u32 }, JoinOrCreateLobby { lobby_id: u32 }, LoginOrAddPlayer, - SetupGame { lobby_id: u32 }, - SortHand, + ShuffleDeal { lobby_id: u32 }, } impl __sdk::InModule for Reducer { @@ -89,8 +84,7 @@ impl __sdk::Reducer for Reducer { Reducer::AddBot { .. } => "add_bot", Reducer::JoinOrCreateLobby { .. } => "join_or_create_lobby", Reducer::LoginOrAddPlayer => "login_or_add_player", - Reducer::SetupGame { .. } => "setup_game", - Reducer::SortHand => "sort_hand", + Reducer::ShuffleDeal { .. } => "shuffle_deal", _ => unreachable!(), } } @@ -112,16 +106,9 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { login_or_add_player_reducer::LoginOrAddPlayerArgs, >("login_or_add_player", &value.args)? .into()), - "setup_game" => Ok( - __sdk::parse_reducer_args::( - "setup_game", - &value.args, - )? - .into(), - ), - "sort_hand" => Ok( - __sdk::parse_reducer_args::( - "sort_hand", + "shuffle_deal" => Ok( + __sdk::parse_reducer_args::( + "shuffle_deal", &value.args, )? .into(), @@ -141,7 +128,6 @@ impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer { #[doc(hidden)] pub struct DbUpdate { bot: __sdk::TableUpdate, - bothand: __sdk::TableUpdate, hand: __sdk::TableUpdate, lobby: __sdk::TableUpdate, player: __sdk::TableUpdate, @@ -159,9 +145,6 @@ impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate { "bot" => db_update .bot .append(bot_table::parse_table_update(table_update)?), - "bothand" => db_update - .bothand - .append(bothand_table::parse_table_update(table_update)?), "hand" => db_update .hand .append(hand_table::parse_table_update(table_update)?), @@ -209,19 +192,18 @@ impl __sdk::DbUpdate for DbUpdate { diff.bot = cache .apply_diff_to_table::("bot", &self.bot) .with_updates_by_pk(|row| &row.id); - diff.bothand = cache - .apply_diff_to_table::("bothand", &self.bothand) - .with_updates_by_pk(|row| &row.bot_id); diff.hand = cache .apply_diff_to_table::("hand", &self.hand) - .with_updates_by_pk(|row| &row.player_identity); + .with_updates_by_pk(|row| &row.id); diff.lobby = cache .apply_diff_to_table::("lobby", &self.lobby) .with_updates_by_pk(|row| &row.id); diff.player = cache .apply_diff_to_table::("player", &self.player) .with_updates_by_pk(|row| &row.identity); - diff.pond = cache.apply_diff_to_table::("pond", &self.pond); + diff.pond = cache + .apply_diff_to_table::("pond", &self.pond) + .with_updates_by_pk(|row| &row.id); diff.wall = cache .apply_diff_to_table::("wall", &self.wall) .with_updates_by_pk(|row| &row.lobby_id); @@ -237,7 +219,6 @@ impl __sdk::DbUpdate for DbUpdate { #[doc(hidden)] pub struct AppliedDiff<'r> { bot: __sdk::TableAppliedDiff<'r, Bot>, - bothand: __sdk::TableAppliedDiff<'r, BotHand>, hand: __sdk::TableAppliedDiff<'r, Hand>, lobby: __sdk::TableAppliedDiff<'r, Lobby>, player: __sdk::TableAppliedDiff<'r, Player>, @@ -258,7 +239,6 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> { callbacks: &mut __sdk::DbCallbacks, ) { callbacks.invoke_table_row_callbacks::("bot", &self.bot, event); - callbacks.invoke_table_row_callbacks::("bothand", &self.bothand, event); callbacks.invoke_table_row_callbacks::("hand", &self.hand, event); callbacks.invoke_table_row_callbacks::("lobby", &self.lobby, event); callbacks.invoke_table_row_callbacks::("player", &self.player, event); @@ -989,7 +969,6 @@ impl __sdk::SpacetimeModule for RemoteModule { fn register_tables(client_cache: &mut __sdk::ClientCache) { bot_table::register_table(client_cache); - bothand_table::register_table(client_cache); hand_table::register_table(client_cache); lobby_table::register_table(client_cache); player_table::register_table(client_cache); diff --git a/jong/src/stdb/bot_hand_type.rs b/jong/src/stdb/player_or_bot_type.rs similarity index 75% rename from jong/src/stdb/bot_hand_type.rs rename to jong/src/stdb/player_or_bot_type.rs index d2aeefb..538d940 100644 --- a/jong/src/stdb/bot_hand_type.rs +++ b/jong/src/stdb/player_or_bot_type.rs @@ -4,15 +4,14 @@ #![allow(unused, clippy::all)] 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)] #[sats(crate = __lib)] -pub struct BotHand { - pub bot_id: u32, - pub tiles: Vec, +pub enum PlayerOrBot { + Player(u32), + + Bot(u32), } -impl __sdk::InModule for BotHand { +impl __sdk::InModule for PlayerOrBot { type Module = super::RemoteModule; } diff --git a/jong/src/stdb/player_type.rs b/jong/src/stdb/player_type.rs index 278ed9e..0e651ec 100644 --- a/jong/src/stdb/player_type.rs +++ b/jong/src/stdb/player_type.rs @@ -11,6 +11,8 @@ pub struct Player { pub id: u32, pub name: Option, pub lobby_id: u32, + pub hand_id: u32, + pub pond_id: u32, } impl __sdk::InModule for Player { diff --git a/jong/src/stdb/pond_table.rs b/jong/src/stdb/pond_table.rs index 0230d77..9f079c2 100644 --- a/jong/src/stdb/pond_table.rs +++ b/jong/src/stdb/pond_table.rs @@ -2,6 +2,7 @@ // 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}; @@ -82,6 +83,23 @@ impl<'ctx> __sdk::Table for PondTableHandle<'ctx> { #[doc(hidden)] pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { let _table = client_cache.get_or_make_table::("pond"); + _table.add_unique_constraint::("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)] @@ -94,3 +112,33 @@ pub(super) fn parse_table_update( .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, + 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::("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 { + self.imp.find(col_val) + } +} diff --git a/jong/src/stdb/pond_type.rs b/jong/src/stdb/pond_type.rs index 3cfbd3e..bf08228 100644 --- a/jong/src/stdb/pond_type.rs +++ b/jong/src/stdb/pond_type.rs @@ -4,11 +4,14 @@ #![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, } diff --git a/jong/src/stdb/set_name_reducer.rs b/jong/src/stdb/set_name_reducer.rs deleted file mode 100644 index cc9905d..0000000 --- a/jong/src/stdb/set_name_reducer.rs +++ /dev/null @@ -1,102 +0,0 @@ -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. - -#![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] -#[sats(crate = __lib)] -pub(super) struct SetNameArgs { - pub name: String, -} - -impl From for super::Reducer { - fn from(args: SetNameArgs) -> Self { - Self::SetName { name: args.name } - } -} - -impl __sdk::InModule for SetNameArgs { - type Module = super::RemoteModule; -} - -pub struct SetNameCallbackId(__sdk::CallbackId); - -#[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `set_name`. -/// -/// Implemented for [`super::RemoteReducers`]. -pub trait set_name { - /// Request that the remote module invoke the reducer `set_name` to run as soon as possible. - /// - /// This method returns immediately, and errors only if we are unable to send the request. - /// The reducer will run asynchronously in the future, - /// and its status can be observed by listening for [`Self::on_set_name`] callbacks. - fn set_name(&self, name: String) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `set_name`. - /// - /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] - /// to determine the reducer's status. - /// - /// The returned [`SetNameCallbackId`] can be passed to [`Self::remove_on_set_name`] - /// to cancel the callback. - fn on_set_name( - &self, - callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, - ) -> SetNameCallbackId; - /// Cancel a callback previously registered by [`Self::on_set_name`], - /// causing it not to run in the future. - fn remove_on_set_name(&self, callback: SetNameCallbackId); -} - -impl set_name for super::RemoteReducers { - fn set_name(&self, name: String) -> __sdk::Result<()> { - self.imp.call_reducer("set_name", SetNameArgs { name }) - } - fn on_set_name( - &self, - mut callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static, - ) -> SetNameCallbackId { - SetNameCallbackId(self.imp.on_reducer( - "set_name", - Box::new(move |ctx: &super::ReducerEventContext| { - #[allow(irrefutable_let_patterns)] - let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::SetName { name }, - .. - }, - .. - } = ctx - else { - unreachable!() - }; - callback(ctx, name) - }), - )) - } - fn remove_on_set_name(&self, callback: SetNameCallbackId) { - self.imp.remove_on_reducer("set_name", callback.0) - } -} - -#[allow(non_camel_case_types)] -#[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `set_name`. -/// -/// Implemented for [`super::SetReducerFlags`]. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_set_name { - /// Set the call-reducer flags for the reducer `set_name` to `flags`. - /// - /// This type is currently unstable and may be removed without a major version bump. - fn set_name(&self, flags: __ws::CallReducerFlags); -} - -impl set_flags_for_set_name for super::SetReducerFlags { - fn set_name(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("set_name", flags); - } -} diff --git a/jong/src/stdb/setup_game_reducer.rs b/jong/src/stdb/shuffle_deal_reducer.rs similarity index 54% rename from jong/src/stdb/setup_game_reducer.rs rename to jong/src/stdb/shuffle_deal_reducer.rs index 3380b89..06b1b23 100644 --- a/jong/src/stdb/setup_game_reducer.rs +++ b/jong/src/stdb/shuffle_deal_reducer.rs @@ -6,68 +6,68 @@ 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 SetupGameArgs { +pub(super) struct ShuffleDealArgs { pub lobby_id: u32, } -impl From for super::Reducer { - fn from(args: SetupGameArgs) -> Self { - Self::SetupGame { +impl From for super::Reducer { + fn from(args: ShuffleDealArgs) -> Self { + Self::ShuffleDeal { lobby_id: args.lobby_id, } } } -impl __sdk::InModule for SetupGameArgs { +impl __sdk::InModule for ShuffleDealArgs { type Module = super::RemoteModule; } -pub struct SetupGameCallbackId(__sdk::CallbackId); +pub struct ShuffleDealCallbackId(__sdk::CallbackId); #[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `setup_game`. +/// Extension trait for access to the reducer `shuffle_deal`. /// /// Implemented for [`super::RemoteReducers`]. -pub trait setup_game { - /// Request that the remote module invoke the reducer `setup_game` to run as soon as possible. +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_setup_game`] callbacks. - fn setup_game(&self, lobby_id: u32) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `setup_game`. + /// 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 [`SetupGameCallbackId`] can be passed to [`Self::remove_on_setup_game`] + /// The returned [`ShuffleDealCallbackId`] can be passed to [`Self::remove_on_shuffle_deal`] /// to cancel the callback. - fn on_setup_game( + fn on_shuffle_deal( &self, callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static, - ) -> SetupGameCallbackId; - /// Cancel a callback previously registered by [`Self::on_setup_game`], + ) -> ShuffleDealCallbackId; + /// Cancel a callback previously registered by [`Self::on_shuffle_deal`], /// causing it not to run in the future. - fn remove_on_setup_game(&self, callback: SetupGameCallbackId); + fn remove_on_shuffle_deal(&self, callback: ShuffleDealCallbackId); } -impl setup_game for super::RemoteReducers { - fn setup_game(&self, lobby_id: u32) -> __sdk::Result<()> { +impl shuffle_deal for super::RemoteReducers { + fn shuffle_deal(&self, lobby_id: u32) -> __sdk::Result<()> { self.imp - .call_reducer("setup_game", SetupGameArgs { lobby_id }) + .call_reducer("shuffle_deal", ShuffleDealArgs { lobby_id }) } - fn on_setup_game( + fn on_shuffle_deal( &self, mut callback: impl FnMut(&super::ReducerEventContext, &u32) + Send + 'static, - ) -> SetupGameCallbackId { - SetupGameCallbackId(self.imp.on_reducer( - "setup_game", + ) -> 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::SetupGame { lobby_id }, + reducer: super::Reducer::ShuffleDeal { lobby_id }, .. }, .. @@ -79,27 +79,27 @@ impl setup_game for super::RemoteReducers { }), )) } - fn remove_on_setup_game(&self, callback: SetupGameCallbackId) { - self.imp.remove_on_reducer("setup_game", callback.0) + 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 `setup_game`. +/// 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_setup_game { - /// Set the call-reducer flags for the reducer `setup_game` to `flags`. +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 setup_game(&self, flags: __ws::CallReducerFlags); + fn shuffle_deal(&self, flags: __ws::CallReducerFlags); } -impl set_flags_for_setup_game for super::SetReducerFlags { - fn setup_game(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("setup_game", flags); +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); } } diff --git a/jong/src/stdb/shuffle_wall_reducer.rs b/jong/src/stdb/shuffle_wall_reducer.rs deleted file mode 100644 index 4f86c24..0000000 --- a/jong/src/stdb/shuffle_wall_reducer.rs +++ /dev/null @@ -1,100 +0,0 @@ -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. - -#![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] -#[sats(crate = __lib)] -pub(super) struct ShuffleWallArgs {} - -impl From for super::Reducer { - fn from(args: ShuffleWallArgs) -> Self { - Self::ShuffleWall - } -} - -impl __sdk::InModule for ShuffleWallArgs { - type Module = super::RemoteModule; -} - -pub struct ShuffleWallCallbackId(__sdk::CallbackId); - -#[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `shuffle_wall`. -/// -/// Implemented for [`super::RemoteReducers`]. -pub trait shuffle_wall { - /// Request that the remote module invoke the reducer `shuffle_wall` to run as soon as possible. - /// - /// This method returns immediately, and errors only if we are unable to send the request. - /// The reducer will run asynchronously in the future, - /// and its status can be observed by listening for [`Self::on_shuffle_wall`] callbacks. - fn shuffle_wall(&self) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `shuffle_wall`. - /// - /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] - /// to determine the reducer's status. - /// - /// The returned [`ShuffleWallCallbackId`] can be passed to [`Self::remove_on_shuffle_wall`] - /// to cancel the callback. - fn on_shuffle_wall( - &self, - callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> ShuffleWallCallbackId; - /// Cancel a callback previously registered by [`Self::on_shuffle_wall`], - /// causing it not to run in the future. - fn remove_on_shuffle_wall(&self, callback: ShuffleWallCallbackId); -} - -impl shuffle_wall for super::RemoteReducers { - fn shuffle_wall(&self) -> __sdk::Result<()> { - self.imp.call_reducer("shuffle_wall", ShuffleWallArgs {}) - } - fn on_shuffle_wall( - &self, - mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> ShuffleWallCallbackId { - ShuffleWallCallbackId(self.imp.on_reducer( - "shuffle_wall", - Box::new(move |ctx: &super::ReducerEventContext| { - #[allow(irrefutable_let_patterns)] - let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::ShuffleWall {}, - .. - }, - .. - } = ctx - else { - unreachable!() - }; - callback(ctx) - }), - )) - } - fn remove_on_shuffle_wall(&self, callback: ShuffleWallCallbackId) { - self.imp.remove_on_reducer("shuffle_wall", callback.0) - } -} - -#[allow(non_camel_case_types)] -#[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `shuffle_wall`. -/// -/// Implemented for [`super::SetReducerFlags`]. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_shuffle_wall { - /// Set the call-reducer flags for the reducer `shuffle_wall` to `flags`. - /// - /// This type is currently unstable and may be removed without a major version bump. - fn shuffle_wall(&self, flags: __ws::CallReducerFlags); -} - -impl set_flags_for_shuffle_wall for super::SetReducerFlags { - fn shuffle_wall(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("shuffle_wall", flags); - } -} diff --git a/jong/src/stdb/sort_hand_reducer.rs b/jong/src/stdb/sort_hand_reducer.rs deleted file mode 100644 index 5673374..0000000 --- a/jong/src/stdb/sort_hand_reducer.rs +++ /dev/null @@ -1,100 +0,0 @@ -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. - -#![allow(unused, clippy::all)] -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] -#[sats(crate = __lib)] -pub(super) struct SortHandArgs {} - -impl From for super::Reducer { - fn from(args: SortHandArgs) -> Self { - Self::SortHand - } -} - -impl __sdk::InModule for SortHandArgs { - type Module = super::RemoteModule; -} - -pub struct SortHandCallbackId(__sdk::CallbackId); - -#[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `sort_hand`. -/// -/// Implemented for [`super::RemoteReducers`]. -pub trait sort_hand { - /// Request that the remote module invoke the reducer `sort_hand` to run as soon as possible. - /// - /// This method returns immediately, and errors only if we are unable to send the request. - /// The reducer will run asynchronously in the future, - /// and its status can be observed by listening for [`Self::on_sort_hand`] callbacks. - fn sort_hand(&self) -> __sdk::Result<()>; - /// Register a callback to run whenever we are notified of an invocation of the reducer `sort_hand`. - /// - /// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`] - /// to determine the reducer's status. - /// - /// The returned [`SortHandCallbackId`] can be passed to [`Self::remove_on_sort_hand`] - /// to cancel the callback. - fn on_sort_hand( - &self, - callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> SortHandCallbackId; - /// Cancel a callback previously registered by [`Self::on_sort_hand`], - /// causing it not to run in the future. - fn remove_on_sort_hand(&self, callback: SortHandCallbackId); -} - -impl sort_hand for super::RemoteReducers { - fn sort_hand(&self) -> __sdk::Result<()> { - self.imp.call_reducer("sort_hand", SortHandArgs {}) - } - fn on_sort_hand( - &self, - mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static, - ) -> SortHandCallbackId { - SortHandCallbackId(self.imp.on_reducer( - "sort_hand", - Box::new(move |ctx: &super::ReducerEventContext| { - #[allow(irrefutable_let_patterns)] - let super::ReducerEventContext { - event: - __sdk::ReducerEvent { - reducer: super::Reducer::SortHand {}, - .. - }, - .. - } = ctx - else { - unreachable!() - }; - callback(ctx) - }), - )) - } - fn remove_on_sort_hand(&self, callback: SortHandCallbackId) { - self.imp.remove_on_reducer("sort_hand", callback.0) - } -} - -#[allow(non_camel_case_types)] -#[doc(hidden)] -/// Extension trait for setting the call-flags for the reducer `sort_hand`. -/// -/// Implemented for [`super::SetReducerFlags`]. -/// -/// This type is currently unstable and may be removed without a major version bump. -pub trait set_flags_for_sort_hand { - /// Set the call-reducer flags for the reducer `sort_hand` to `flags`. - /// - /// This type is currently unstable and may be removed without a major version bump. - fn sort_hand(&self, flags: __ws::CallReducerFlags); -} - -impl set_flags_for_sort_hand for super::SetReducerFlags { - fn sort_hand(&self, flags: __ws::CallReducerFlags) { - self.imp.set_call_reducer_flags("sort_hand", flags); - } -} diff --git a/jong/src/stdb/view_hand_table.rs b/jong/src/stdb/view_hand_table.rs deleted file mode 100644 index a9927c9..0000000 --- a/jong/src/stdb/view_hand_table.rs +++ /dev/null @@ -1,96 +0,0 @@ -// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE -// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. - -#![allow(unused, clippy::all)] -use super::hand_type::Hand; -use super::tile_type::Tile; -use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; - -/// Table handle for the table `view_hand`. -/// -/// Obtain a handle from the [`ViewHandTableAccess::view_hand`] method on [`super::RemoteTables`], -/// like `ctx.db.view_hand()`. -/// -/// Users are encouraged not to explicitly reference this type, -/// but to directly chain method calls, -/// like `ctx.db.view_hand().on_insert(...)`. -pub struct ViewHandTableHandle<'ctx> { - imp: __sdk::TableHandle, - ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, -} - -#[allow(non_camel_case_types)] -/// Extension trait for access to the table `view_hand`. -/// -/// Implemented for [`super::RemoteTables`]. -pub trait ViewHandTableAccess { - #[allow(non_snake_case)] - /// Obtain a [`ViewHandTableHandle`], which mediates access to the table `view_hand`. - fn view_hand(&self) -> ViewHandTableHandle<'_>; -} - -impl ViewHandTableAccess for super::RemoteTables { - fn view_hand(&self) -> ViewHandTableHandle<'_> { - ViewHandTableHandle { - imp: self.imp.get_table::("view_hand"), - ctx: std::marker::PhantomData, - } - } -} - -pub struct ViewHandInsertCallbackId(__sdk::CallbackId); -pub struct ViewHandDeleteCallbackId(__sdk::CallbackId); - -impl<'ctx> __sdk::Table for ViewHandTableHandle<'ctx> { - type Row = Hand; - type EventContext = super::EventContext; - - fn count(&self) -> u64 { - self.imp.count() - } - fn iter(&self) -> impl Iterator + '_ { - self.imp.iter() - } - - type InsertCallbackId = ViewHandInsertCallbackId; - - fn on_insert( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> ViewHandInsertCallbackId { - ViewHandInsertCallbackId(self.imp.on_insert(Box::new(callback))) - } - - fn remove_on_insert(&self, callback: ViewHandInsertCallbackId) { - self.imp.remove_on_insert(callback.0) - } - - type DeleteCallbackId = ViewHandDeleteCallbackId; - - fn on_delete( - &self, - callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, - ) -> ViewHandDeleteCallbackId { - ViewHandDeleteCallbackId(self.imp.on_delete(Box::new(callback))) - } - - fn remove_on_delete(&self, callback: ViewHandDeleteCallbackId) { - self.imp.remove_on_delete(callback.0) - } -} - -#[doc(hidden)] -pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { - let _table = client_cache.get_or_make_table::("view_hand"); -} - -#[doc(hidden)] -pub(super) fn parse_table_update( - raw_updates: __ws::TableUpdate<__ws::BsatnFormat>, -) -> __sdk::Result<__sdk::TableUpdate> { - __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { - __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") - .with_cause(e) - .into() - }) -} diff --git a/jong/src/stdb/view_player_hand_table.rs b/jong/src/stdb/view_player_hand_table.rs index 37429bd..82cfb91 100644 --- a/jong/src/stdb/view_player_hand_table.rs +++ b/jong/src/stdb/view_player_hand_table.rs @@ -3,6 +3,7 @@ #![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}; diff --git a/justfile b/justfile index c55cca1..0d4b9f7 100644 --- a/justfile +++ b/justfile @@ -2,11 +2,14 @@ set shell := ["nu", "-c"] alias rt := run-tui alias s := spacetime +alias g := spacetime_generate-bindings default: just --list run-tui: + mprocs -s localhost:4050 --ctl $"({c: restart-proc, name: spacetimedb_generate_bindings} | to yaml)" + sleep 3sec cargo run -- run-tui update: @@ -16,5 +19,8 @@ update: spacetime: devenv up -generate-bindings: +spacetime_dev: + spacetime dev --module-bindings-path jong/src/stdb jongline --delete-data=always + +spacetime_generate-bindings: spacetime generate --lang rust --out-dir jong/src/stdb --project-path spacetimedb diff --git a/mprocs.log b/mprocs.log new file mode 100644 index 0000000..b8bf64f --- /dev/null +++ b/mprocs.log @@ -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 diff --git a/spacetimedb/src/game.rs b/spacetimedb/src/game.rs new file mode 100644 index 0000000..1266e64 --- /dev/null +++ b/spacetimedb/src/game.rs @@ -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()) + } +} diff --git a/spacetimedb/src/game/hand.rs b/spacetimedb/src/game/hand.rs new file mode 100644 index 0000000..546ad66 --- /dev/null +++ b/spacetimedb/src/game/hand.rs @@ -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 { + 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!() +// } diff --git a/spacetimedb/src/game/wall.rs b/spacetimedb/src/game/wall.rs new file mode 100644 index 0000000..dca40d4 --- /dev/null +++ b/spacetimedb/src/game/wall.rs @@ -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 { + let mut rng = ctx.rng(); + let mut wall = tiles(); + wall.shuffle(&mut rng); + + wall +} diff --git a/spacetimedb/src/lib.rs b/spacetimedb/src/lib.rs index efd08f2..e1669d6 100644 --- a/spacetimedb/src/lib.rs +++ b/spacetimedb/src/lib.rs @@ -1,83 +1,13 @@ use log::{debug, info}; use spacetimedb::{ - Identity, ReducerContext, Table, ViewContext, rand::seq::SliceRandom, reducer, table, view, + ReducerContext, Table, ViewContext, rand::seq::SliceRandom, reducer, table, view, }; +use crate::tables::*; use jong_types::*; -#[derive(Debug)] -#[table(name = player, public)] -pub struct Player { - #[primary_key] - identity: Identity, - - #[auto_inc] - #[index(direct)] - #[unique] - id: u32, - - name: Option, - - #[index(btree)] - lobby_id: u32, -} - -#[table(name = bot)] -pub struct Bot { - #[primary_key] - #[auto_inc] - id: u32, - - #[index(btree)] - lobby_id: u32, -} - -#[derive(Debug, Clone, Copy)] -#[table(name = lobby, public)] -pub struct Lobby { - #[primary_key] - #[auto_inc] - id: u32, - - #[index(direct)] - #[unique] - host_player_id: u32, - - game_state: GameState, -} - -#[table(name = wall)] -pub struct Wall { - // #[auto_inc] - // id: u32, - #[primary_key] - // #[index(direct)] - // #[unique] - lobby_id: u32, - - tiles: Vec, -} - -#[table(name = hand)] -pub struct Hand { - #[primary_key] - player_identity: Identity, - - tiles: Vec, -} - -#[table(name = bothand)] -pub struct BotHand { - #[primary_key] - bot_id: u32, - - tiles: Vec, -} - -#[table(name = pond, public)] -pub struct Pond { - tiles: Vec, -} +mod game; +mod tables; #[reducer(client_connected)] pub fn login_or_add_player(ctx: &ReducerContext) { @@ -89,6 +19,8 @@ pub fn login_or_add_player(ctx: &ReducerContext) { id: 0, name: None, lobby_id: 0, + hand_id: 0, + pond_id: 0, }) { info!("added player: {:?}", player); } else { @@ -97,117 +29,6 @@ pub fn login_or_add_player(ctx: &ReducerContext) { } } -#[reducer] -pub fn join_or_create_lobby(ctx: &ReducerContext, mut lobby_id: u32) -> Result<(), String> { - let mut player = ctx - .db - .player() - .identity() - .find(ctx.sender) - .ok_or(format!("cannot find player {}", ctx.sender))?; - - if lobby_id == 0 { - let lobby = ctx.db.lobby().insert(Lobby { - id: 0, - host_player_id: player.id, - game_state: GameState::None, - }); - info!("created lobby: {:?}", lobby); - - lobby_id = lobby.id; - } - - player.lobby_id = lobby_id; - - let player = ctx.db.player().identity().update(player); - - info!("player {} joined lobby {}", player.id, lobby_id); - Ok(()) -} - -#[reducer] -pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> { - if lobby_id == 0 { - Err("cannot add a bot without a lobby".into()) - } else if let Some(lobby) = ctx.db.lobby().id().find(lobby_id) - && (ctx.db.player().lobby_id().filter(lobby_id).count() - + ctx.db.bot().lobby_id().filter(lobby_id).count() - <= 4) - { - let bot = ctx.db.bot().insert(Bot { id: 0, lobby_id }); - info!("added bot {} to lobby {}", bot.id, lobby_id); - Ok(()) - } else { - Err("lobby doesn't exist".into()) - } -} - -#[reducer] -pub fn setup_game(ctx: &ReducerContext, lobby_id: u32) { - debug!("lobby_id: {lobby_id}"); - let mut lobby = ctx.db.lobby().id().find(lobby_id).unwrap(); - lobby.game_state = GameState::Setup; - - ctx.db.lobby().id().update(lobby); - - let tiles = new_shuffled_wall(ctx); - ctx.db.wall().insert(Wall { - // id: 0, - lobby_id, - tiles, - }); - - lobby.game_state = GameState::Deal; - ctx.db.lobby().id().update(lobby); - - deal_hands(ctx, lobby_id); - lobby.game_state = GameState::Play; - ctx.db.lobby().id().update(lobby); -} - -pub fn new_shuffled_wall(ctx: &ReducerContext) -> Vec { - let mut rng = ctx.rng(); - let mut wall = tiles(); - wall.shuffle(&mut rng); - - wall -} - -pub fn deal_hands(ctx: &ReducerContext, lobby_id: u32) { - let players = ctx.db.player().lobby_id().filter(lobby_id); - let bots = ctx.db.bot().lobby_id().filter(lobby_id); - - let mut wall = ctx.db.wall().lobby_id().find(lobby_id).unwrap(); - - // FIXME rectify deal orders - for player in players { - let tiles = wall.tiles.split_off(wall.tiles.len() - 13); - wall = ctx.db.wall().lobby_id().update(wall); - ctx.db.hand().insert(Hand { - player_identity: player.identity, - tiles, - }); - } - for bot in bots { - let tiles = wall.tiles.split_off(wall.tiles.len() - 13); - wall = ctx.db.wall().lobby_id().update(wall); - ctx.db.bothand().insert(BotHand { - bot_id: bot.id, - tiles, - }); - } -} - -#[view(name = view_player_hand, public)] -pub fn view_player_hand(ctx: &ViewContext) -> Option { - ctx.db.hand().player_identity().find(ctx.sender) -} - -#[reducer] -pub fn sort_hand(ctx: &ReducerContext) { - todo!() -} - // #[reducer(init)] // pub fn init(_ctx: &ReducerContext) { // // Called when the module is initially published diff --git a/spacetimedb/src/tables.rs b/spacetimedb/src/tables.rs new file mode 100644 index 0000000..c53daf7 --- /dev/null +++ b/spacetimedb/src/tables.rs @@ -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, + + #[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, + + pub game_state: GameState, +} + +#[table(name = wall)] +pub struct Wall { + #[primary_key] + pub lobby_id: u32, + + pub tiles: Vec, +} + +#[table(name = hand)] +pub struct Hand { + #[primary_key] + #[auto_inc] + pub id: u32, + + pub owner: PlayerOrBot, + + pub sort: bool, + pub tiles: Vec, +} + +#[table(name = pond, public)] +pub struct Pond { + #[primary_key] + #[auto_inc] + pub id: u32, + + pub owner: PlayerOrBot, + + pub tiles: Vec, +}