Update the build environment and some architectural elements of the Kifu app #210
|
@ -120,6 +120,17 @@ version = "1.0.75"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"event-listener 2.5.3",
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "2.1.1"
|
||||
|
@ -133,6 +144,126 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-executor"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c"
|
||||
dependencies = [
|
||||
"async-lock 3.3.0",
|
||||
"async-task",
|
||||
"concurrent-queue",
|
||||
"fastrand 2.0.1",
|
||||
"futures-lite 2.2.0",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-global-executor"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c"
|
||||
dependencies = [
|
||||
"async-channel 2.1.1",
|
||||
"async-executor",
|
||||
"async-io 2.3.1",
|
||||
"async-lock 3.3.0",
|
||||
"blocking",
|
||||
"futures-lite 2.2.0",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-io"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af"
|
||||
dependencies = [
|
||||
"async-lock 2.8.0",
|
||||
"autocfg 1.1.0",
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"futures-lite 1.13.0",
|
||||
"log 0.4.20",
|
||||
"parking",
|
||||
"polling 2.8.0",
|
||||
"rustix 0.37.27",
|
||||
"slab",
|
||||
"socket2 0.4.10",
|
||||
"waker-fn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-io"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f97ab0c5b00a7cdbe5a371b9a782ee7be1316095885c8a4ea1daf490eb0ef65"
|
||||
dependencies = [
|
||||
"async-lock 3.3.0",
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"futures-io",
|
||||
"futures-lite 2.2.0",
|
||||
"parking",
|
||||
"polling 3.4.0",
|
||||
"rustix 0.38.28",
|
||||
"slab",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-lock"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b"
|
||||
dependencies = [
|
||||
"event-listener 2.5.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-lock"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b"
|
||||
dependencies = [
|
||||
"event-listener 4.0.1",
|
||||
"event-listener-strategy",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-std"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d"
|
||||
dependencies = [
|
||||
"async-channel 1.9.0",
|
||||
"async-global-executor",
|
||||
"async-io 1.13.0",
|
||||
"async-lock 2.8.0",
|
||||
"crossbeam-utils",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-lite 1.13.0",
|
||||
"gloo-timers",
|
||||
"kv-log-macro",
|
||||
"log 0.4.20",
|
||||
"memchr",
|
||||
"once_cell",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
"wasm-bindgen-futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-task"
|
||||
version = "4.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.77"
|
||||
|
@ -153,6 +284,12 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic-waker"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||
|
||||
[[package]]
|
||||
name = "atomic-write-file"
|
||||
version = "0.1.2"
|
||||
|
@ -275,6 +412,22 @@ dependencies = [
|
|||
"generic-array 0.14.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blocking"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118"
|
||||
dependencies = [
|
||||
"async-channel 2.1.1",
|
||||
"async-lock 3.3.0",
|
||||
"async-task",
|
||||
"fastrand 2.0.1",
|
||||
"futures-io",
|
||||
"futures-lite 2.2.0",
|
||||
"piper",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "build_html"
|
||||
version = "2.4.0"
|
||||
|
@ -872,6 +1025,15 @@ dependencies = [
|
|||
"zune-inflate",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.0.1"
|
||||
|
@ -938,7 +1100,7 @@ checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6"
|
|||
name = "fitnesstrax"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-channel 2.1.1",
|
||||
"async-trait",
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
|
@ -1138,6 +1300,34 @@ version = "0.3.29"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
|
||||
dependencies = [
|
||||
"fastrand 1.9.0",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"memchr",
|
||||
"parking",
|
||||
"pin-project-lite",
|
||||
"waker-fn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba"
|
||||
dependencies = [
|
||||
"fastrand 2.0.1",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"parking",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.29"
|
||||
|
@ -1394,6 +1584,18 @@ dependencies = [
|
|||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo-timers"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gm-control-panel"
|
||||
version = "0.1.0"
|
||||
|
@ -1765,7 +1967,7 @@ dependencies = [
|
|||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"socket2 0.5.5",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
|
@ -1902,6 +2104,15 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "intl-memoizer"
|
||||
version = "0.5.1"
|
||||
|
@ -1921,6 +2132,17 @@ dependencies = [
|
|||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.9.0"
|
||||
|
@ -1950,7 +2172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"rustix",
|
||||
"rustix 0.38.28",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
|
@ -2000,6 +2222,7 @@ dependencies = [
|
|||
name = "kifu-core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"chrono",
|
||||
"config",
|
||||
"config-derive",
|
||||
|
@ -2009,13 +2232,14 @@ dependencies = [
|
|||
"serde_json",
|
||||
"sgf",
|
||||
"thiserror",
|
||||
"typeshare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kifu-gtk"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-channel 2.1.1",
|
||||
"async-std",
|
||||
"cairo-rs",
|
||||
"gio",
|
||||
"glib",
|
||||
|
@ -2029,6 +2253,15 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kv-log-macro"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
|
||||
dependencies = [
|
||||
"log 0.4.20",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "language-tags"
|
||||
version = "0.2.2"
|
||||
|
@ -2105,6 +2338,12 @@ dependencies = [
|
|||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.12"
|
||||
|
@ -2135,6 +2374,9 @@ name = "log"
|
|||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
dependencies = [
|
||||
"value-bag",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logger"
|
||||
|
@ -2687,6 +2929,17 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "piper"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4"
|
||||
dependencies = [
|
||||
"atomic-waker",
|
||||
"fastrand 2.0.1",
|
||||
"futures-io",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs1"
|
||||
version = "0.7.5"
|
||||
|
@ -2748,6 +3001,36 @@ dependencies = [
|
|||
"miniz_oxide 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"libc",
|
||||
"log 0.4.20",
|
||||
"pin-project-lite",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30054e72317ab98eddd8561db0f6524df3367636884b7b21b703e4b280a84a14"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"pin-project-lite",
|
||||
"rustix 0.38.28",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
|
@ -3197,6 +3480,20 @@ dependencies = [
|
|||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.37.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys 0.3.8",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.28"
|
||||
|
@ -3206,7 +3503,7 @@ dependencies = [
|
|||
"bitflags 2.4.1",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"linux-raw-sys 0.4.12",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
|
@ -3466,6 +3763,16 @@ version = "1.11.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.5.5"
|
||||
|
@ -3810,9 +4117,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"fastrand 2.0.1",
|
||||
"redox_syscall",
|
||||
"rustix",
|
||||
"rustix 0.38.28",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
|
@ -3953,7 +4260,7 @@ dependencies = [
|
|||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"socket2 0.5.5",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
@ -4339,6 +4646,12 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "value-bag"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "126e423afe2dd9ac52142e7e9d5ce4135d7e13776c529d27fd6bc49f19e3280b"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
|
@ -4384,6 +4697,12 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "waker-fn"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690"
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.1"
|
||||
|
|
30
Makefile
30
Makefile
|
@ -1,30 +0,0 @@
|
|||
|
||||
all: test bin
|
||||
|
||||
test: kifu-core/test-oneshot sgf/test-oneshot
|
||||
|
||||
bin: kifu-gtk
|
||||
|
||||
kifu-core/dev:
|
||||
cd kifu/core && make test
|
||||
|
||||
kifu-core/test:
|
||||
cd kifu/core && make test
|
||||
|
||||
kifu-core/test-oneshot:
|
||||
cd kifu/core && make test-oneshot
|
||||
|
||||
kifu-gtk:
|
||||
cd kifu/gtk && make release
|
||||
|
||||
kifu-gtk/dev:
|
||||
cd kifu/gtk && make dev
|
||||
|
||||
kifu-pwa:
|
||||
cd kifu/pwa && make release
|
||||
|
||||
kifu-pwa/dev:
|
||||
pushd kifu/pwa && make dev
|
||||
|
||||
kifu-pwa/server:
|
||||
pushd kifu/pwa && make server
|
73
build.sh
73
build.sh
|
@ -1,73 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RUST_ALL_TARGETS=(
|
||||
"changeset"
|
||||
"config"
|
||||
"config-derive"
|
||||
"coordinates"
|
||||
"cyberpunk-splash"
|
||||
"dashboard"
|
||||
"emseries"
|
||||
"file-service"
|
||||
"fitnesstrax"
|
||||
"fluent-ergonomics"
|
||||
"geo-types"
|
||||
"gm-control-panel"
|
||||
"hex-grid"
|
||||
"ifc"
|
||||
"kifu-core"
|
||||
"kifu-gtk"
|
||||
"memorycache"
|
||||
"nom-training"
|
||||
"result-extended"
|
||||
"screenplay"
|
||||
"sgf"
|
||||
"tree"
|
||||
)
|
||||
|
||||
build_rust_targets() {
|
||||
local CMD=$1
|
||||
local TARGETS=${@/$CMD}
|
||||
|
||||
for target in $TARGETS; do
|
||||
MODULE=$target CMD=$CMD ./builders/rust.sh
|
||||
done
|
||||
}
|
||||
|
||||
build_dist() {
|
||||
local TARGETS=${@/$CMD}
|
||||
|
||||
for target in $TARGETS; do
|
||||
if [ -f $target/dist.sh ]; then
|
||||
build_rust_targets release ${TARGETS[*]}
|
||||
cd $target && ./dist.sh
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
export CARGO=`which cargo`
|
||||
|
||||
if [ -z "${TARGET-}" ]; then
|
||||
TARGET="all"
|
||||
fi
|
||||
|
||||
if [ -z "${CMD-}" ]; then
|
||||
CMD="test release"
|
||||
fi
|
||||
|
||||
if [ "${CMD}" == "clean" ]; then
|
||||
cargo clean
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for cmd in $CMD; do
|
||||
if [ "${CMD}" == "dist" ]; then
|
||||
build_dist $TARGET
|
||||
elif [ "${TARGET}" == "all" ]; then
|
||||
build_rust_targets $cmd ${RUST_ALL_TARGETS[*]}
|
||||
else
|
||||
build_rust_targets $cmd $TARGET
|
||||
fi
|
||||
done
|
|
@ -1,41 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [ ! -z "$MODULE" ]; then
|
||||
MODULE="-p $MODULE"
|
||||
fi
|
||||
|
||||
if [ -z "${PARAMS-}" ]; then
|
||||
PARAMS=""
|
||||
fi
|
||||
|
||||
case $CMD in
|
||||
build)
|
||||
$CARGO build $MODULE $PARAMS
|
||||
;;
|
||||
lint)
|
||||
$CARGO clippy $MODULE $PARAMS -- -Dwarnings
|
||||
;;
|
||||
test)
|
||||
$CARGO test $MODULE $PARAMS
|
||||
;;
|
||||
run)
|
||||
$CARGO run $MODULE $PARAMS
|
||||
;;
|
||||
release)
|
||||
$CARGO clippy $MODULE $PARAMS -- -Dwarnings
|
||||
$CARGO build --release $MODULE $PARAMS
|
||||
$CARGO test --release $MODULE $PARAMS
|
||||
;;
|
||||
clean)
|
||||
$CARGO clean $MODULE
|
||||
;;
|
||||
"")
|
||||
echo "No command specified. Use build | lint | test | run | release | clean"
|
||||
;;
|
||||
*)
|
||||
echo "$CMD is unknown. Use build | lint | test | run | release | clean"
|
||||
;;
|
||||
esac
|
||||
|
|
@ -70,6 +70,7 @@
|
|||
|
||||
dashboard = attrs: { nativeBuildInputs = gtkNativeInputs; };
|
||||
fitnesstrax = import ./fitnesstrax/app/override.nix { gtkNativeInputs = gtkNativeInputs; };
|
||||
kifu-gtk = import ./kifu/gtk/override.nix { gtkNativeInputs = gtkNativeInputs; };
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -83,6 +84,7 @@
|
|||
dashboard = cargo_nix.workspaceMembers.dashboard.build;
|
||||
file-service = cargo_nix.workspaceMembers.file-service.build;
|
||||
fitnesstrax = cargo_nix.workspaceMembers.fitnesstrax.build;
|
||||
kifu-gtk = cargo_nix.workspaceMembers.kifu-gtk.build;
|
||||
|
||||
all = pkgs.symlinkJoin {
|
||||
name = "all";
|
||||
|
@ -91,6 +93,7 @@
|
|||
dashboard
|
||||
file-service
|
||||
fitnesstrax
|
||||
kifu-gtk
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
SOURCES = $(shell find ../core -name "*.rs")
|
||||
dist/index.ts: $(SOURCES)
|
||||
mkdir -p dist
|
||||
typeshare ../core --lang=typescript --output-file=dist/index.ts
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"name": "core-types",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"types": "dist/index.ts",
|
||||
"main": "dist/index.ts",
|
||||
"scripts": {
|
||||
"build": "make",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Savanni D'Gerinel <savanni@luminescent-dreams.com>",
|
||||
"license": "GPL-3.0-or-later"
|
||||
}
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
async-std = { version = "1" }
|
||||
chrono = { version = "0.4" }
|
||||
config = { path = "../../config" }
|
||||
config-derive = { path = "../../config-derive" }
|
||||
|
@ -14,7 +15,6 @@ grid = { version = "0.9" }
|
|||
serde_json = { version = "1" }
|
||||
serde = { version = "1", features = [ "derive" ] }
|
||||
thiserror = { version = "1" }
|
||||
typeshare = { version = "1" }
|
||||
|
||||
[dev-dependencies]
|
||||
cool_asserts = { version = "2" }
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
use crate::{
|
||||
database::Database,
|
||||
types::{AppState, Config, ConfigOption, DatabasePath, GameState, Player, Rank},
|
||||
ui::{configuration, home, playing_field, ConfigurationView, HomeView, PlayingFieldView},
|
||||
};
|
||||
use async_std::channel::{Receiver, Sender};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
path::PathBuf,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
use typeshare::typeshare;
|
||||
|
||||
pub trait Observable<T> {
|
||||
fn subscribe(&self) -> Receiver<T>;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
#[serde(tag = "type", content = "content")]
|
||||
pub enum CoreRequest {
|
||||
ChangeSetting(ChangeSettingRequest),
|
||||
CreateGame(CreateGameRequest),
|
||||
|
@ -23,34 +26,28 @@ pub enum CoreRequest {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
#[serde(tag = "type", content = "content")]
|
||||
pub enum ChangeSettingRequest {
|
||||
LibraryPath(String),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct PlayStoneRequest {
|
||||
pub column: u8,
|
||||
pub row: u8,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct CreateGameRequest {
|
||||
pub black_player: PlayerInfoRequest,
|
||||
pub white_player: PlayerInfoRequest,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub enum PlayerInfoRequest {
|
||||
Hotseat(HotseatPlayerRequest),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct HotseatPlayerRequest {
|
||||
pub name: String,
|
||||
pub rank: Option<String>,
|
||||
|
@ -66,8 +63,6 @@ impl From<HotseatPlayerRequest> for Player {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
#[serde(tag = "type", content = "content")]
|
||||
pub enum CoreResponse {
|
||||
ConfigurationView(ConfigurationView),
|
||||
HomeView(HomeView),
|
||||
|
@ -75,37 +70,48 @@ pub enum CoreResponse {
|
|||
UpdatedConfigurationView(ConfigurationView),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CoreApp {
|
||||
config: Arc<RwLock<Config>>,
|
||||
state: Arc<RwLock<AppState>>,
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum CoreNotification {
|
||||
BoardUpdated,
|
||||
}
|
||||
|
||||
impl CoreApp {
|
||||
pub fn new(config_path: std::path::PathBuf) -> Self {
|
||||
let config = Config::from_path(config_path).expect("configuration to open");
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Core {
|
||||
// config: Arc<RwLock<Config>>,
|
||||
// state: Arc<RwLock<AppState>>,
|
||||
database: Arc<RwLock<Option<Database>>>,
|
||||
subscribers: Arc<RwLock<Vec<Sender<CoreNotification>>>>,
|
||||
}
|
||||
|
||||
let db_path: DatabasePath = config.get().unwrap();
|
||||
let state = Arc::new(RwLock::new(AppState::new(db_path)));
|
||||
impl Core {
|
||||
pub fn new(_config: Config) -> Self {
|
||||
// let config = Config::from_path(config_path).expect("configuration to open");
|
||||
|
||||
// let state = Arc::new(RwLock::new(AppState::new(db_path)));
|
||||
|
||||
Self {
|
||||
config: Arc::new(RwLock::new(config)),
|
||||
state,
|
||||
// config: Arc::new(RwLock::new(config)),
|
||||
// state,
|
||||
database: Arc::new(RwLock::new(None)),
|
||||
subscribers: Arc::new(RwLock::new(vec![])),
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub async fn dispatch(&self, request: CoreRequest) -> CoreResponse {
|
||||
match request {
|
||||
CoreRequest::ChangeSetting(request) => match request {
|
||||
ChangeSettingRequest::LibraryPath(path) => {
|
||||
let mut config = self.config.write().unwrap();
|
||||
config.set(ConfigOption::DatabasePath(DatabasePath(PathBuf::from(
|
||||
path,
|
||||
))));
|
||||
CoreResponse::UpdatedConfigurationView(configuration(&config))
|
||||
// let mut config = self.config.write().unwrap();
|
||||
// config.set(ConfigOption::DatabasePath(DatabasePath(PathBuf::from(
|
||||
// path,
|
||||
// ))));
|
||||
// CoreResponse::UpdatedConfigurationView(configuration(&config))
|
||||
unimplemented!()
|
||||
}
|
||||
},
|
||||
CoreRequest::CreateGame(create_request) => {
|
||||
/*
|
||||
let mut app_state = self.state.write().unwrap();
|
||||
let white_player = {
|
||||
match create_request.white_player {
|
||||
|
@ -124,30 +130,48 @@ impl CoreApp {
|
|||
});
|
||||
let game_state = app_state.game.as_ref().unwrap();
|
||||
CoreResponse::PlayingFieldView(playing_field(game_state))
|
||||
*/
|
||||
unimplemented!()
|
||||
}
|
||||
CoreRequest::Home => {
|
||||
CoreResponse::HomeView(home(self.state.read().unwrap().database.all_games()))
|
||||
// CoreResponse::HomeView(home(self.state.read().unwrap().database.all_games()))
|
||||
unimplemented!()
|
||||
}
|
||||
CoreRequest::OpenConfiguration => {
|
||||
CoreResponse::ConfigurationView(configuration(&self.config.read().unwrap()))
|
||||
// CoreResponse::ConfigurationView(configuration(&self.config.read().unwrap()))
|
||||
unimplemented!()
|
||||
}
|
||||
CoreRequest::PlayingField => {
|
||||
let app_state = self.state.read().unwrap();
|
||||
let game = app_state.game.as_ref().unwrap();
|
||||
CoreResponse::PlayingFieldView(playing_field(game))
|
||||
// let app_state = self.state.read().unwrap();
|
||||
// let game = app_state.game.as_ref().unwrap();
|
||||
// CoreResponse::PlayingFieldView(playing_field(game))
|
||||
unimplemented!()
|
||||
}
|
||||
CoreRequest::PlayStone(request) => {
|
||||
let mut app_state = self.state.write().unwrap();
|
||||
app_state.place_stone(request);
|
||||
// let mut app_state = self.state.write().unwrap();
|
||||
// app_state.place_stone(request);
|
||||
|
||||
let game = app_state.game.as_ref().unwrap();
|
||||
CoreResponse::PlayingFieldView(playing_field(game))
|
||||
// let game = app_state.game.as_ref().unwrap();
|
||||
// CoreResponse::PlayingFieldView(playing_field(game))
|
||||
unimplemented!()
|
||||
}
|
||||
CoreRequest::StartGame => {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
pub async fn run(&self) {}
|
||||
// pub async fn run(&self) {}
|
||||
}
|
||||
|
||||
impl Observable<CoreNotification> for Core {
|
||||
fn subscribe(&self) -> Receiver<CoreNotification> {
|
||||
let mut subscribers = self.subscribers.write().unwrap();
|
||||
|
||||
let (sender, receiver) = async_std::channel::unbounded();
|
||||
subscribers.push(sender);
|
||||
|
||||
receiver
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,12 @@ use crate::{BoardError, Color, Size};
|
|||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Board {
|
||||
pub struct Goban {
|
||||
pub size: Size,
|
||||
pub groups: Vec<Group>,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Board {
|
||||
impl std::fmt::Display for Goban {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
write!(f, " ")?;
|
||||
// for c in 'A'..'U' {
|
||||
|
@ -31,7 +31,7 @@ impl std::fmt::Display for Board {
|
|||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Board {
|
||||
impl PartialEq for Goban {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
if self.size != other.size {
|
||||
return false;
|
||||
|
@ -51,7 +51,7 @@ impl PartialEq for Board {
|
|||
}
|
||||
}
|
||||
|
||||
impl Board {
|
||||
impl Goban {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
size: Size {
|
||||
|
@ -77,7 +77,7 @@ pub struct Coordinate {
|
|||
pub row: u8,
|
||||
}
|
||||
|
||||
impl Board {
|
||||
impl Goban {
|
||||
pub fn place_stone(mut self, coordinate: Coordinate, color: Color) -> Result<Self, BoardError> {
|
||||
if self.stone(&coordinate).is_some() {
|
||||
return Err(BoardError::InvalidPosition);
|
||||
|
@ -224,8 +224,8 @@ mod test {
|
|||
* A stone placed in a suicidal position is legal if it captures other stones first.
|
||||
*/
|
||||
|
||||
fn with_example_board(test: impl FnOnce(Board)) {
|
||||
let board = Board::from_coordinates(
|
||||
fn with_example_board(test: impl FnOnce(Goban)) {
|
||||
let board = Goban::from_coordinates(
|
||||
vec![
|
||||
(Coordinate { column: 3, row: 3 }, Color::White),
|
||||
(Coordinate { column: 3, row: 4 }, Color::White),
|
||||
|
@ -284,7 +284,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn it_gets_adjacencies_for_coordinate() {
|
||||
let board = Board::new();
|
||||
let board = Goban::new();
|
||||
for column in 0..19 {
|
||||
for row in 0..19 {
|
||||
for coordinate in board.adjacencies(&Coordinate { column, row }) {
|
||||
|
@ -302,7 +302,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn it_counts_individual_liberties() {
|
||||
let board = Board::from_coordinates(
|
||||
let board = Goban::from_coordinates(
|
||||
vec![
|
||||
(Coordinate { column: 3, row: 3 }, Color::White),
|
||||
(Coordinate { column: 0, row: 3 }, Color::White),
|
||||
|
@ -357,7 +357,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn stones_share_liberties() {
|
||||
with_example_board(|board: Board| {
|
||||
with_example_board(|board: Goban| {
|
||||
let test_cases = vec![
|
||||
(
|
||||
board.clone(),
|
||||
|
@ -567,11 +567,11 @@ mod test {
|
|||
#[test]
|
||||
fn validate_group_comparisons() {
|
||||
{
|
||||
let b1 = Board::from_coordinates(
|
||||
let b1 = Goban::from_coordinates(
|
||||
vec![(Coordinate { column: 7, row: 9 }, Color::White)].into_iter(),
|
||||
)
|
||||
.unwrap();
|
||||
let b2 = Board::from_coordinates(
|
||||
let b2 = Goban::from_coordinates(
|
||||
vec![(Coordinate { column: 7, row: 9 }, Color::White)].into_iter(),
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -580,7 +580,7 @@ mod test {
|
|||
}
|
||||
|
||||
{
|
||||
let b1 = Board::from_coordinates(
|
||||
let b1 = Goban::from_coordinates(
|
||||
vec![
|
||||
(Coordinate { column: 7, row: 9 }, Color::White),
|
||||
(Coordinate { column: 8, row: 10 }, Color::White),
|
||||
|
@ -588,7 +588,7 @@ mod test {
|
|||
.into_iter(),
|
||||
)
|
||||
.unwrap();
|
||||
let b2 = Board::from_coordinates(
|
||||
let b2 = Goban::from_coordinates(
|
||||
vec![
|
||||
(Coordinate { column: 8, row: 10 }, Color::White),
|
||||
(Coordinate { column: 7, row: 9 }, Color::White),
|
||||
|
@ -603,7 +603,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn two_boards_can_be_compared() {
|
||||
let board = Board::from_coordinates(
|
||||
let board = Goban::from_coordinates(
|
||||
vec![
|
||||
(Coordinate { column: 7, row: 9 }, Color::White),
|
||||
(Coordinate { column: 8, row: 8 }, Color::White),
|
||||
|
|
|
@ -2,8 +2,8 @@ extern crate config_derive;
|
|||
|
||||
mod api;
|
||||
pub use api::{
|
||||
ChangeSettingRequest, CoreApp, CoreRequest, CoreResponse, CreateGameRequest,
|
||||
HotseatPlayerRequest, PlayerInfoRequest,
|
||||
ChangeSettingRequest, Core, CoreNotification, CoreRequest, CoreResponse, CreateGameRequest,
|
||||
HotseatPlayerRequest, Observable, PlayerInfoRequest,
|
||||
};
|
||||
|
||||
mod board;
|
||||
|
@ -12,6 +12,6 @@ pub use board::*;
|
|||
mod database;
|
||||
|
||||
mod types;
|
||||
pub use types::{BoardError, Color, Rank, Size};
|
||||
pub use types::{BoardError, Color, Config, ConfigOption, DatabasePath, Player, Rank, Size};
|
||||
|
||||
pub mod ui;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
api::PlayStoneRequest,
|
||||
board::{Board, Coordinate},
|
||||
board::{Coordinate, Goban},
|
||||
database::Database,
|
||||
};
|
||||
use config::define_config;
|
||||
|
@ -8,7 +8,6 @@ use config_derive::ConfigOption;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::{path::PathBuf, time::Duration};
|
||||
use thiserror::Error;
|
||||
use typeshare::typeshare;
|
||||
|
||||
define_config! {
|
||||
DatabasePath(DatabasePath),
|
||||
|
@ -25,6 +24,12 @@ impl std::ops::Deref for DatabasePath {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<String> for DatabasePath {
|
||||
fn from(s: String) -> Self {
|
||||
Self(PathBuf::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, ConfigOption)]
|
||||
pub struct Me(Player);
|
||||
|
||||
|
@ -46,14 +51,12 @@ pub enum BoardError {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub enum Color {
|
||||
Black,
|
||||
White,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct Size {
|
||||
pub width: u8,
|
||||
pub height: u8,
|
||||
|
@ -93,7 +96,6 @@ impl AppState {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub enum Rank {
|
||||
Kyu(u8),
|
||||
Dan(u8),
|
||||
|
@ -126,8 +128,8 @@ pub struct Player {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct GameState {
|
||||
pub board: Board,
|
||||
pub past_positions: Vec<Board>,
|
||||
pub board: Goban,
|
||||
pub past_positions: Vec<Goban>,
|
||||
|
||||
pub conversation: Vec<String>,
|
||||
pub current_player: Color,
|
||||
|
@ -142,7 +144,7 @@ pub struct GameState {
|
|||
impl Default for GameState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
board: Board::new(),
|
||||
board: Goban::new(),
|
||||
past_positions: vec![],
|
||||
conversation: vec![],
|
||||
current_player: Color::Black,
|
||||
|
@ -194,7 +196,7 @@ mod test {
|
|||
#[test]
|
||||
fn current_player_remains_the_same_after_self_capture() {
|
||||
let mut state = GameState::default();
|
||||
state.board = Board::from_coordinates(
|
||||
state.board = Goban::from_coordinates(
|
||||
vec![
|
||||
(Coordinate { column: 17, row: 0 }, Color::White),
|
||||
(Coordinate { column: 17, row: 1 }, Color::White),
|
||||
|
@ -215,7 +217,7 @@ mod test {
|
|||
#[test]
|
||||
fn ko_rules_are_enforced() {
|
||||
let mut state = GameState::default();
|
||||
state.board = Board::from_coordinates(
|
||||
state.board = Goban::from_coordinates(
|
||||
vec![
|
||||
(Coordinate { column: 7, row: 9 }, Color::White),
|
||||
(Coordinate { column: 8, row: 8 }, Color::White),
|
||||
|
|
|
@ -3,10 +3,8 @@ use crate::{
|
|||
ui::Field,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct ConfigurationView {
|
||||
pub library: Field<()>,
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use sgf::{Game, GameResult, Win};
|
||||
use typeshare::typeshare;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[typeshare]
|
||||
pub struct GamePreviewElement {
|
||||
pub date: String,
|
||||
pub name: String,
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct Menu<T: PartialEq + Eq> {
|
||||
current: Option<T>,
|
||||
options: Vec<T>,
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
|
||||
pub mod game_preview;
|
||||
pub mod menu;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct Action<A> {
|
||||
pub id: String,
|
||||
pub label: String,
|
||||
|
@ -13,7 +11,6 @@ pub struct Action<A> {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct Toggle<A> {
|
||||
pub id: String,
|
||||
pub label: String,
|
||||
|
@ -22,7 +19,6 @@ pub struct Toggle<A> {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct Field<A> {
|
||||
pub id: String,
|
||||
pub label: String,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::ui::{Action, GamePreviewElement};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sgf::Game;
|
||||
use typeshare::typeshare;
|
||||
|
||||
fn rank_strings() -> Vec<String> {
|
||||
vec![
|
||||
|
@ -18,7 +17,6 @@ fn rank_strings() -> Vec<String> {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub enum PlayerElement {
|
||||
Hotseat(HotseatPlayerElement),
|
||||
// Remote(RemotePlayerElement),
|
||||
|
@ -32,7 +30,6 @@ impl Default for PlayerElement {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
|
||||
#[typeshare]
|
||||
pub struct HotseatPlayerElement {
|
||||
pub placeholder: Option<String>,
|
||||
pub default_rank: Option<String>,
|
||||
|
@ -40,15 +37,12 @@ pub struct HotseatPlayerElement {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct RemotePlayerElement {}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct BotPlayerElement {}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct HomeView {
|
||||
pub black_player: PlayerElement,
|
||||
pub white_player: PlayerElement,
|
||||
|
|
|
@ -3,10 +3,8 @@ use crate::{
|
|||
ui::types,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct PlayingFieldView {
|
||||
pub board: types::BoardElement,
|
||||
pub player_card_black: types::PlayerCardElement,
|
||||
|
|
|
@ -1,20 +1,17 @@
|
|||
use crate::types::{Color, Size};
|
||||
use crate::{
|
||||
api::{CoreRequest, PlayStoneRequest},
|
||||
Board, Coordinate,
|
||||
Coordinate, Goban,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct Jitter {
|
||||
pub x: i8,
|
||||
pub y: i8,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct StoneElement {
|
||||
pub color: Color,
|
||||
pub jitter: Jitter,
|
||||
|
@ -32,8 +29,6 @@ impl StoneElement {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
#[serde(tag = "type", content = "content")]
|
||||
pub enum IntersectionElement {
|
||||
Unplayable,
|
||||
Empty(CoreRequest),
|
||||
|
@ -41,7 +36,6 @@ pub enum IntersectionElement {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct BoardElement {
|
||||
pub size: Size,
|
||||
pub spaces: Vec<IntersectionElement>,
|
||||
|
@ -80,8 +74,8 @@ impl BoardElement {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<&Board> for BoardElement {
|
||||
fn from(board: &Board) -> Self {
|
||||
impl From<&Goban> for BoardElement {
|
||||
fn from(board: &Goban) -> Self {
|
||||
let spaces: Vec<IntersectionElement> =
|
||||
(0..board.size.height)
|
||||
.map(|row| {
|
||||
|
@ -114,7 +108,6 @@ impl Default for BoardElement {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct PlayerCardElement {
|
||||
pub color: Color,
|
||||
pub name: String,
|
||||
|
@ -123,11 +116,9 @@ pub struct PlayerCardElement {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct ChatElement {
|
||||
pub messages: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[typeshare]
|
||||
pub struct TextFieldElement {}
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="styles.css" />
|
||||
|
||||
<body>
|
||||
<div class="menu">
|
||||
<ul>
|
||||
<li> <a href="index.html">Index</a> </li>
|
||||
<li> <a href="playing.html">Game Board for playing</a> </li>
|
||||
<li> <a href="database.html">Game database</a> </li>
|
||||
<li> <a href="analysis.html">Game board for analysis</a> </li>
|
||||
<li> Connection management </li>
|
||||
<li> Challenge list </li>
|
||||
<li> Friends list </li>
|
||||
<li> Open challenges </li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="widget">
|
||||
<div> US Go Congress 2023, DDK Tournament, Round 1, Board 25 </div>
|
||||
<div class="game-analysis">
|
||||
<div class="game-analysis__board">
|
||||
<img src="game-screen.jpg" />
|
||||
</div>
|
||||
|
||||
<div class="game-analysis__tree">
|
||||
<div>
|
||||
<img src="game-tree.jpg" />
|
||||
</div>
|
||||
<p> Shoring up the wall. Any chance to capture that group was lost a couple of moves back and Savanni knows it. </p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="game-info">
|
||||
<div class="player-info">
|
||||
<div> Savanni (10k) </div>
|
||||
</div>
|
||||
<div class="player-info">
|
||||
<div> Opal (10k) </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="styles.css" />
|
||||
|
||||
<body>
|
||||
<div class="menu">
|
||||
<ul>
|
||||
<li> <a href="index.html">Index</a> </li>
|
||||
<li> <a href="playing.html">Game Board for playing</a> </li>
|
||||
<li> <a href="database.html">Game database</a> </li>
|
||||
<li> Game board for analysis </li>
|
||||
<li> Connection management </li>
|
||||
<li> Challenge list </li>
|
||||
<li> Friends list </li>
|
||||
<li> Open challenges </li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="widget">
|
||||
<div class="game-filter">
|
||||
<input class="game-filter__term" placeholder="date" />
|
||||
<input class="game-filter__term" placeholder="player name" />
|
||||
<input class="game-filter__term" placeholder="minimum strength" />
|
||||
<input class="game-filter__term" placeholder="maximum strength" />
|
||||
</div>
|
||||
|
||||
<div class="game-database">
|
||||
<div class="game-entry">
|
||||
<a href="analysis.html"><img class="game-entry__icon" src="game-thumbnail.jpg" /></a>
|
||||
<div class="game-entry__info-card">
|
||||
<div class="game-entry__info-row">
|
||||
2016-06-15
|
||||
</div>
|
||||
|
||||
<div class="game-entry__info-row">
|
||||
(B) Alpha Go (w)
|
||||
</div>
|
||||
|
||||
<div class="game-entry__info-row">
|
||||
(W) Lee Sedol
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="game-entry">
|
||||
<img class="game-entry__icon" src="game-thumbnail.jpg" />
|
||||
<div class="game-entry__info-card">
|
||||
<div class="game-entry__info-row">
|
||||
2016-06-15
|
||||
</div>
|
||||
|
||||
<div class="game-entry__info-row">
|
||||
(B) Alpha Go (w)
|
||||
</div>
|
||||
|
||||
<div class="game-entry__info-row">
|
||||
(W) Lee Sedol
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="game-entry">
|
||||
<img class="game-entry__icon" src="game-thumbnail.jpg" />
|
||||
<div class="game-entry__info-card">
|
||||
<div class="game-entry__info-row">
|
||||
2016-06-15
|
||||
</div>
|
||||
|
||||
<div class="game-entry__info-row">
|
||||
(B) Alpha Go (w)
|
||||
</div>
|
||||
|
||||
<div class="game-entry__info-row">
|
||||
(W) Lee Sedol
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="game-entry">
|
||||
<img class="game-entry__icon" src="game-thumbnail.jpg" />
|
||||
<div class="game-entry__info-card">
|
||||
<div class="game-entry__info-row">
|
||||
2016-06-15
|
||||
</div>
|
||||
|
||||
<div class="game-entry__info-row">
|
||||
(B) Alpha Go (w)
|
||||
</div>
|
||||
|
||||
<div class="game-entry__info-row">
|
||||
(W) Lee Sedol
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="game-entry">
|
||||
<img class="game-entry__icon" src="game-thumbnail.jpg" />
|
||||
<div class="game-entry__info-card">
|
||||
<div class="game-entry__info-row">
|
||||
2016-06-15
|
||||
</div>
|
||||
|
||||
<div class="game-entry__info-row">
|
||||
(B) Alpha Go (w)
|
||||
</div>
|
||||
|
||||
<div class="game-entry__info-row">
|
||||
(W) Lee Sedol
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 151 KiB |
Binary file not shown.
Before Width: | Height: | Size: 81 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.9 KiB |
|
@ -1,24 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="styles.css" />
|
||||
|
||||
<body>
|
||||
<div class="menu">
|
||||
<ul>
|
||||
<li> <a href="playing.html">Game Board for playing</a> </li>
|
||||
<li> <a href="database.html">Game database</a> </li>
|
||||
<li> <a href="analysis.html">Game board for analysis</a> </li>
|
||||
<li> Connection management </li>
|
||||
<li> Challenge list </li>
|
||||
<li> Friends list </li>
|
||||
<li> Open challenges </li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="widget">
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,49 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="styles.css" />
|
||||
|
||||
<body>
|
||||
<div class="menu">
|
||||
<ul>
|
||||
<li> <a href="index.html">Index</a> </li>
|
||||
<li> <a href="playing.html">Game Board for playing</a> </li>
|
||||
<li> Game database </li>
|
||||
<li> Game board for analysis </li>
|
||||
<li> Connection management </li>
|
||||
<li> Challenge list </li>
|
||||
<li> Friends list </li>
|
||||
<li> Open challenges </li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="widget">
|
||||
|
||||
<img src="game-screen.jpg" />
|
||||
|
||||
<div class="game-info">
|
||||
<div class="player-info">
|
||||
<div> Savanni (10k) </div> <div> 24:53 </div>
|
||||
</div>
|
||||
<div class="player-info">
|
||||
<div> Opal (10k) </div> <div> 25:00 </div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="chat">
|
||||
<div>
|
||||
<textarea cols="80" rows="25">
|
||||
[22:05] Savanni: oops
|
||||
[22:06] Opal: you know I'll take advantage of that, right?
|
||||
</textarea>
|
||||
</div>
|
||||
<div>
|
||||
<input size="60"></input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -1,270 +0,0 @@
|
|||
(;FF[4]
|
||||
CA[UTF-8]
|
||||
GM[1]
|
||||
DT[2022-02-17]
|
||||
GN[Amika Matĉo]
|
||||
PC[https://online-go.com/review/823151]
|
||||
PB[mearss25]
|
||||
PW[savanni.dgerinel]
|
||||
BR[16k]
|
||||
WR[10k]
|
||||
TM[1500]OT[15 fischer]
|
||||
RE[W+46.5]
|
||||
SZ[19]
|
||||
KM[7.5]
|
||||
RU[AGA]
|
||||
|
||||
;B[pd]SQ[ph]SQ[oi]LB[pi:B]LB[qi:A]SQ[pj]LB[qj:C]
|
||||
;W[dp]
|
||||
;B[dd]
|
||||
;W[qp]
|
||||
;B[ch]
|
||||
;W[np]
|
||||
;B[cl]
|
||||
;W[qf]
|
||||
;B[qh]
|
||||
(;W[of]
|
||||
(;B[nc]
|
||||
;W[oi]
|
||||
;B[pj]
|
||||
;W[md]
|
||||
;B[nk]
|
||||
;W[jd]
|
||||
;B[gc]
|
||||
(;W[jj]
|
||||
;B[mi]
|
||||
;W[mj]
|
||||
;B[lj]
|
||||
;W[nj]
|
||||
;B[ok]
|
||||
;W[li]
|
||||
;B[ki]
|
||||
;W[lh]
|
||||
;B[kj]
|
||||
;W[kh]
|
||||
;B[mk]
|
||||
(;W[pi]
|
||||
;B[qi]
|
||||
;W[ji]
|
||||
;B[ni]
|
||||
;W[oj]
|
||||
;B[nh]
|
||||
;W[mh]
|
||||
;B[oh]
|
||||
;W[ng]
|
||||
;B[ig]
|
||||
;W[qc]
|
||||
;B[pf]
|
||||
;W[pg]
|
||||
;B[ph]
|
||||
;W[pe]
|
||||
;B[qd]
|
||||
;W[od]
|
||||
;B[oc]
|
||||
;W[pc]
|
||||
;B[nd]
|
||||
;W[oe]
|
||||
;B[og]
|
||||
;W[rd]
|
||||
;B[mc]
|
||||
;W[mf]
|
||||
;B[ld]
|
||||
;W[me]
|
||||
;B[jh]
|
||||
;W[cc]
|
||||
;B[cd]
|
||||
;W[dc]
|
||||
;B[ec]
|
||||
;W[eb]
|
||||
;B[fd]
|
||||
;W[fb]
|
||||
;B[gb]
|
||||
;W[bd]
|
||||
;B[be]
|
||||
;W[bc]
|
||||
;B[ad]
|
||||
;W[ce]
|
||||
;B[de]
|
||||
;W[ac]
|
||||
;B[cf]
|
||||
;W[ae]
|
||||
;B[fa]
|
||||
;W[ea]
|
||||
;B[ga]
|
||||
;W[ca]
|
||||
;B[cq]
|
||||
;W[dq]
|
||||
;B[cp]
|
||||
;W[cn]
|
||||
;B[bn]
|
||||
;W[do]
|
||||
;B[cm]
|
||||
;W[cr]
|
||||
;B[co]
|
||||
;W[dn]
|
||||
;B[dm]
|
||||
;W[fn]
|
||||
;B[fm]
|
||||
;W[hn]
|
||||
;B[il]
|
||||
;W[jp]
|
||||
;B[hq]
|
||||
;W[jq]
|
||||
;B[er]
|
||||
;W[dr]
|
||||
;B[fq]
|
||||
;W[ir]
|
||||
;B[io]
|
||||
;W[jm]
|
||||
;B[kn]
|
||||
;W[jn]
|
||||
;B[ho]
|
||||
;W[gn]
|
||||
;B[hr]
|
||||
;W[gp]
|
||||
;B[gr]
|
||||
;W[es]
|
||||
;B[fs]
|
||||
;W[ds]
|
||||
;B[eq]
|
||||
;W[hs]
|
||||
;B[go]
|
||||
;W[fp]
|
||||
;B[en]
|
||||
;W[eo]
|
||||
;B[br]
|
||||
;W[fo]
|
||||
;B[mo]
|
||||
;W[mp]
|
||||
;B[lp]
|
||||
;W[lq]
|
||||
;B[ko]
|
||||
;W[jo]
|
||||
;B[km]
|
||||
;W[ql]
|
||||
;B[pl]
|
||||
;W[pm]
|
||||
;B[om]
|
||||
;W[pn]
|
||||
;B[on]
|
||||
;W[oo]
|
||||
;B[no]
|
||||
;W[op]
|
||||
;B[qk]
|
||||
;W[rl]
|
||||
;B[rk]
|
||||
;W[rn]
|
||||
;B[qg]
|
||||
;W[rf]
|
||||
;B[rg]
|
||||
;W[kf]
|
||||
;B[if]
|
||||
;W[kc]
|
||||
;B[lb]
|
||||
;W[lc]
|
||||
;B[kb]
|
||||
;W[jb]
|
||||
;B[ma]
|
||||
;W[ob]
|
||||
;B[nb]
|
||||
;W[pa]
|
||||
;B[ka]
|
||||
;W[je]
|
||||
;B[ie]
|
||||
;W[id]
|
||||
;B[hd]
|
||||
;W[jl]
|
||||
;B[ii]
|
||||
;W[ik]
|
||||
;B[hk]
|
||||
;W[hl]
|
||||
;B[gl]
|
||||
;W[hm]
|
||||
;B[ij]
|
||||
;W[jk]
|
||||
;B[gm]
|
||||
;W[bf]
|
||||
;B[bg]
|
||||
;W[ce]
|
||||
;B[cg]
|
||||
;W[be]
|
||||
;B[fh]
|
||||
;W[jg]
|
||||
;B[ih]
|
||||
;W[em]
|
||||
;B[el]
|
||||
;W[gk]
|
||||
;B[hj]
|
||||
;W[fl]
|
||||
;B[gj]
|
||||
;W[fk]
|
||||
;B[ek]
|
||||
;W[kp]
|
||||
;B[fj]
|
||||
;W[sl]
|
||||
;B[sk]
|
||||
;W[kk]
|
||||
;B[lk]
|
||||
;W[lo]
|
||||
;B[ln]
|
||||
;W[lp]
|
||||
;B[ll]
|
||||
;W[sf]
|
||||
;B[sg]
|
||||
;W[ib]
|
||||
;B[ic]
|
||||
;W[jc]
|
||||
;B[hc]
|
||||
;W[is]
|
||||
;B[bs]
|
||||
;W[fc]
|
||||
;B[ed]
|
||||
;W[ne]
|
||||
;B[na]
|
||||
;W[oa]
|
||||
;B[qa]
|
||||
;W[pb]
|
||||
;B[rc]
|
||||
;W[qe]
|
||||
;B[ag]
|
||||
;W[jf]
|
||||
;B[pf]
|
||||
;W[kl]
|
||||
;B[mm]
|
||||
;W[pg]
|
||||
;B[]
|
||||
;W[pf]
|
||||
;B[]
|
||||
;W[]
|
||||
)(;W[lk]
|
||||
;B[kk]
|
||||
;W[ll]
|
||||
;B[kl]
|
||||
;W[km]
|
||||
;B[jm]
|
||||
;W[kn]
|
||||
))(;W[mj]
|
||||
))(;B[nd]
|
||||
;W[oh]
|
||||
;B[qk]
|
||||
))(;W[qc]
|
||||
(;B[qd]
|
||||
;W[pc]
|
||||
;B[od]
|
||||
;W[rd]
|
||||
;B[re]
|
||||
;W[rc]
|
||||
;B[rf]
|
||||
;W[nc]
|
||||
;B[me]
|
||||
)(;B[pc]TR[jc]
|
||||
;W[qd]
|
||||
;B[pe]
|
||||
(;W[rf]
|
||||
;B[og]
|
||||
)(;W[pf]
|
||||
;B[of]
|
||||
;W[oe]
|
||||
(;B[ne]
|
||||
)(;B[nf]
|
||||
)))))
|
|
@ -1,44 +0,0 @@
|
|||
body {
|
||||
background: hsl(0 0% 85%);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.menu {
|
||||
border-right: 1px solid black;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.game-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.widget {
|
||||
}
|
||||
|
||||
.game-database {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.game-entry {
|
||||
display: flex;
|
||||
width: 500px;
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
.game-entry__icon {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.game-analysis {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.game-analysis__board {
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
.game-analysis__tree {
|
||||
flex-shrink: 0;
|
||||
}
|
|
@ -1,564 +0,0 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
|
||||
dependencies = [
|
||||
"termcolor",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cxxbridge-flags",
|
||||
"cxxbridge-macro",
|
||||
"link-cplusplus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx-build"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"codespan-reporting",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"scratch",
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-flags"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb"
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-macro"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "grid"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0634107a3a005070dd73e27e74ecb691a94e9e5ba7829f434db7fbf73a6b5c47"
|
||||
dependencies = [
|
||||
"no-std-compat",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
|
||||
dependencies = [
|
||||
"cxx",
|
||||
"cxx-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kifu-core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"grid",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"typeshare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kifu-wasm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"kifu-core",
|
||||
"serde",
|
||||
"serde-wasm-bindgen",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.142"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"
|
||||
|
||||
[[package]]
|
||||
name = "link-cplusplus"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "no-std-compat"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
|
||||
|
||||
[[package]]
|
||||
name = "scratch"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.160"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-wasm-bindgen"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.160"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typeshare"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f44d1a2f454cb35fbe05b218c410792697e76bd868f48d3a418f2cd1a7d527d6"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"typeshare-annotation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typeshare-annotation"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc670d0e358428857cc3b4bf504c691e572fccaec9542ff09212d3f13d74b7a9"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
|
@ -1,19 +0,0 @@
|
|||
[package]
|
||||
name = "kifu-wasm"
|
||||
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]
|
||||
kifu-core = { path = "../../core" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde-wasm-bindgen = "0.5.0"
|
||||
wasm-bindgen = "0.2"
|
||||
wasm-bindgen-futures = "*"
|
||||
|
||||
[package.metadata.wasm-pack.profile.release]
|
||||
wasm-opt = false
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
all:
|
||||
wasm-pack build --target web
|
|
@ -1,26 +0,0 @@
|
|||
use kifu_core::{CoreRequest, CoreResponse};
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
pub fn log(s: &str);
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[derive(Debug)]
|
||||
pub struct CoreApp(kifu_core::CoreApp);
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl CoreApp {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new() -> Self {
|
||||
Self(kifu_core::CoreApp::new())
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub async fn dispatch(&self, param: &JsValue) -> JsValue {
|
||||
let request: CoreRequest = serde_wasm_bindgen::from_value(param.clone()).unwrap();
|
||||
serde_wasm_bindgen::to_value(&self.0.dispatch(request).await).unwrap()
|
||||
}
|
||||
}
|
|
@ -10,6 +10,8 @@ screenplay = []
|
|||
|
||||
[dependencies]
|
||||
adw = { version = "0.5", package = "libadwaita", features = [ "v1_2" ] }
|
||||
async-channel = { version = "2" }
|
||||
async-std = { version = "1" }
|
||||
cairo-rs = { version = "0.18" }
|
||||
gio = { version = "0.18" }
|
||||
glib = { version = "0.18" }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
fn main() {
|
||||
glib_build_tools::compile_resources(
|
||||
&["resources"],
|
||||
"resources/gresources.xml",
|
||||
"gresources.xml",
|
||||
"com.luminescent-dreams.kifu-gtk.gresource",
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
{ gtkNativeInputs }:
|
||||
attrs:
|
||||
let
|
||||
gsettingsDir = "${attrs.crateName}-${attrs.version}";
|
||||
in {
|
||||
nativeBuildInputs = gtkNativeInputs;
|
||||
postInstall = ''
|
||||
install -Dt $out/share/applications resources/kifu.desktop
|
||||
install -Dt $out/gsettings-schemas/${gsettingsDir}/glib-2.0/schemas resources/com.luminescent-dreams.kifu.gschema.xml
|
||||
glib-compile-schemas $out/gsettings-schemas/${gsettingsDir}/glib-2.0/schemas
|
||||
'';
|
||||
# preFixup = ''
|
||||
# gappsWrapperArgs+=(
|
||||
# --prefix XDG_DATA_DIRS : $out/gsettings-schemas/${gsettingsDir}
|
||||
# )
|
||||
# '';
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<schemalist>
|
||||
<schema id="com.luminescent-dreams.kifu-gtk.dev" path="/com/luminescent-dreams/kifu-gtk/dev/">
|
||||
<key name="database-path" type="s">
|
||||
<default>""</default>
|
||||
<summary>Path to the directory of games</summary>
|
||||
</key>
|
||||
<key name="language" type="s">
|
||||
<default>""</default>
|
||||
<summary>Language override, use system settings if empty</summary>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<schemalist>
|
||||
<schema id="com.luminescent-dreams.kifu-gtk" path="/com/luminescent-dreams/kifu-gtk/">
|
||||
<key name="database-path" type="s">
|
||||
<default>""</default>
|
||||
<summary>Path to the directory of games</summary>
|
||||
</key>
|
||||
<key name="language" type="s">
|
||||
<default>""</default>
|
||||
<summary>Language override, use system settings if empty</summary>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
|
@ -0,0 +1,5 @@
|
|||
[Desktop Entry]
|
||||
Version=0.2
|
||||
Type=Application
|
||||
Name=Kifu
|
||||
Exec=kifu
|
|
@ -1,22 +1,30 @@
|
|||
pub mod ui;
|
||||
use kifu_core::{CoreApp, CoreRequest, CoreResponse};
|
||||
use std::sync::Arc;
|
||||
|
||||
mod view_models;
|
||||
mod views;
|
||||
|
||||
use async_std::task::yield_now;
|
||||
use kifu_core::{Core, CoreRequest, CoreResponse, Observable};
|
||||
use std::{rc::Rc, sync::Arc};
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CoreApi {
|
||||
pub gtk_tx: gtk::glib::Sender<CoreResponse>,
|
||||
pub rt: Arc<Runtime>,
|
||||
pub core: CoreApp,
|
||||
pub core: Core,
|
||||
}
|
||||
|
||||
impl CoreApi {
|
||||
pub fn dispatch(&self, request: CoreRequest) {
|
||||
self.rt.spawn({
|
||||
/*
|
||||
spawn({
|
||||
/*
|
||||
let gtk_tx = self.gtk_tx.clone();
|
||||
let core = self.core.clone();
|
||||
async move { gtk_tx.send(core.dispatch(request).await) }
|
||||
*/
|
||||
});
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,3 +38,48 @@ where
|
|||
println!("[Trace: {}] {:?}", trace_name, end - start);
|
||||
result
|
||||
}
|
||||
|
||||
/// LocalObserver creates a task on the current thread which watches the specified observer for notifications and calls the handler function with each one.
|
||||
///
|
||||
/// The LocalObserver starts a task which listens for notifications during the constructor. When the observer goes out of scope, it will make a point of aborting the task. This combination means that anything which uses the observer can create it, hold on to a reference of it, and then drop it when done, and not have to do anything else with the observer object.
|
||||
struct LocalObserver<T> {
|
||||
join_handle: glib::JoinHandle<()>,
|
||||
handler: Rc<dyn Fn(T)>,
|
||||
}
|
||||
|
||||
impl<T: 'static> LocalObserver<T> {
|
||||
/// Construct a new LocalObserver and start it running.
|
||||
///
|
||||
/// observable -- any object which emits events
|
||||
/// handler -- a function which can process events
|
||||
fn new(observable: &dyn Observable<T>, handler: impl Fn(T) + 'static) -> Self {
|
||||
let listener = observable.subscribe();
|
||||
let handler = Rc::new(handler);
|
||||
let join_handle = glib::spawn_future_local({
|
||||
let handler = handler.clone();
|
||||
async move {
|
||||
loop {
|
||||
match listener.recv().await {
|
||||
Ok(msg) => handler(msg),
|
||||
Err(_) => {
|
||||
// recv only fails if the channel has been closed and no other notifications are pending. This will break out of the loop and terminate the observer.
|
||||
return;
|
||||
}
|
||||
}
|
||||
yield_now().await;
|
||||
}
|
||||
}
|
||||
});
|
||||
Self {
|
||||
join_handle,
|
||||
handler,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for LocalObserver<T> {
|
||||
fn drop(&mut self) {
|
||||
// Abort the task when the observer goes out of scope.
|
||||
self.join_handle.abort();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use adw::prelude::*;
|
||||
use kifu_core::{CoreApp, CoreRequest, CoreResponse};
|
||||
use kifu_core::{Config, ConfigOption, Core, CoreRequest, CoreResponse, DatabasePath};
|
||||
use kifu_gtk::{
|
||||
perftrace,
|
||||
ui::{AppWindow, ConfigurationPage, Home, PlayingField},
|
||||
|
@ -7,6 +7,11 @@ use kifu_gtk::{
|
|||
};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
const APP_ID_DEV: &str = "com.luminescent-dreams.kifu-gtk.dev";
|
||||
const APP_ID_PROD: &str = "com.luminescent-dreams.kifu-gtk";
|
||||
|
||||
const RESOURCE_BASE_PATH: &str = "/com/luminescent-dreams/kifu-gtk/";
|
||||
|
||||
fn handle_response(api: CoreApi, app_window: &AppWindow, message: CoreResponse) {
|
||||
let playing_field = Arc::new(RwLock::new(None));
|
||||
match message {
|
||||
|
@ -48,6 +53,17 @@ fn main() {
|
|||
gio::resources_register_include!("com.luminescent-dreams.kifu-gtk.gresource")
|
||||
.expect("Failed to register resources");
|
||||
|
||||
let app_id = if std::env::var_os("ENV") == Some("dev".into()) {
|
||||
APP_ID_DEV
|
||||
} else {
|
||||
APP_ID_PROD
|
||||
};
|
||||
|
||||
let settings = gio::Settings::new(app_id);
|
||||
let db_path: String = settings.string("database-path").into();
|
||||
let mut config = Config::new();
|
||||
config.set(ConfigOption::DatabasePath(db_path.into()));
|
||||
|
||||
let runtime = Arc::new(
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
|
@ -55,6 +71,7 @@ fn main() {
|
|||
.unwrap(),
|
||||
);
|
||||
|
||||
/*
|
||||
let config_path = std::env::var("CONFIG")
|
||||
.map(std::path::PathBuf::from)
|
||||
.or({
|
||||
|
@ -66,15 +83,18 @@ fn main() {
|
|||
})
|
||||
})
|
||||
.expect("no config path could be found");
|
||||
*/
|
||||
|
||||
let core = CoreApp::new(config_path);
|
||||
let core = Core::new(config);
|
||||
|
||||
/*
|
||||
let core_handle = runtime.spawn({
|
||||
let core = core.clone();
|
||||
async move {
|
||||
core.run().await;
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
let app = adw::Application::builder()
|
||||
.application_id("com.luminescent-dreams.kifu-gtk")
|
||||
|
@ -84,13 +104,9 @@ fn main() {
|
|||
app.connect_activate({
|
||||
let runtime = runtime.clone();
|
||||
move |app| {
|
||||
let (gtk_tx, gtk_rx) =
|
||||
gtk::glib::MainContext::channel::<CoreResponse>(gtk::glib::Priority::DEFAULT);
|
||||
|
||||
let app_window = AppWindow::new(app);
|
||||
|
||||
let api = CoreApi {
|
||||
gtk_tx,
|
||||
rt: runtime.clone(),
|
||||
core: core.clone(),
|
||||
};
|
||||
|
@ -106,6 +122,7 @@ fn main() {
|
|||
|
||||
app_window.window.present();
|
||||
|
||||
/*
|
||||
gtk_rx.attach(None, {
|
||||
let api = api.clone();
|
||||
move |message| {
|
||||
|
@ -115,6 +132,7 @@ fn main() {
|
|||
glib::ControlFlow::Continue
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
api.dispatch(CoreRequest::Home);
|
||||
}
|
||||
|
@ -123,5 +141,5 @@ fn main() {
|
|||
println!("running the gtk loop");
|
||||
app.run();
|
||||
|
||||
let _ = runtime.block_on(core_handle);
|
||||
/* let _ = runtime.block_on(core_handle); */
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Copyright 2024, Savanni D'Gerinel <savanni@luminescent-dreams.com>
|
||||
|
||||
This file is part of Kifu.
|
||||
|
||||
Kifu is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||||
General Public License as published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Kifu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with Kifu. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::LocalObserver;
|
||||
use kifu_core::{Core, CoreNotification};
|
||||
|
||||
pub struct GameReviewViewModel {
|
||||
core: Core,
|
||||
notification_observer: LocalObserver<CoreNotification>,
|
||||
widget: gtk::Box,
|
||||
}
|
||||
|
||||
impl GameReviewViewModel {
|
||||
fn new(core: Core) -> Self {
|
||||
let notification_observer = LocalObserver::new(&core, |msg| {
|
||||
println!("GameReviewViewModel called with message: {:?}", msg)
|
||||
});
|
||||
|
||||
Self {
|
||||
core,
|
||||
notification_observer,
|
||||
widget: gtk::Box::new(gtk::Orientation::Horizontal, 0),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
Copyright 2024, Savanni D'Gerinel <savanni@luminescent-dreams.com>
|
||||
|
||||
This file is part of Kifu.
|
||||
|
||||
Kifu is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||||
General Public License as published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Kifu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with Kifu. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use async_std::{channel::Receiver, task::yield_now};
|
||||
use kifu_core::{Color, Core, CoreNotification, Goban, Observable, Player};
|
||||
use std::{cell::RefCell, rc::Rc, time::Duration};
|
||||
|
||||
use crate::LocalObserver;
|
||||
|
||||
pub struct GameState {
|
||||
goban: Goban,
|
||||
white_clock: Duration,
|
||||
black_clock: Duration,
|
||||
white_score: f32,
|
||||
black_score: f32,
|
||||
current: Color,
|
||||
}
|
||||
|
||||
struct GameViewModelPrivate {
|
||||
white: Player, /* Maybe this should be PlayerState, instead, combining the player info, current clock, and current captures. */
|
||||
black: Player,
|
||||
|
||||
state: GameState,
|
||||
}
|
||||
|
||||
/// The Game View Model manages the current state of the game. It shows the two player cards, the board, the current capture count, the current player, and it maintains the UI for the clock (bearing in mind that the real clock is managed in the core). This view model should only be created once the details of the game, whether a game in progress or a new game (this view model won't know the difference) is known.
|
||||
pub struct GameViewModel {
|
||||
core: Core,
|
||||
notification_observer: LocalObserver<CoreNotification>,
|
||||
widget: gtk::Box,
|
||||
data: Rc<RefCell<GameViewModelPrivate>>,
|
||||
}
|
||||
|
||||
impl GameViewModelPrivate {
|
||||
fn handle(&mut self, _message: CoreNotification) {}
|
||||
}
|
||||
|
||||
impl GameViewModel {
|
||||
pub fn new(white: Player, black: Player, game: GameState, core: Core) -> Self {
|
||||
let data = Rc::new(RefCell::new(GameViewModelPrivate {
|
||||
white,
|
||||
black,
|
||||
state: game,
|
||||
}));
|
||||
|
||||
let notification_observer = LocalObserver::new(&core, |msg| {
|
||||
println!("GameViewModelHandler called with message: {:?}", msg)
|
||||
});
|
||||
|
||||
Self {
|
||||
core,
|
||||
notification_observer,
|
||||
widget: gtk::Box::new(gtk::Orientation::Horizontal, 0),
|
||||
data,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Copyright 2024, Savanni D'Gerinel <savanni@luminescent-dreams.com>
|
||||
|
||||
This file is part of Kifu.
|
||||
|
||||
Kifu is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||||
General Public License as published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Kifu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with Kifu. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::LocalObserver;
|
||||
use kifu_core::{Core, CoreNotification};
|
||||
|
||||
/// Home controls the view that the user sees when starting the application if there are no games in progress. It provides a window into the database, showing a list of recently recorded games. It also provides the UI for starting a new game. This will render an empty database view if the user hasn't configured a database yet.
|
||||
pub struct HomeViewModel {
|
||||
core: Core,
|
||||
notification_observer: LocalObserver<CoreNotification>,
|
||||
widget: gtk::Box,
|
||||
}
|
||||
|
||||
impl HomeViewModel {
|
||||
fn new(core: Core) -> Self {
|
||||
let notification_observer = LocalObserver::new(&core, |msg| {
|
||||
println!("DatabaseViewModelHandler called with message: {:?}", msg)
|
||||
});
|
||||
|
||||
Self {
|
||||
core,
|
||||
notification_observer,
|
||||
widget: gtk::Box::new(gtk::Orientation::Horizontal, 0),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new game with the given parameters.
|
||||
fn new_game(&self) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// Select a game from the database to show in detail. This will require a transition away from this view model into a different one.
|
||||
fn select_game(&self) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// Delete a game from the database.
|
||||
fn delete_game(&self) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Copyright 2024, Savanni D'Gerinel <savanni@luminescent-dreams.com>
|
||||
|
||||
This file is part of Kifu.
|
||||
|
||||
Kifu is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||||
General Public License as published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Kifu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with Kifu. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Every view model requires a reference to the app so that it can call functions on the core, and a notification receiver so that it can receive messages from the core.
|
||||
|
||||
The view model is primary over the view. It will construct the view, it can make major changes to the view or even swap for another related view. It must listen for all messages from the core, discarding those that aren't relevant to it. It will also convert requests from sync to async.
|
||||
*/
|
||||
|
||||
mod game_view_model;
|
||||
pub use game_view_model::GameViewModel;
|
||||
|
||||
mod game_review_view_model;
|
||||
pub use game_review_view_model::GameReviewViewModel;
|
||||
|
||||
mod home_view_model;
|
||||
pub use home_view_model::HomeViewModel;
|
||||
|
||||
mod settings_view_model;
|
||||
pub use settings_view_model::SettingsViewModel;
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Copyright 2024, Savanni D'Gerinel <savanni@luminescent-dreams.com>
|
||||
|
||||
This file is part of Kifu.
|
||||
|
||||
Kifu is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||||
General Public License as published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Kifu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with Kifu. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::LocalObserver;
|
||||
use kifu_core::{Core, CoreNotification};
|
||||
|
||||
pub struct SettingsViewModel {
|
||||
core: Core,
|
||||
notification_observer: LocalObserver<CoreNotification>,
|
||||
widget: gtk::Box,
|
||||
}
|
||||
|
||||
impl SettingsViewModel {
|
||||
fn new(core: Core) -> Self {
|
||||
let notification_observer = LocalObserver::new(&core, |msg| {
|
||||
println!("SettingsViewModel called with message: {:?}", msg)
|
||||
});
|
||||
|
||||
Self {
|
||||
core,
|
||||
notification_observer,
|
||||
widget: gtk::Box::new(gtk::Orientation::Horizontal, 0),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
|
||||
release: kifu-wasm core-types
|
||||
NODE_ENV=production npm run build
|
||||
|
||||
dev: kifu-wasm core-types
|
||||
npm run build
|
||||
|
||||
kifu-wasm:
|
||||
pushd ../ffi/wasm && make && popd
|
||||
|
||||
core-types:
|
||||
pushd ../core-types && make && popd
|
||||
|
||||
server:
|
||||
npx http-server ./dist
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"name": "kifu-pwa",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "webpack.config.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "webpack"
|
||||
},
|
||||
"author": "Savanni D'Gerinel <savanni@luminescent-dreams.com>",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.14.194",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^5.0.4",
|
||||
"webpack": "^5.82.0",
|
||||
"webpack-cli": "^5.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21"
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
export const assertNever = (_: never) => {};
|
|
@ -1,262 +0,0 @@
|
|||
import { BoardElement, Color, Size, CoreRequest } from "core-types";
|
||||
import { assertNever } from "../assertNever";
|
||||
|
||||
const MARGIN = 20;
|
||||
const BOARD_WIDTH = 800;
|
||||
const BOARD_HEIGHT = 800;
|
||||
|
||||
type Pixel = { x: number; y: number };
|
||||
type Coordinate = { column: number; row: number };
|
||||
|
||||
export interface GoBoardProps {
|
||||
board: BoardElement;
|
||||
onClick: (_: CoreRequest) => void;
|
||||
}
|
||||
|
||||
export class GoBoard {
|
||||
private board: BoardElement;
|
||||
private pen: Pen;
|
||||
private cursorLocation: Coordinate | null;
|
||||
private backgroundBoard: HTMLCanvasElement;
|
||||
private currentBoardState: HTMLCanvasElement;
|
||||
canvas: HTMLCanvasElement;
|
||||
|
||||
constructor({ board, onClick }: GoBoardProps) {
|
||||
this.board = board;
|
||||
|
||||
this.canvas = document.createElement("canvas");
|
||||
this.canvas.classList.add("board");
|
||||
this.canvas.width = BOARD_WIDTH;
|
||||
this.canvas.height = BOARD_HEIGHT;
|
||||
|
||||
this.pen = new Pen(
|
||||
this.canvas.width,
|
||||
this.canvas.height,
|
||||
MARGIN,
|
||||
this.board.size.width,
|
||||
this.board.size.height
|
||||
);
|
||||
|
||||
this.backgroundBoard = document.createElement("canvas");
|
||||
this.backgroundBoard.width = BOARD_WIDTH;
|
||||
this.backgroundBoard.height = BOARD_HEIGHT;
|
||||
this.renderBackgroundBoard();
|
||||
|
||||
this.currentBoardState = document.createElement("canvas");
|
||||
this.currentBoardState.width = BOARD_WIDTH;
|
||||
this.currentBoardState.height = BOARD_HEIGHT;
|
||||
|
||||
this.cursorLocation = null;
|
||||
|
||||
this.canvas.onmousemove = (event) => {
|
||||
const bounds = this.canvas.getBoundingClientRect();
|
||||
const coordinate = {
|
||||
x: event.clientX - bounds.x,
|
||||
y: event.clientY - bounds.y,
|
||||
};
|
||||
|
||||
let address = this.pen.address(coordinate);
|
||||
|
||||
if (this.cursorLocation != address) {
|
||||
this.cursorLocation = this.pen.address(coordinate);
|
||||
this.renderBoard();
|
||||
}
|
||||
};
|
||||
|
||||
this.canvas.onclick = (_) => {
|
||||
if (this.cursorLocation) {
|
||||
const intersection =
|
||||
this.board.spaces[boardAddress(this.board.size, this.cursorLocation)];
|
||||
switch (intersection.type) {
|
||||
case "Unplayable":
|
||||
break;
|
||||
case "Empty":
|
||||
onClick(intersection.content);
|
||||
break;
|
||||
case "Filled":
|
||||
break;
|
||||
default:
|
||||
assertNever(intersection);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
setBoard(board: BoardElement) {
|
||||
this.board = board;
|
||||
|
||||
this.pen = new Pen(
|
||||
this.canvas.width,
|
||||
this.canvas.height,
|
||||
MARGIN,
|
||||
this.board.size.width,
|
||||
this.board.size.height
|
||||
);
|
||||
this.renderBoard();
|
||||
}
|
||||
|
||||
renderBoard() {
|
||||
// Cache:
|
||||
// - Standard blank board with background
|
||||
// - Current board state without the ghost stone
|
||||
const ctx = this.canvas.getContext("2d");
|
||||
if (!ctx) {
|
||||
alert("could not get the canvas context");
|
||||
return null;
|
||||
}
|
||||
|
||||
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
ctx.drawImage(this.backgroundBoard, 0, 0);
|
||||
|
||||
let col = 0;
|
||||
let row = 0;
|
||||
for (let idx = 0; idx < this.board.spaces.length; idx++) {
|
||||
const space = this.board.spaces[idx];
|
||||
switch (space.type) {
|
||||
case "Filled":
|
||||
this.pen.stone(ctx, { column: col, row: row }, space.content.color);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
col = col + 1;
|
||||
if (col == this.board.size.width) {
|
||||
col = 0;
|
||||
row = row + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.cursorLocation) {
|
||||
this.pen.ghostStone(ctx, this.cursorLocation, Color.White);
|
||||
}
|
||||
}
|
||||
|
||||
private renderBackgroundBoard() {
|
||||
const ctx = this.backgroundBoard.getContext("2d");
|
||||
if (!ctx) {
|
||||
alert("could not get the background canvas context");
|
||||
return;
|
||||
}
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = "black";
|
||||
ctx.beginPath();
|
||||
for (var col = 0; col < this.board.size.width; col++) {
|
||||
ctx.moveTo(MARGIN + col * this.pen.hspaceBetween, MARGIN);
|
||||
ctx.lineTo(
|
||||
MARGIN + col * this.pen.hspaceBetween,
|
||||
MARGIN + (this.board.size.height - 1) * this.pen.vspaceBetween
|
||||
);
|
||||
}
|
||||
for (var row = 0; row < this.board.size.height; row++) {
|
||||
ctx.moveTo(MARGIN, MARGIN + row * this.pen.vspaceBetween);
|
||||
ctx.lineTo(
|
||||
MARGIN + (this.board.size.width - 1) * this.pen.hspaceBetween,
|
||||
MARGIN + row * this.pen.vspaceBetween
|
||||
);
|
||||
}
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
this.pen.starPoint(ctx, { column: 3, row: 3 });
|
||||
this.pen.starPoint(ctx, { column: 3, row: 9 });
|
||||
this.pen.starPoint(ctx, { column: 3, row: 15 });
|
||||
this.pen.starPoint(ctx, { column: 9, row: 3 });
|
||||
this.pen.starPoint(ctx, { column: 9, row: 9 });
|
||||
this.pen.starPoint(ctx, { column: 9, row: 15 });
|
||||
this.pen.starPoint(ctx, { column: 15, row: 3 });
|
||||
this.pen.starPoint(ctx, { column: 15, row: 9 });
|
||||
this.pen.starPoint(ctx, { column: 15, row: 15 });
|
||||
}
|
||||
}
|
||||
|
||||
class Pen {
|
||||
margin: number;
|
||||
hspaceBetween: number;
|
||||
vspaceBetween: number;
|
||||
|
||||
constructor(
|
||||
width: number,
|
||||
height: number,
|
||||
margin: number,
|
||||
columns: number,
|
||||
rows: number
|
||||
) {
|
||||
this.margin = margin;
|
||||
this.hspaceBetween = (width - margin * 2) / (columns - 1);
|
||||
this.vspaceBetween = (height - margin * 2) / (rows - 1);
|
||||
}
|
||||
|
||||
starPoint(ctx: CanvasRenderingContext2D, addr: Coordinate) {
|
||||
ctx.fillStyle = "rgba(0, 0, 0, 1.0);";
|
||||
ctx.beginPath();
|
||||
const pixel = this.position(addr);
|
||||
ctx.moveTo(pixel.x, pixel.y);
|
||||
ctx.arc(pixel.x, pixel.y, 5, 0, 2 * Math.PI);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
ghostStone(ctx: CanvasRenderingContext2D, addr: Coordinate, color: Color) {
|
||||
switch (color) {
|
||||
case Color.White:
|
||||
ctx.fillStyle = "rgba(230, 230, 230, 0.5)";
|
||||
break;
|
||||
case Color.Black:
|
||||
ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
|
||||
break;
|
||||
}
|
||||
|
||||
this.drawStone(ctx, addr);
|
||||
}
|
||||
|
||||
stone(ctx: CanvasRenderingContext2D, addr: Coordinate, color: Color) {
|
||||
switch (color) {
|
||||
case Color.White:
|
||||
ctx.fillStyle = "rgb(230, 230, 230)";
|
||||
break;
|
||||
case Color.Black:
|
||||
ctx.fillStyle = "rgb(0, 0, 0)";
|
||||
break;
|
||||
}
|
||||
|
||||
this.drawStone(ctx, addr);
|
||||
}
|
||||
|
||||
drawStone(ctx: CanvasRenderingContext2D, addr: Coordinate) {
|
||||
ctx.beginPath();
|
||||
const radius = this.hspaceBetween / 2 - 2;
|
||||
const pixel = this.position(addr);
|
||||
ctx.moveTo(pixel.x, pixel.y);
|
||||
ctx.arc(pixel.x, pixel.y, radius, 0, 2.0 * Math.PI);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
position(addr: Coordinate): Pixel {
|
||||
return {
|
||||
x: this.margin + addr.column * this.hspaceBetween,
|
||||
y: this.margin + addr.row * this.vspaceBetween,
|
||||
};
|
||||
}
|
||||
|
||||
address(pixel: Pixel): Coordinate | null {
|
||||
if (
|
||||
Math.round(pixel.x) < this.margin ||
|
||||
Math.round(pixel.y) < this.margin
|
||||
) {
|
||||
return null;
|
||||
} else {
|
||||
return {
|
||||
column: Math.round(
|
||||
(Math.round(pixel.x) - this.margin) / this.hspaceBetween
|
||||
),
|
||||
row: Math.round(
|
||||
(Math.round(pixel.y) - this.margin) / this.vspaceBetween
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const boardAddress = (size: Size, coordinate: Coordinate): number =>
|
||||
coordinate.column + size.width * coordinate.row;
|
|
@ -1,24 +0,0 @@
|
|||
import init, { CoreApp } from "kifu-wasm";
|
||||
import { CoreResponse, CoreRequest, PlayingFieldView } from "core-types";
|
||||
|
||||
export class CoreApi {
|
||||
core: CoreApp;
|
||||
|
||||
constructor() {
|
||||
let app = new CoreApp();
|
||||
this.core = app;
|
||||
}
|
||||
|
||||
async dispatch(request: CoreRequest): Promise<CoreResponse> {
|
||||
return await this.core.dispatch(request);
|
||||
}
|
||||
|
||||
async playingField(): Promise<PlayingFieldView> {
|
||||
return (await this.dispatch({ type: "PlayingField" })).content;
|
||||
}
|
||||
}
|
||||
|
||||
export const initCore = async (): Promise<CoreApi> => {
|
||||
await init();
|
||||
return new CoreApi();
|
||||
};
|
Binary file not shown.
Before Width: | Height: | Size: 479 KiB |
|
@ -1,20 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link rel="stylesheet" href="kifu.css">
|
||||
<title>Kifu</title>
|
||||
<script type="module" src="kifu-bundle.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> Kifu </h1>
|
||||
<div id="root"></div>
|
||||
<script>
|
||||
if('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('/sw.js', { scope: '/' });
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
html {
|
||||
background: rgb(243, 243, 243);
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
font-size: 15pt;
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
canvas {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.board {
|
||||
background-color: rgb(150, 150, 150);
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
import { GoBoard } from "./components/Board";
|
||||
import { CoreRequest, CoreResponse } from "core-types";
|
||||
import { CoreApi, initCore } from "./coreApi";
|
||||
// import { assertNever } from "./assertNever";
|
||||
|
||||
class UIState {
|
||||
private currentView: GoBoard | null;
|
||||
private rootElement: HTMLElement;
|
||||
coreApi: CoreApi;
|
||||
|
||||
constructor(coreApi: CoreApi, root: HTMLElement) {
|
||||
this.currentView = null;
|
||||
this.rootElement = root;
|
||||
this.coreApi = coreApi;
|
||||
|
||||
if (!root) {
|
||||
console.log("root element not found");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
processResponse(response: CoreResponse) {
|
||||
switch (response.type) {
|
||||
case "PlayingFieldView":
|
||||
if (this.currentView) {
|
||||
this.currentView.setBoard(response.content.board);
|
||||
} else {
|
||||
this.currentView = new GoBoard({
|
||||
board: response.content.board,
|
||||
onClick: async (request: CoreRequest) => {
|
||||
const response = await this.coreApi.dispatch(request);
|
||||
this.processResponse(response);
|
||||
},
|
||||
});
|
||||
this.rootElement?.appendChild(this.currentView.canvas);
|
||||
this.currentView.renderBoard();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log("impossible branch: ", response);
|
||||
alert("impossible branch");
|
||||
// assertNever(response);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const main = async () => {
|
||||
let coreApi = await initCore();
|
||||
let response = await coreApi.dispatch({ type: "PlayingField" });
|
||||
const root = document.getElementById("root");
|
||||
|
||||
if (!root) {
|
||||
console.log("root element not present");
|
||||
return;
|
||||
}
|
||||
|
||||
const uiState = new UIState(coreApi, root);
|
||||
uiState.processResponse(response);
|
||||
};
|
||||
|
||||
main();
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"lang": "en-us",
|
||||
"name": "Kifu",
|
||||
"short_name": "Kifu",
|
||||
"description": "An app for playing Go",
|
||||
"start_url": "/",
|
||||
"background_color": "#2f3d58",
|
||||
"theme_color": "#2f3d58",
|
||||
"orientation": "any",
|
||||
"display": "standalone",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/icon512.png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
const CACHE_NAME = 'kifu-pwa-3';
|
||||
|
||||
self.addEventListener('install', event => {
|
||||
event.waitUntil((async () => {
|
||||
const cache = await caches.open(CACHE_NAME);
|
||||
cache.addAll([
|
||||
'/',
|
||||
'/kifu-bundle.js',
|
||||
'/kifu.css',
|
||||
]);
|
||||
})());
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', event => {
|
||||
event.respondWith((async () => {
|
||||
const cache = await caches.open(CACHE_NAME);
|
||||
const cachedResponse = await cache.match(event.request);
|
||||
if (cachedResponse) {
|
||||
return cachedResponse;
|
||||
} else {
|
||||
try {
|
||||
const fetchResponse = await fetch(event.request);
|
||||
cache.put(event.request, fetchResponse.clone());
|
||||
return fetchResponse;
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
})());
|
||||
});
|
|
@ -1,28 +0,0 @@
|
|||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
mode: "development",
|
||||
entry: {
|
||||
"kifu-bundle": "./src/main.ts",
|
||||
sw: "./src/sw.js",
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.ts$/, use: "ts-loader", exclude: /node_modules/ },
|
||||
{ test: /\.wasm$/, type: "asset/inline" }
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
{ from: "src/index.html" },
|
||||
{ from: "src/kifu.css" },
|
||||
{ from: "src/manifest.json" },
|
||||
{ from: "src/icon512.png" }
|
||||
]
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
extensions: ['.ts'],
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"name": "tools",
|
||||
"workspaces": [
|
||||
"kifu/ffi/wasm/pkg",
|
||||
"kifu/core-types",
|
||||
"kifu/pwa"
|
||||
]
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2016",
|
||||
"module": "commonjs",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue