Merge pull request 'next' (#1) from next into main
Some checks failed
Rust / build (push) Has been cancelled
Some checks failed
Rust / build (push) Has been cancelled
Reviewed-on: #1
This commit is contained in:
commit
5f5e10d39f
493
Cargo.lock
generated
493
Cargo.lock
generated
|
@ -2,20 +2,11 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.14"
|
||||
version = "0.6.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
|
||||
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
|
@ -28,49 +19,62 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.7"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
|
||||
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.4"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
|
||||
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.3"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
|
||||
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.3"
|
||||
version = "3.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
|
||||
checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.52.0",
|
||||
"once_cell",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.5.0"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
"tap",
|
||||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
@ -80,9 +84,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.4"
|
||||
version = "4.5.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
|
||||
checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
@ -90,9 +94,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.2"
|
||||
version = "4.5.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
|
||||
checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
@ -102,9 +106,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.4"
|
||||
version = "4.5.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
|
||||
checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
|
@ -114,27 +118,38 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.0"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.1"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
|
||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.27.0"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
||||
checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"derive_more",
|
||||
"document-features",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"rustix",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
|
@ -150,33 +165,56 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.0"
|
||||
name = "derive_more"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea"
|
||||
checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678"
|
||||
dependencies = [
|
||||
"log",
|
||||
"regex",
|
||||
"derive_more-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.3"
|
||||
name = "derive_more-impl"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9"
|
||||
checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"env_filter",
|
||||
"humantime",
|
||||
"log",
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "document-features"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d"
|
||||
dependencies = [
|
||||
"litrs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
|
@ -189,23 +227,29 @@ version = "0.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.0"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.155"
|
||||
version = "0.2.172"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
|
||||
|
||||
[[package]]
|
||||
name = "litrs"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
|
@ -219,33 +263,33 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.2"
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
|
@ -261,49 +305,58 @@ dependencies = [
|
|||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.5",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.82"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.0-alpha.1"
|
||||
name = "radium"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d31e63ea85be51c423e52ba8f2e68a3efd53eed30203ee029dd09947333693e"
|
||||
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.9.0-alpha.1"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78674ef918c19451dbd250f8201f8619b494f64c9aa6f3adb28fd8a0f1f6da46"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
|
@ -311,52 +364,35 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.9.0-alpha.1"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc89dffba8377c5ec847d12bb41492bda235dba31a25e8b695cd0fe6589eb8c9"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.1"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
|
||||
checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.4"
|
||||
name = "rustix"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
|
@ -364,24 +400,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "servicepoint-life"
|
||||
version = "0.1.0"
|
||||
name = "servicepoint"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ce70bae3641ccafdeb9832ac367efd51243e0708ef35151ad8c2c4ee578aa4a"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"crossterm",
|
||||
"env_logger",
|
||||
"bitvec",
|
||||
"log",
|
||||
"rand",
|
||||
"servicepoint2",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "servicepoint2"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94d9aecc4d31a71578481de6c6d64383d374126c38469c9689067579c1d910fd"
|
||||
name = "servicepoint-life"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"clap",
|
||||
"crossterm",
|
||||
"rand",
|
||||
"servicepoint",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -396,9 +433,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
||||
checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
|
@ -407,18 +444,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.2"
|
||||
version = "1.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||
checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
|
@ -428,9 +465,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.64"
|
||||
version = "2.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f"
|
||||
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -438,16 +475,48 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
|
@ -477,159 +546,111 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.5",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.5",
|
||||
"windows_aarch64_msvc 0.52.5",
|
||||
"windows_i686_gnu 0.52.5",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.5",
|
||||
"windows_x86_64_gnu 0.52.5",
|
||||
"windows_x86_64_gnullvm 0.52.5",
|
||||
"windows_x86_64_msvc 0.52.5",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.5"
|
||||
name = "wyz"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
|
||||
dependencies = [
|
||||
"tap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.0-alpha.6"
|
||||
version = "0.8.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db678a6ee512bd06adf35c35be471cae2f9c82a5aed2b5d15e03628c98bddd57"
|
||||
checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.0-alpha.6"
|
||||
version = "0.8.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "201585ea96d37ee69f2ac769925ca57160cef31acb137c16f38b02b76f4c1e62"
|
||||
checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
36
Cargo.toml
36
Cargo.toml
|
@ -1,12 +1,34 @@
|
|||
[package]
|
||||
name = "servicepoint-life"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
license = "GPL-3.0-or-later"
|
||||
description = "Small terminal app that generates conways game of life rules and simulates them on the servicepoint display."
|
||||
repository = "https://git.berlin.ccc.de/vinzenz/servicepoint-life"
|
||||
readme = "README.md"
|
||||
keywords = ["cccb", "cccb-servicepoint", "conway", "game-of-life", "simulation"]
|
||||
rust-version = "1.70.0"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
rand = "0.9.0-alpha.1"
|
||||
env_logger = "0.11.3"
|
||||
servicepoint2 = { version = "0.4.2", default-features = false }
|
||||
crossterm = "0.27.0"
|
||||
log = "0.4.21"
|
||||
clap = { version = "4.5", features = ["derive"] }
|
||||
rand = "0.8"
|
||||
crossterm = "0.29"
|
||||
|
||||
[dependencies.servicepoint]
|
||||
package = "servicepoint"
|
||||
version = "0.14.0"
|
||||
features = ["rand"]
|
||||
default-features = false
|
||||
|
||||
[lints.clippy]
|
||||
incompatible_msrv = "forbid"
|
||||
|
||||
[profile.release]
|
||||
lto = true # Enable link-time optimization
|
||||
codegen-units = 1 # Reduce number of codegen units to increase optimizations
|
||||
|
||||
[profile.size-optimized]
|
||||
inherits = "release"
|
||||
opt-level = 'z' # Optimize for size
|
||||
panic = 'abort' # Abort on panic
|
||||
strip = true # Strip symbols from binary
|
||||
|
|
10
README.md
10
README.md
|
@ -1,5 +1,13 @@
|
|||
# servicepoint-life
|
||||
|
||||
More fully featured game of life for the servicepoint display based on the example in the repo.
|
||||
This is a small terminal app that generates conways game of life rules and simulates them on the servicepoint display.
|
||||
|
||||
It uses the [servicepoint](https://git.berlin.ccc.de/servicepoint/servicepoint/) library for the display commands.
|
||||
|
||||
## Running
|
||||
|
||||
With Nix flakes, you can just `nix run git+https://git.berlin.ccc.de/vinzenz/servicepoint-life`.
|
||||
|
||||
Otherwise, you can `cargo install --git https://git.berlin.ccc.de/vinzenz/servicepoint-life` and then run `servicepoint-life`.
|
||||
|
||||
If you want to poke at the code you can always check out the repo and `cargo run` it.
|
||||
|
|
64
flake.lock
Normal file
64
flake.lock
Normal file
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"nodes": {
|
||||
"naersk": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1745925850,
|
||||
"narHash": "sha256-cyAAMal0aPrlb1NgzMxZqeN1mAJ2pJseDhm2m6Um8T0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "38bc60bbc157ae266d4a0c96671c6c742ee17a5f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-filter": {
|
||||
"locked": {
|
||||
"lastModified": 1731533336,
|
||||
"narHash": "sha256-oRam5PS1vcrr5UPgALW0eo1m/5/pls27Z/pabHNy2Ms=",
|
||||
"owner": "numtide",
|
||||
"repo": "nix-filter",
|
||||
"rev": "f7653272fd234696ae94229839a99b73c9ab7de0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "nix-filter",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1746183838,
|
||||
"narHash": "sha256-kwaaguGkAqTZ1oK0yXeQ3ayYjs8u/W7eEfrFpFfIDFA=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "bf3287dac860542719fe7554e21e686108716879",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-24.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"naersk": "naersk",
|
||||
"nix-filter": "nix-filter",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
103
flake.nix
Normal file
103
flake.nix
Normal file
|
@ -0,0 +1,103 @@
|
|||
{
|
||||
description = "Flake for servicepoint-life";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";
|
||||
nix-filter.url = "github:numtide/nix-filter";
|
||||
naersk = {
|
||||
url = "github:nix-community/naersk";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
inputs@{
|
||||
self,
|
||||
nixpkgs,
|
||||
naersk,
|
||||
nix-filter,
|
||||
}:
|
||||
let
|
||||
lib = nixpkgs.lib;
|
||||
supported-systems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
"aarch64-darwin"
|
||||
"x86_64-darwin"
|
||||
];
|
||||
forAllSystems =
|
||||
f:
|
||||
lib.genAttrs supported-systems (
|
||||
system:
|
||||
f rec {
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
naersk' = pkgs.callPackage naersk { };
|
||||
selfPkgs = self.packages."${system}";
|
||||
inherit system;
|
||||
}
|
||||
);
|
||||
in
|
||||
rec {
|
||||
packages = forAllSystems (
|
||||
{ pkgs, naersk', ... }:
|
||||
rec {
|
||||
servicepoint-life = naersk'.buildPackage rec {
|
||||
strictDeps = true;
|
||||
nativeBuildInputs = with pkgs; [ pkg-config ];
|
||||
buildInputs = with pkgs; [
|
||||
xe
|
||||
xz
|
||||
];
|
||||
src = nix-filter.lib.filter {
|
||||
root = ./.;
|
||||
include = [
|
||||
./Cargo.toml
|
||||
./Cargo.lock
|
||||
./src
|
||||
./README.md
|
||||
./LICENSE
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
default = servicepoint-life;
|
||||
}
|
||||
);
|
||||
|
||||
legacyPackages = packages;
|
||||
|
||||
apps = forAllSystems (
|
||||
{ selfPkgs, ... }:
|
||||
rec {
|
||||
servicepoint-life = {
|
||||
type = "app";
|
||||
program = "${selfPkgs.servicepoint-life}/bin/servicepoint-life";
|
||||
};
|
||||
default = servicepoint-life;
|
||||
}
|
||||
);
|
||||
|
||||
devShells = forAllSystems (
|
||||
{ pkgs, selfPkgs, ... }:
|
||||
{
|
||||
default = pkgs.mkShell rec {
|
||||
inputsFrom = [ selfPkgs.default ];
|
||||
packages = [
|
||||
pkgs.gdb
|
||||
(pkgs.symlinkJoin {
|
||||
name = "rust-toolchain";
|
||||
paths = with pkgs; [
|
||||
rustc
|
||||
cargo
|
||||
rustfmt
|
||||
clippy
|
||||
];
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
formatter = forAllSystems ({ pkgs, ... }: pkgs.nixfmt-rfc-style);
|
||||
};
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs.buildPackages; [ rustup cargo pkg-config xe lzma ];
|
||||
}
|
153
src/app.rs
Normal file
153
src/app.rs
Normal file
|
@ -0,0 +1,153 @@
|
|||
use crate::{
|
||||
print::{println_debug, println_info, println_warning},
|
||||
simulation::{Simulation, SimulationEvent},
|
||||
Cli,
|
||||
};
|
||||
use crossterm::{
|
||||
event,
|
||||
event::{Event, KeyCode, KeyEvent, KeyEventKind},
|
||||
execute,
|
||||
terminal::{
|
||||
disable_raw_mode, enable_raw_mode, EnableLineWrap, EnterAlternateScreen,
|
||||
LeaveAlternateScreen,
|
||||
},
|
||||
};
|
||||
use servicepoint::{
|
||||
Bitmap, BitmapCommand, BrightnessGrid, BrightnessGridCommand, UdpSocketExt,
|
||||
FRAME_PACING, TILE_HEIGHT, TILE_WIDTH,
|
||||
};
|
||||
use std::{
|
||||
io::stdout,
|
||||
net::UdpSocket,
|
||||
thread,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
pub(crate) struct App {
|
||||
connection: UdpSocket,
|
||||
sim: Simulation,
|
||||
target_duration: Duration,
|
||||
pixels: Bitmap,
|
||||
luma: BrightnessGrid,
|
||||
terminated: bool,
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new(cli: Cli) -> Self {
|
||||
let connection = UdpSocket::bind_connect(cli.destination)
|
||||
.expect("Could not connect. Did you forget `--destination`?");
|
||||
|
||||
execute!(stdout(), EnterAlternateScreen, EnableLineWrap)
|
||||
.expect("could not enter alternate screen");
|
||||
enable_raw_mode().expect("could not enable raw terminal mode");
|
||||
|
||||
Self {
|
||||
connection,
|
||||
sim: Simulation::new(),
|
||||
terminated: false,
|
||||
target_duration: FRAME_PACING * 4,
|
||||
pixels: Bitmap::max_sized(),
|
||||
luma: BrightnessGrid::new(TILE_WIDTH, TILE_HEIGHT),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn run_iteration(&mut self) {
|
||||
let start = Instant::now();
|
||||
self.sim.run_iteration();
|
||||
|
||||
self.sim.draw_state(&mut self.pixels, &mut self.luma);
|
||||
let cmd: BitmapCommand = self.pixels.clone().into();
|
||||
self.connection.send_command(cmd).unwrap();
|
||||
let cmd: BrightnessGridCommand = self.luma.clone().into();
|
||||
self.connection.send_command(cmd).unwrap();
|
||||
|
||||
self.poll_events();
|
||||
|
||||
let tick_time = start.elapsed();
|
||||
if tick_time < self.target_duration {
|
||||
thread::sleep(self.target_duration - tick_time);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn terminated(&self) -> bool {
|
||||
self.terminated
|
||||
}
|
||||
|
||||
fn poll_events(&mut self) -> bool {
|
||||
while event::poll(Duration::from_secs(0)).expect("could not poll") {
|
||||
let event = event::read().expect("could not read event");
|
||||
|
||||
if let Event::Key(KeyEvent {
|
||||
kind: KeyEventKind::Press,
|
||||
code,
|
||||
..
|
||||
}) = event
|
||||
{
|
||||
if let Some(sim_event) = self.handle_key(code) {
|
||||
self.sim.handle_event(sim_event);
|
||||
};
|
||||
} else {
|
||||
println_debug(format!("unhandled event {event:?}"));
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn handle_key(&mut self, code: KeyCode) -> Option<SimulationEvent> {
|
||||
match code {
|
||||
KeyCode::Char('d') => Some(SimulationEvent::RandomizeLeftPixels),
|
||||
KeyCode::Char('e') => Some(SimulationEvent::RandomizeLeftLuma),
|
||||
KeyCode::Char('f') => Some(SimulationEvent::RandomizeRightPixels),
|
||||
KeyCode::Char('r') => Some(SimulationEvent::RandomizeRightLuma),
|
||||
KeyCode::Right => Some(SimulationEvent::SeparatorAccelerate),
|
||||
KeyCode::Left => Some(SimulationEvent::SeparatorDecelerate),
|
||||
KeyCode::Char('h') => {
|
||||
println_info("[h] help");
|
||||
println_info("[q] quit");
|
||||
println_info("[d] randomize left pixels");
|
||||
println_info("[e] randomize left luma");
|
||||
println_info("[r] randomize right pixels");
|
||||
println_info("[f] randomize right luma");
|
||||
println_info("[→] accelerate divider right");
|
||||
println_info("[←] accelerate divider left");
|
||||
None
|
||||
}
|
||||
KeyCode::Char('q') => {
|
||||
println_warning("terminating");
|
||||
self.terminated = true;
|
||||
None
|
||||
}
|
||||
KeyCode::Up => {
|
||||
self.target_duration = self
|
||||
.target_duration
|
||||
.saturating_sub(Duration::from_millis(1));
|
||||
println_info(format!(
|
||||
"increased simulation speed to {} ups",
|
||||
1f64 / self.target_duration.as_secs_f64()
|
||||
));
|
||||
None
|
||||
}
|
||||
KeyCode::Down => {
|
||||
self.target_duration = self
|
||||
.target_duration
|
||||
.saturating_add(Duration::from_millis(1));
|
||||
println_info(format!(
|
||||
"decreased simulation speed to {} ups",
|
||||
1f64 / self.target_duration.as_secs_f64()
|
||||
));
|
||||
None
|
||||
}
|
||||
key_code => {
|
||||
println_debug(format!("unhandled KeyCode {key_code:?}"));
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for App {
|
||||
fn drop(&mut self) {
|
||||
disable_raw_mode().expect("could not disable raw terminal mode");
|
||||
execute!(stdout(), LeaveAlternateScreen).expect("could not leave alternate screen");
|
||||
}
|
||||
}
|
28
src/game.rs
28
src/game.rs
|
@ -1,29 +1,21 @@
|
|||
use servicepoint2::Grid;
|
||||
use servicepoint::{Grid, Value, ValueGrid};
|
||||
|
||||
use crate::rules::Rules;
|
||||
|
||||
pub(crate) struct Game<TState, TGrid, TKernel, const KERNEL_SIZE: usize>
|
||||
where
|
||||
TGrid: Grid<TState>,
|
||||
TState: Copy + PartialEq,
|
||||
TKernel: Copy,
|
||||
pub(crate) struct Game<T: Value>
|
||||
{
|
||||
pub field: TGrid,
|
||||
pub rules: Rules<TState, TKernel, KERNEL_SIZE>,
|
||||
pub field: ValueGrid<T>,
|
||||
pub rules: Rules<T>,
|
||||
}
|
||||
|
||||
impl<TState, TGrid, TKernel, const KERNEL_SIZE: usize> Game<TState, TGrid, TKernel, KERNEL_SIZE>
|
||||
where
|
||||
TGrid: Grid<TState>,
|
||||
TState: Copy + PartialEq,
|
||||
TKernel: Copy,
|
||||
impl<T: Value> Game<T>
|
||||
{
|
||||
pub fn step(&mut self) {
|
||||
self.field = self.field_iteration();
|
||||
}
|
||||
|
||||
fn field_iteration(&self) -> TGrid {
|
||||
let mut next = TGrid::new(self.field.width(), self.field.height());
|
||||
fn field_iteration(&self) -> ValueGrid<T> {
|
||||
let mut next = ValueGrid::new(self.field.width(), self.field.height());
|
||||
for x in 0..self.field.width() {
|
||||
for y in 0..self.field.height() {
|
||||
let old_state = self.field.get(x, y);
|
||||
|
@ -41,14 +33,12 @@ where
|
|||
let mut count = 0;
|
||||
|
||||
let kernel = &self.rules.kernel;
|
||||
assert_eq!(KERNEL_SIZE % 2, 1);
|
||||
let offset = KERNEL_SIZE as i32 / 2;
|
||||
|
||||
for (kernel_y, kernel_row) in kernel.iter().enumerate() {
|
||||
let offset_y = kernel_y as i32 - offset;
|
||||
let offset_y = kernel_y as i32 - 1;
|
||||
|
||||
for (kernel_x, kernel_value) in kernel_row.iter().enumerate() {
|
||||
let offset_x = kernel_x as i32 - offset;
|
||||
let offset_x = kernel_x as i32 - 1;
|
||||
let neighbor_x = x + offset_x;
|
||||
let neighbor_y = y + offset_y;
|
||||
|
||||
|
|
281
src/main.rs
281
src/main.rs
|
@ -1,30 +1,11 @@
|
|||
use std::io::stdout;
|
||||
use std::num::Wrapping;
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use crate::app::App;
|
||||
use clap::Parser;
|
||||
use crossterm::{event, execute};
|
||||
use crossterm::event::{Event, KeyCode, KeyEventKind};
|
||||
use crossterm::terminal::{
|
||||
disable_raw_mode, enable_raw_mode, EnableLineWrap, EnterAlternateScreen, LeaveAlternateScreen,
|
||||
};
|
||||
use log::LevelFilter;
|
||||
use rand::distributions::{Distribution, Standard};
|
||||
use rand::Rng;
|
||||
use servicepoint2::{
|
||||
ByteGrid, CompressionCode, Connection, FRAME_PACING, Grid, Origin, PixelGrid, TILE_HEIGHT,
|
||||
TILE_WIDTH,
|
||||
};
|
||||
use servicepoint2::Command::{BitmapLinearWin, CharBrightness};
|
||||
|
||||
use crate::game::Game;
|
||||
use crate::print::{println_debug, println_info, println_warning};
|
||||
use crate::rules::{generate_bb3, generate_u8b3};
|
||||
|
||||
mod app;
|
||||
mod game;
|
||||
mod print;
|
||||
mod rules;
|
||||
mod simulation;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct Cli {
|
||||
|
@ -33,258 +14,8 @@ struct Cli {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
let connection = init();
|
||||
|
||||
let mut left_pixels = Game {
|
||||
rules: generate_bb3(),
|
||||
field: PixelGrid::max_sized(),
|
||||
};
|
||||
let mut right_pixels = Game {
|
||||
rules: generate_bb3(),
|
||||
field: PixelGrid::max_sized(),
|
||||
};
|
||||
let mut left_luma = Game {
|
||||
rules: generate_u8b3(),
|
||||
field: ByteGrid::new(TILE_WIDTH, TILE_HEIGHT),
|
||||
};
|
||||
let mut right_luma = Game {
|
||||
rules: generate_u8b3(),
|
||||
field: ByteGrid::new(TILE_WIDTH, TILE_HEIGHT),
|
||||
};
|
||||
|
||||
randomize(&mut left_luma.field);
|
||||
randomize(&mut left_pixels.field);
|
||||
randomize(&mut right_luma.field);
|
||||
randomize(&mut right_pixels.field);
|
||||
|
||||
let mut pixels = PixelGrid::max_sized();
|
||||
let mut luma = ByteGrid::new(TILE_WIDTH, TILE_HEIGHT);
|
||||
|
||||
let mut split_pixel = 0;
|
||||
let mut split_speed: i32 = 1;
|
||||
|
||||
let mut iteration = Wrapping(0u8);
|
||||
|
||||
let mut target_duration = FRAME_PACING;
|
||||
|
||||
loop {
|
||||
let start = Instant::now();
|
||||
|
||||
left_pixels.step();
|
||||
right_pixels.step();
|
||||
|
||||
if iteration % Wrapping(10) == Wrapping(0) {
|
||||
left_luma.step();
|
||||
right_luma.step();
|
||||
}
|
||||
|
||||
iteration += Wrapping(1u8);
|
||||
|
||||
if split_speed > 0 && split_pixel == pixels.width() {
|
||||
split_pixel = 0;
|
||||
|
||||
(left_luma, right_luma) = (right_luma, left_luma);
|
||||
(left_pixels, right_pixels) = (right_pixels, left_pixels);
|
||||
|
||||
randomize(&mut left_pixels.field);
|
||||
randomize(&mut left_luma.field);
|
||||
left_pixels.rules = generate_bb3();
|
||||
left_luma.rules = generate_u8b3();
|
||||
} else if split_speed < 0 && split_pixel == 0 {
|
||||
split_pixel = pixels.width();
|
||||
|
||||
(left_luma, right_luma) = (right_luma, left_luma);
|
||||
(left_pixels, right_pixels) = (right_pixels, left_pixels);
|
||||
|
||||
randomize(&mut right_pixels.field);
|
||||
randomize(&mut right_luma.field);
|
||||
right_pixels.rules = generate_bb3();
|
||||
right_luma.rules = generate_u8b3();
|
||||
}
|
||||
|
||||
split_pixel =
|
||||
i32::clamp(split_pixel as i32 + split_speed, 0, pixels.width() as i32) as usize;
|
||||
|
||||
draw_pixels(
|
||||
&mut pixels,
|
||||
&left_pixels.field,
|
||||
&right_pixels.field,
|
||||
split_pixel,
|
||||
);
|
||||
draw_luma(
|
||||
&mut luma,
|
||||
&left_luma.field,
|
||||
&right_luma.field,
|
||||
split_pixel / 8,
|
||||
);
|
||||
send_to_screen(&connection, &pixels, &luma);
|
||||
|
||||
while event::poll(Duration::from_secs(0)).expect("could not poll") {
|
||||
match event::read().expect("could not read event").try_into() {
|
||||
Err(_) => {}
|
||||
Ok(AppEvent::RandomizeLeftPixels) => {
|
||||
randomize(&mut left_pixels.field);
|
||||
println_debug("randomized left pixels");
|
||||
}
|
||||
Ok(AppEvent::RandomizeRightPixels) => {
|
||||
randomize(&mut right_pixels.field);
|
||||
println_info("randomized right pixels");
|
||||
}
|
||||
Ok(AppEvent::RandomizeLeftLuma) => {
|
||||
randomize(&mut left_luma.field);
|
||||
println_info("randomized left luma");
|
||||
}
|
||||
Ok(AppEvent::RandomizeRightLuma) => {
|
||||
randomize(&mut right_luma.field);
|
||||
println_info("randomized right luma");
|
||||
}
|
||||
Ok(AppEvent::SeparatorAccelerate) => {
|
||||
split_speed += 1;
|
||||
println_info(format!("increased separator speed to {split_speed}"));
|
||||
}
|
||||
Ok(AppEvent::SeparatorDecelerate) => {
|
||||
split_speed -= 1;
|
||||
println_info(format!("decreased separator speed to {split_speed}"));
|
||||
}
|
||||
Ok(AppEvent::Close) => {
|
||||
println_warning("terminating");
|
||||
de_init();
|
||||
return;
|
||||
}
|
||||
Ok(AppEvent::SimulationSpeedUp) => {
|
||||
target_duration = target_duration.saturating_sub(Duration::from_millis(1));
|
||||
println_info(format!("increased simulation speed to {} ups", 1f64 / target_duration.as_secs_f64()));
|
||||
}
|
||||
Ok(AppEvent::SimulationSpeedDown) => {
|
||||
target_duration = target_duration.saturating_add(Duration::from_millis(1));
|
||||
println_info(format!("decreased simulation speed to {} ups", 1f64 / target_duration.as_secs_f64()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let tick_time = start.elapsed();
|
||||
if tick_time < target_duration {
|
||||
thread::sleep(target_duration - tick_time);
|
||||
}
|
||||
let mut app = App::new(Cli::parse());
|
||||
while !app.terminated() {
|
||||
app.run_iteration();
|
||||
}
|
||||
}
|
||||
|
||||
enum AppEvent {
|
||||
Close,
|
||||
RandomizeLeftPixels,
|
||||
RandomizeRightPixels,
|
||||
RandomizeLeftLuma,
|
||||
RandomizeRightLuma,
|
||||
SeparatorAccelerate,
|
||||
SeparatorDecelerate,
|
||||
SimulationSpeedUp,
|
||||
SimulationSpeedDown,
|
||||
}
|
||||
|
||||
impl TryFrom<Event> for AppEvent {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(event: Event) -> Result<Self, Self::Error> {
|
||||
match event {
|
||||
Event::Key(key_event) if key_event.kind == KeyEventKind::Press => {
|
||||
match key_event.code {
|
||||
KeyCode::Char('h') => {
|
||||
println_info("[h] help");
|
||||
println_info("[q] quit");
|
||||
println_info("[d] randomize left pixels");
|
||||
println_info("[e] randomize left luma");
|
||||
println_info("[r] randomize right pixels");
|
||||
println_info("[f] randomize right luma");
|
||||
println_info("[→] accelerate divider right");
|
||||
println_info("[←] accelerate divider left");
|
||||
Err(())
|
||||
}
|
||||
KeyCode::Char('q') => Ok(AppEvent::Close),
|
||||
KeyCode::Char('d') => Ok(AppEvent::RandomizeLeftPixels),
|
||||
KeyCode::Char('e') => Ok(AppEvent::RandomizeLeftLuma),
|
||||
KeyCode::Char('f') => Ok(AppEvent::RandomizeRightPixels),
|
||||
KeyCode::Char('r') => Ok(AppEvent::RandomizeRightLuma),
|
||||
KeyCode::Right => Ok(AppEvent::SeparatorAccelerate),
|
||||
KeyCode::Left => Ok(AppEvent::SeparatorDecelerate),
|
||||
KeyCode::Up => Ok(AppEvent::SimulationSpeedUp),
|
||||
KeyCode::Down => Ok(AppEvent::SimulationSpeedDown),
|
||||
key_code => {
|
||||
println_debug(format!("unhandled KeyCode {key_code:?}"));
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
event => {
|
||||
println_debug(format!("unhandled event {event:?}"));
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_pixels(pixels: &mut PixelGrid, left: &PixelGrid, right: &PixelGrid, split_index: usize) {
|
||||
for x in 0..pixels.width() {
|
||||
let left_or_right = if x < split_index { left } else { right };
|
||||
for y in 0..pixels.height() {
|
||||
let set = x == split_index || left_or_right.get(x, y);
|
||||
pixels.set(x, y, set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_luma(luma: &mut ByteGrid, left: &ByteGrid, right: &ByteGrid, split_tile: usize) {
|
||||
for x in 0..luma.width() {
|
||||
let left_or_right = if x < split_tile { left } else { right };
|
||||
for y in 0..luma.height() {
|
||||
let set = u8::max(48, left_or_right.get(x, y));
|
||||
|
||||
let set = set as f32 / u8::MAX as f32 * 12f32;
|
||||
|
||||
luma.set(x, y, set as u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn send_to_screen(connection: &Connection, pixels: &PixelGrid, luma: &ByteGrid) {
|
||||
let pixel_cmd = BitmapLinearWin(Origin(0, 0), pixels.clone(), CompressionCode::Uncompressed);
|
||||
connection
|
||||
.send(pixel_cmd.into())
|
||||
.expect("could not send pixels");
|
||||
|
||||
connection
|
||||
.send(CharBrightness(Origin(0, 0), luma.clone()).into())
|
||||
.expect("could not send brightness");
|
||||
}
|
||||
|
||||
fn randomize<TGrid, TValue>(field: &mut TGrid)
|
||||
where
|
||||
TGrid: Grid<TValue>,
|
||||
Standard: Distribution<TValue>,
|
||||
{
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
for y in 0..field.height() {
|
||||
for x in 0..field.width() {
|
||||
field.set(x, y, rng.gen());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn init() -> Connection {
|
||||
env_logger::builder()
|
||||
.filter_level(LevelFilter::Info)
|
||||
.parse_default_env()
|
||||
.init();
|
||||
|
||||
execute!(stdout(), EnterAlternateScreen, EnableLineWrap)
|
||||
.expect("could not enter alternate screen");
|
||||
enable_raw_mode().expect("could not enable raw terminal mode");
|
||||
|
||||
Connection::open(Cli::parse().destination)
|
||||
.expect("Could not connect. Did you forget `--destination`?")
|
||||
}
|
||||
|
||||
fn de_init() {
|
||||
disable_raw_mode().expect("could not disable raw terminal mode");
|
||||
execute!(stdout(), LeaveAlternateScreen).expect("could not leave alternate screen");
|
||||
}
|
||||
|
|
76
src/rules.rs
76
src/rules.rs
|
@ -1,30 +1,30 @@
|
|||
use rand::rngs::ThreadRng;
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
use servicepoint::Value;
|
||||
use crate::print::println_info;
|
||||
|
||||
const MAX_BRIGHTNESS: u8 = 12;
|
||||
|
||||
pub struct Rules<TState, TKernel, const KERNEL_SIZE: usize>
|
||||
where
|
||||
TState: Copy + PartialEq,
|
||||
TKernel: Copy,
|
||||
pub struct Rules<T: Value>
|
||||
{
|
||||
pub kernel: [[TKernel; KERNEL_SIZE]; KERNEL_SIZE],
|
||||
pub count_neighbor: Box<dyn Fn(TState, TKernel) -> i32>,
|
||||
pub next_state: Box<dyn Fn(TState, i32) -> TState>,
|
||||
pub kernel: Kernel3x3,
|
||||
pub count_neighbor: Box<dyn Fn(T, bool) -> i32>,
|
||||
pub next_state: Box<dyn Fn(T, i32) -> T>,
|
||||
}
|
||||
|
||||
pub const MOORE_NEIGHBORHOOD: [[bool; 3]; 3] =
|
||||
[[true, true, true], [true, false, true], [true, true, true]];
|
||||
type Kernel3x3 = [[bool; 3]; 3];
|
||||
|
||||
pub const NEUMANN_NEIGHBORHOOD: [[bool; 3]; 3] = [
|
||||
pub const MOORE_NEIGHBORHOOD: Kernel3x3 = [
|
||||
[true, true, true],
|
||||
[true, false, true],
|
||||
[true, true, true]
|
||||
];
|
||||
|
||||
pub const NEUMANN_NEIGHBORHOOD: Kernel3x3 = [
|
||||
[false, true, false],
|
||||
[true, false, true],
|
||||
[false, true, false],
|
||||
];
|
||||
|
||||
pub const DIAGONALS_NEIGHBORHOOD: [[bool; 3]; 3] = [
|
||||
pub const DIAGONALS_NEIGHBORHOOD: Kernel3x3 = [
|
||||
[true, false, true],
|
||||
[false, false, false],
|
||||
[true, false, true],
|
||||
|
@ -39,16 +39,11 @@ pub fn count_true_neighbor(neighbor_state: bool, kernel_value: bool) -> i32 {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn generate_bb3() -> Rules<bool, bool, 3> {
|
||||
pub fn generate_bb3() -> Rules<bool> {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
let is_moore = rng.gen_bool(1.0 / 2.0);
|
||||
let kernel = if is_moore {
|
||||
MOORE_NEIGHBORHOOD
|
||||
} else {
|
||||
NEUMANN_NEIGHBORHOOD
|
||||
};
|
||||
let max_neighbors = if is_moore { 8 } else { 4 };
|
||||
let kernel = choose_neighborhood(&mut rng);
|
||||
let max_neighbors = count_max_neighbors(kernel);
|
||||
|
||||
let birth = generate_neighbor_counts(rng.gen_range(1..=max_neighbors), &mut rng, &[0]);
|
||||
let survive = generate_neighbor_counts(rng.gen_range(1..=max_neighbors), &mut rng, &[]);
|
||||
|
@ -78,17 +73,11 @@ fn generate_neighbor_counts(count: u8, rng: &mut ThreadRng, exclude: &[i32]) ->
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn generate_u8b3() -> Rules<u8, bool, 3> {
|
||||
pub fn generate_u8b3() -> Rules<u8> {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
let kernel = match rng.gen_range(0..3) {
|
||||
0 => MOORE_NEIGHBORHOOD,
|
||||
1 => NEUMANN_NEIGHBORHOOD,
|
||||
2 => DIAGONALS_NEIGHBORHOOD,
|
||||
_ => panic!(),
|
||||
};
|
||||
|
||||
let alive_threshold = rng.gen();
|
||||
let kernel = choose_neighborhood(&mut rng);
|
||||
let alive_threshold = u8::max(1, rng.gen());
|
||||
|
||||
let birth = generate_neighbor_counts(rng.gen_range(1..=9), &mut rng, &[0]);
|
||||
let survive = generate_neighbor_counts(
|
||||
|
@ -97,8 +86,8 @@ pub fn generate_u8b3() -> Rules<u8, bool, 3> {
|
|||
&[],
|
||||
);
|
||||
|
||||
let add = rng.gen_range(5..40);
|
||||
let sub = rng.gen_range(5..40);
|
||||
let add = rng.gen_range(1..15);
|
||||
let sub = rng.gen_range(1..15);
|
||||
|
||||
println_info(format!("generated u8b3: Birth {birth:?} Survival {survive:?}, kernel: {kernel:?}, alive_thresh: {alive_threshold}, delta: {add}/{sub}"));
|
||||
|
||||
|
@ -115,3 +104,24 @@ pub fn generate_u8b3() -> Rules<u8, bool, 3> {
|
|||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn choose_neighborhood(rng: &mut ThreadRng) -> Kernel3x3 {
|
||||
match rng.gen_range(0..3) {
|
||||
0 => MOORE_NEIGHBORHOOD,
|
||||
1 => NEUMANN_NEIGHBORHOOD,
|
||||
2 => DIAGONALS_NEIGHBORHOOD,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn count_max_neighbors<const SIZE: usize>(kernel: [[bool; SIZE]; SIZE]) -> u8 {
|
||||
let mut result = 0;
|
||||
for row in kernel {
|
||||
for cell in row {
|
||||
if cell {
|
||||
result += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
|
179
src/simulation.rs
Normal file
179
src/simulation.rs
Normal file
|
@ -0,0 +1,179 @@
|
|||
use crate::{
|
||||
game::Game,
|
||||
print::{println_debug, println_info},
|
||||
rules::{generate_bb3, generate_u8b3},
|
||||
};
|
||||
use rand::{distributions::Standard, prelude::Distribution, Rng};
|
||||
use servicepoint::{
|
||||
Bitmap, Brightness, BrightnessGrid, Grid, Value, ValueGrid, PIXEL_HEIGHT, PIXEL_WIDTH,
|
||||
TILE_HEIGHT, TILE_SIZE, TILE_WIDTH,
|
||||
};
|
||||
use std::num::Wrapping;
|
||||
|
||||
pub(crate) struct Simulation {
|
||||
pub(crate) left_pixels: Game<bool>,
|
||||
pub(crate) right_pixels: Game<bool>,
|
||||
pub(crate) left_luma: Game<u8>,
|
||||
pub(crate) right_luma: Game<u8>,
|
||||
split_pixel: usize,
|
||||
pub(crate) split_speed: i32,
|
||||
iteration: Wrapping<u8>,
|
||||
}
|
||||
|
||||
pub enum SimulationEvent {
|
||||
RandomizeLeftPixels,
|
||||
RandomizeRightPixels,
|
||||
RandomizeLeftLuma,
|
||||
RandomizeRightLuma,
|
||||
SeparatorAccelerate,
|
||||
SeparatorDecelerate,
|
||||
}
|
||||
|
||||
impl Simulation {
|
||||
pub fn new() -> Simulation {
|
||||
let left_pixels = Game {
|
||||
rules: generate_bb3(),
|
||||
field: make_randomized(PIXEL_WIDTH, PIXEL_HEIGHT),
|
||||
};
|
||||
let right_pixels = Game {
|
||||
rules: generate_bb3(),
|
||||
field: make_randomized(PIXEL_WIDTH, PIXEL_HEIGHT),
|
||||
};
|
||||
let left_luma = Game {
|
||||
rules: generate_u8b3(),
|
||||
field: make_randomized(TILE_WIDTH, TILE_HEIGHT),
|
||||
};
|
||||
let right_luma = Game {
|
||||
rules: generate_u8b3(),
|
||||
field: make_randomized(TILE_WIDTH, TILE_HEIGHT),
|
||||
};
|
||||
|
||||
Self {
|
||||
left_pixels,
|
||||
right_pixels,
|
||||
left_luma,
|
||||
right_luma,
|
||||
split_pixel: 0,
|
||||
split_speed: 1,
|
||||
iteration: Wrapping(0u8),
|
||||
}
|
||||
}
|
||||
|
||||
fn swap_left_right(&mut self) {
|
||||
std::mem::swap(&mut self.left_luma, &mut self.right_luma);
|
||||
std::mem::swap(&mut self.left_pixels, &mut self.right_pixels);
|
||||
}
|
||||
|
||||
fn regenerate(pixels: &mut Game<bool>, luma: &mut Game<u8>) {
|
||||
randomize(&mut pixels.field);
|
||||
randomize(&mut luma.field);
|
||||
pixels.rules = generate_bb3();
|
||||
luma.rules = generate_u8b3();
|
||||
}
|
||||
|
||||
pub(crate) fn run_iteration(&mut self) {
|
||||
self.left_pixels.step();
|
||||
self.right_pixels.step();
|
||||
|
||||
self.left_luma.step();
|
||||
self.right_luma.step();
|
||||
|
||||
self.iteration += Wrapping(1u8);
|
||||
|
||||
if self.split_speed > 0 && self.split_pixel == self.left_pixels.field.width() {
|
||||
self.split_pixel = 0;
|
||||
self.swap_left_right();
|
||||
Self::regenerate(&mut self.left_pixels, &mut self.left_luma);
|
||||
} else if self.split_speed < 0 && self.split_pixel == 0 {
|
||||
self.split_pixel = self.left_pixels.field.width();
|
||||
self.swap_left_right();
|
||||
Self::regenerate(&mut self.right_pixels, &mut self.right_luma);
|
||||
}
|
||||
|
||||
self.split_pixel = i32::clamp(
|
||||
self.split_pixel as i32 + self.split_speed,
|
||||
0,
|
||||
self.left_pixels.field.width() as i32,
|
||||
) as usize;
|
||||
}
|
||||
|
||||
pub(crate) fn draw_state(&self, pixels: &mut Bitmap, luma: &mut BrightnessGrid) {
|
||||
for x in 0..pixels.width() {
|
||||
let left_or_right = if x < self.split_pixel {
|
||||
&self.left_pixels.field
|
||||
} else {
|
||||
&self.right_pixels.field
|
||||
};
|
||||
for y in 0..pixels.height() {
|
||||
let set = x == self.split_pixel || left_or_right.get(x, y);
|
||||
pixels.set(x, y, set);
|
||||
}
|
||||
}
|
||||
|
||||
let split_tile = self.split_pixel / TILE_SIZE;
|
||||
for x in 0..luma.width() {
|
||||
let left_or_right = if x < split_tile {
|
||||
&self.left_luma.field
|
||||
} else {
|
||||
&self.right_luma.field
|
||||
};
|
||||
for y in 0..luma.height() {
|
||||
let set = left_or_right.get(x, y) as f32 / u8::MAX as f32 * u8::from(Brightness::MAX) as f32;
|
||||
let set = (set as u8).max(1);
|
||||
let set = Brightness::try_from(set).unwrap();
|
||||
luma.set(x, y, set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn handle_event(&mut self, event: SimulationEvent) {
|
||||
match event {
|
||||
SimulationEvent::RandomizeLeftPixels => {
|
||||
randomize(&mut self.left_pixels.field);
|
||||
println_debug("randomized left pixels");
|
||||
}
|
||||
SimulationEvent::RandomizeRightPixels => {
|
||||
randomize(&mut self.right_pixels.field);
|
||||
println_info("randomized right pixels");
|
||||
}
|
||||
SimulationEvent::RandomizeLeftLuma => {
|
||||
randomize(&mut self.left_luma.field);
|
||||
println_info("randomized left luma");
|
||||
}
|
||||
SimulationEvent::RandomizeRightLuma => {
|
||||
randomize(&mut self.right_luma.field);
|
||||
println_info("randomized right luma");
|
||||
}
|
||||
SimulationEvent::SeparatorAccelerate => {
|
||||
self.split_speed += 1;
|
||||
println_info(format!("increased separator speed to {}", self.split_speed));
|
||||
}
|
||||
SimulationEvent::SeparatorDecelerate => {
|
||||
self.split_speed -= 1;
|
||||
println_info(format!("decreased separator speed to {}", self.split_speed));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_randomized<T: Value>(width: usize, height: usize) -> ValueGrid<T>
|
||||
where
|
||||
Standard: Distribution<T>,
|
||||
{
|
||||
let mut grid = ValueGrid::new(width, height);
|
||||
randomize(&mut grid);
|
||||
grid
|
||||
}
|
||||
|
||||
fn randomize<T: Value>(field: &mut ValueGrid<T>)
|
||||
where
|
||||
Standard: Distribution<T>,
|
||||
{
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
for y in 0..field.height() {
|
||||
for x in 0..field.width() {
|
||||
field.set(x, y, rng.gen());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue