implement upgrade system
This commit is contained in:
		
							parent
							
								
									64f4ea529a
								
							
						
					
					
						commit
						3468fff882
					
				
					 7 changed files with 559 additions and 101 deletions
				
			
		
							
								
								
									
										275
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										275
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -2,6 +2,65 @@
 | 
			
		|||
# It is not intended for manual editing.
 | 
			
		||||
version = 4
 | 
			
		||||
 | 
			
		||||
[[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.19"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "anstyle",
 | 
			
		||||
 "anstyle-parse",
 | 
			
		||||
 "anstyle-query",
 | 
			
		||||
 "anstyle-wincon",
 | 
			
		||||
 "colorchoice",
 | 
			
		||||
 "is_terminal_polyfill",
 | 
			
		||||
 "utf8parse",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "anstyle"
 | 
			
		||||
version = "1.0.11"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "anstyle-parse"
 | 
			
		||||
version = "0.2.7"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "utf8parse",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "anstyle-query"
 | 
			
		||||
version = "1.1.3"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "windows-sys",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "anstyle-wincon"
 | 
			
		||||
version = "3.0.9"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "anstyle",
 | 
			
		||||
 "once_cell_polyfill",
 | 
			
		||||
 "windows-sys",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "bitvec"
 | 
			
		||||
version = "1.0.1"
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +73,35 @@ dependencies = [
 | 
			
		|||
 "wyz",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "colorchoice"
 | 
			
		||||
version = "1.0.4"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "env_filter"
 | 
			
		||||
version = "0.1.3"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "log",
 | 
			
		||||
 "regex",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "env_logger"
 | 
			
		||||
version = "0.11.8"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "anstream",
 | 
			
		||||
 "anstyle",
 | 
			
		||||
 "env_filter",
 | 
			
		||||
 "jiff",
 | 
			
		||||
 "log",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "funty"
 | 
			
		||||
version = "2.0.0"
 | 
			
		||||
| 
						 | 
				
			
			@ -31,24 +119,81 @@ dependencies = [
 | 
			
		|||
 "syn",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "is_terminal_polyfill"
 | 
			
		||||
version = "1.70.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "jiff"
 | 
			
		||||
version = "0.2.15"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "jiff-static",
 | 
			
		||||
 "log",
 | 
			
		||||
 "portable-atomic",
 | 
			
		||||
 "portable-atomic-util",
 | 
			
		||||
 "serde",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "jiff-static"
 | 
			
		||||
version = "0.2.15"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
 "quote",
 | 
			
		||||
 "syn",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "log"
 | 
			
		||||
version = "0.4.27"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "memchr"
 | 
			
		||||
version = "2.7.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "once_cell"
 | 
			
		||||
version = "1.21.3"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "once_cell_polyfill"
 | 
			
		||||
version = "1.70.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "pkg-config"
 | 
			
		||||
version = "0.3.32"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "portable-atomic"
 | 
			
		||||
version = "1.11.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "portable-atomic-util"
 | 
			
		||||
version = "0.2.4"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "portable-atomic",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "proc-macro2"
 | 
			
		||||
version = "1.0.95"
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +218,35 @@ version = "0.7.0"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "regex"
 | 
			
		||||
version = "1.11.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "aho-corasick",
 | 
			
		||||
 "memchr",
 | 
			
		||||
 "regex-automata",
 | 
			
		||||
 "regex-syntax",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "regex-automata"
 | 
			
		||||
version = "0.4.9"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "aho-corasick",
 | 
			
		||||
 "memchr",
 | 
			
		||||
 "regex-syntax",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "regex-syntax"
 | 
			
		||||
version = "0.8.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "rust-lzma"
 | 
			
		||||
version = "0.6.0"
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +257,26 @@ dependencies = [
 | 
			
		|||
 "vcpkg",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "serde"
 | 
			
		||||
version = "1.0.219"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "serde_derive",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "serde_derive"
 | 
			
		||||
version = "1.0.219"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
 "quote",
 | 
			
		||||
 "syn",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "servicepoint"
 | 
			
		||||
version = "0.16.0"
 | 
			
		||||
| 
						 | 
				
			
			@ -99,6 +293,8 @@ dependencies = [
 | 
			
		|||
name = "servicepoint-idle"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "env_logger",
 | 
			
		||||
 "log",
 | 
			
		||||
 "servicepoint",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -145,12 +341,91 @@ version = "1.0.18"
 | 
			
		|||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "utf8parse"
 | 
			
		||||
version = "0.2.2"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "vcpkg"
 | 
			
		||||
version = "0.2.15"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
 | 
			
		||||
 | 
			
		||||
[[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.52.6"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "windows_aarch64_gnullvm",
 | 
			
		||||
 "windows_aarch64_msvc",
 | 
			
		||||
 "windows_i686_gnu",
 | 
			
		||||
 "windows_i686_gnullvm",
 | 
			
		||||
 "windows_i686_msvc",
 | 
			
		||||
 "windows_x86_64_gnu",
 | 
			
		||||
 "windows_x86_64_gnullvm",
 | 
			
		||||
 "windows_x86_64_msvc",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_aarch64_gnullvm"
 | 
			
		||||
version = "0.52.6"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_aarch64_msvc"
 | 
			
		||||
version = "0.52.6"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_i686_gnu"
 | 
			
		||||
version = "0.52.6"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_i686_gnullvm"
 | 
			
		||||
version = "0.52.6"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_i686_msvc"
 | 
			
		||||
version = "0.52.6"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_x86_64_gnu"
 | 
			
		||||
version = "0.52.6"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_x86_64_gnullvm"
 | 
			
		||||
version = "0.52.6"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_x86_64_msvc"
 | 
			
		||||
version = "0.52.6"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "wyz"
 | 
			
		||||
version = "0.5.1"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,4 +5,8 @@ edition = "2024"
 | 
			
		|||
 | 
			
		||||
[dependencies.servicepoint]
 | 
			
		||||
version = "0.16.0"
 | 
			
		||||
path = "../servicepoint-uniffi3"
 | 
			
		||||
path = "../servicepoint-uniffi3"
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
env_logger = "0.11.8"
 | 
			
		||||
log = "0.4.27"
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +47,8 @@
 | 
			
		|||
              xz
 | 
			
		||||
              pkg-config
 | 
			
		||||
            ];
 | 
			
		||||
            RUST_LOG="debug";
 | 
			
		||||
            RUST_BACKTRACE = "1";
 | 
			
		||||
            RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
 | 
			
		||||
          };
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										59
									
								
								src/bar.rs
									
										
									
									
									
								
							
							
						
						
									
										59
									
								
								src/bar.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,49 +1,60 @@
 | 
			
		|||
use crate::{Currency, Progressable};
 | 
			
		||||
use servicepoint::{GridMut};
 | 
			
		||||
use servicepoint::{CharGridMutExt, GridMut, WindowMut};
 | 
			
		||||
use std::time::Duration;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
#[derive(Debug, Clone, Copy)]
 | 
			
		||||
pub struct Bar {
 | 
			
		||||
    name: &'static str,
 | 
			
		||||
    pub(crate) enabled: bool,
 | 
			
		||||
    progress: f64,
 | 
			
		||||
    speed: f64,
 | 
			
		||||
    factor: f64,
 | 
			
		||||
    pub(crate) speed: f64,
 | 
			
		||||
    pub(crate) productivity: f64,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Bar {
 | 
			
		||||
    pub(crate) fn new(factor: f64, speed: f64) -> Self {
 | 
			
		||||
    pub(crate) fn new(productivity: f64, speed: f64, name: &'static str) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            factor,
 | 
			
		||||
            name,
 | 
			
		||||
            enabled: false,
 | 
			
		||||
            productivity,
 | 
			
		||||
            progress: 0f64,
 | 
			
		||||
            speed,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub(crate) fn add_speed(&self, speed: f64) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            speed: self.speed + speed,
 | 
			
		||||
            ..*self
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub(crate) fn is_enabled(&self) -> bool {
 | 
			
		||||
        self.speed > 0.0
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Progressable for Bar {
 | 
			
		||||
    fn progress(&self, delta: Duration) -> (Self, Currency) {
 | 
			
		||||
        let extra_progress = delta.as_secs_f64() * self.speed;
 | 
			
		||||
impl Bar {
 | 
			
		||||
    pub(crate) fn progress(&mut self, delta: Duration) -> Currency {
 | 
			
		||||
        if !self.enabled {
 | 
			
		||||
            return 0.0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let extra_progress = delta.mul_f64(self.speed).as_secs_f64();
 | 
			
		||||
        let progress = self.progress + extra_progress;
 | 
			
		||||
        let completions = progress.floor();
 | 
			
		||||
        let progress = progress - completions;
 | 
			
		||||
        let currency = completions * self.factor;
 | 
			
		||||
        self.progress = progress - completions;
 | 
			
		||||
 | 
			
		||||
        (Self { progress, ..*self }, currency)
 | 
			
		||||
        completions * self.productivity
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Bar {
 | 
			
		||||
    pub fn draw<P: GridMut<bool>>(&self, bitmap: &mut P) {
 | 
			
		||||
    pub fn draw<C: GridMut<char>, P: GridMut<bool>>(&self, chars: &mut C, bitmap: &mut P) {
 | 
			
		||||
        if !self.enabled {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut bitmap = WindowMut::new(bitmap, 0, 0, bitmap.width() / 2, bitmap.height()).unwrap();
 | 
			
		||||
        let mut chars = WindowMut::new(
 | 
			
		||||
            chars,
 | 
			
		||||
            chars.width() / 2 + 1,
 | 
			
		||||
            0,
 | 
			
		||||
            chars.width() / 2 - 1,
 | 
			
		||||
            chars.height(),
 | 
			
		||||
        )
 | 
			
		||||
        .unwrap();
 | 
			
		||||
 | 
			
		||||
        chars.set_row_str(0, self.name).unwrap();
 | 
			
		||||
        bitmap.fill(false);
 | 
			
		||||
 | 
			
		||||
        let margin = 1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										157
									
								
								src/game.rs
									
										
									
									
									
								
							
							
						
						
									
										157
									
								
								src/game.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,92 +1,121 @@
 | 
			
		|||
use crate::{
 | 
			
		||||
    bar::Bar,
 | 
			
		||||
    Currency,
 | 
			
		||||
    Progressable
 | 
			
		||||
};
 | 
			
		||||
use servicepoint::{Bitmap, CharGrid, CharGridMutExt, WindowMut, TILE_SIZE};
 | 
			
		||||
use crate::upgrades::{Upgrade, get_upgrades};
 | 
			
		||||
use crate::{Currency, Progressable, bar::Bar};
 | 
			
		||||
use log::log;
 | 
			
		||||
use servicepoint::{Bitmap, CharGrid, CharGridMutExt, TILE_SIZE, WindowMut};
 | 
			
		||||
use std::collections::VecDeque;
 | 
			
		||||
use std::time::Duration;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub struct Game<const STEP_COUNT:usize=11> {
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub struct Game<const STEP_COUNT: usize = 11> {
 | 
			
		||||
    pub(crate) currency: Currency,
 | 
			
		||||
    pub(crate) bars: [Bar; STEP_COUNT],
 | 
			
		||||
    pub(crate) names: [&'static str; STEP_COUNT],
 | 
			
		||||
    unlocks: usize,
 | 
			
		||||
    unlock_queue: VecDeque<Upgrade>,
 | 
			
		||||
    total_currency: Currency,
 | 
			
		||||
    pub(crate) global_speed: f64,
 | 
			
		||||
    pub(crate) global_productivity: f64,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Game {
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            currency: 0f64,
 | 
			
		||||
            total_currency: 0f64,
 | 
			
		||||
            global_speed: 1f64,
 | 
			
		||||
            global_productivity: 1f64,
 | 
			
		||||
            unlocks: 0,
 | 
			
		||||
            unlock_queue: get_upgrades(),
 | 
			
		||||
            bars: [
 | 
			
		||||
                Bar::new(1f64,1.0),
 | 
			
		||||
                Bar::new(2f64, 0.5),
 | 
			
		||||
                Bar::new(4f64, 0.25),
 | 
			
		||||
                Bar::new(8f64,0.125),
 | 
			
		||||
                Bar::new(16f64, 0.0625),
 | 
			
		||||
                Bar::new(32f64, 0.03125),
 | 
			
		||||
                Bar::new(64f64, 0.015625),
 | 
			
		||||
                Bar::new(128f64, 0.0078125),
 | 
			
		||||
                Bar::new(256f64, 0.00390625),
 | 
			
		||||
                Bar::new(512f64, 0.001953125),
 | 
			
		||||
                Bar::new(1024f64,0.000976562),
 | 
			
		||||
            ],
 | 
			
		||||
            names: [
 | 
			
		||||
                "Powering infrastructure",
 | 
			
		||||
                "Dusting ServicePoint",
 | 
			
		||||
                "Activating colorful lights",
 | 
			
		||||
                "Dimming darkroom",
 | 
			
		||||
                "Refilling Matemat",
 | 
			
		||||
                "Pre-heating convectiomat",
 | 
			
		||||
                "Resetting chair heights",
 | 
			
		||||
                "Cleaning 'block chain'",
 | 
			
		||||
                "Refilling sticker box",
 | 
			
		||||
                "Setting room to public",
 | 
			
		||||
                "Welcoming creatures",
 | 
			
		||||
                Bar::new(1f64, 1.0, "Powering infrastructure"),
 | 
			
		||||
                Bar::new(2f64, 0.5, "Dusting ServicePoint"),
 | 
			
		||||
                Bar::new(4f64, 0.25, "Activating colorful lights"),
 | 
			
		||||
                Bar::new(8f64, 0.125, "Dimming darkroom"),
 | 
			
		||||
                Bar::new(16f64, 0.0625, "Refilling Matemat"),
 | 
			
		||||
                Bar::new(32f64, 0.03125, "Pre-heating convectiomat"),
 | 
			
		||||
                Bar::new(64f64, 0.015625, "Resetting chair heights"),
 | 
			
		||||
                Bar::new(128f64, 0.0078125, "Untangling 'block chain'"),
 | 
			
		||||
                Bar::new(256f64, 0.00390625, "Refilling sticker box"),
 | 
			
		||||
                Bar::new(512f64, 0.001953125, "Setting room to public"),
 | 
			
		||||
                Bar::new(1024f64, 0.000976562, "Welcoming creatures"),
 | 
			
		||||
            ],
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Progressable for Game {
 | 
			
		||||
    fn progress(&self, delta: Duration) -> (Self, Currency) {
 | 
			
		||||
        let mut currency = self.currency;
 | 
			
		||||
        let bars = self.bars.clone().map(|bar| {
 | 
			
		||||
            let (bar, curr) = bar.progress(delta);
 | 
			
		||||
            currency += curr;
 | 
			
		||||
            bar
 | 
			
		||||
        });
 | 
			
		||||
    pub(crate) fn progress(&mut self, delta: Duration) {
 | 
			
		||||
        let adjusted_delta = delta.mul_f64(self.global_speed);
 | 
			
		||||
 | 
			
		||||
        (
 | 
			
		||||
            Self {
 | 
			
		||||
                currency,
 | 
			
		||||
                bars,
 | 
			
		||||
                names: self.names,
 | 
			
		||||
            },
 | 
			
		||||
            0f64,
 | 
			
		||||
        )
 | 
			
		||||
        self.currency += self.global_productivity
 | 
			
		||||
            * self
 | 
			
		||||
                .bars
 | 
			
		||||
                .iter_mut()
 | 
			
		||||
                .map(|bar| bar.progress(adjusted_delta))
 | 
			
		||||
                .sum::<Currency>();
 | 
			
		||||
 | 
			
		||||
        if let Some(next_upgrade) = self.unlock_queue.front() {
 | 
			
		||||
            if next_upgrade.cost <= self.currency {
 | 
			
		||||
                log::info!("Applying upgrade {:?}", next_upgrade);
 | 
			
		||||
                let next_upgrade = self.unlock_queue.pop_front().unwrap();
 | 
			
		||||
                self.currency -= next_upgrade.cost;
 | 
			
		||||
                (next_upgrade.apply)(self);
 | 
			
		||||
                self.unlocks += 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Game {
 | 
			
		||||
    pub fn draw(&self, text_layer: &mut WindowMut<char, CharGrid>, pixel_layer: &mut WindowMut<bool, Bitmap>) {
 | 
			
		||||
        text_layer.set_row_str(0, "Discordia Boot Procedure").unwrap();
 | 
			
		||||
    pub(crate) fn draw(
 | 
			
		||||
        &self,
 | 
			
		||||
        text_layer: &mut WindowMut<char, CharGrid>,
 | 
			
		||||
        pixel_layer: &mut WindowMut<bool, Bitmap>,
 | 
			
		||||
    ) {
 | 
			
		||||
        text_layer
 | 
			
		||||
            .set_row_str(0, "Discordia Boot Procedure")
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        let middle = text_layer.width() / 2;
 | 
			
		||||
        text_layer.window_mut( middle, 0, middle, 1)
 | 
			
		||||
        text_layer
 | 
			
		||||
            .window_mut(middle, 0, middle, 1)
 | 
			
		||||
            .unwrap()
 | 
			
		||||
            .set_row_str(0, &format!(" Cycles: {}", self.currency.floor()))
 | 
			
		||||
            .set_row_str(0, &format!(" Completions: {}", self.currency.floor()))
 | 
			
		||||
            .unwrap();
 | 
			
		||||
 | 
			
		||||
        for (index, bar) in self.bars.iter().enumerate() {
 | 
			
		||||
            let row = 1 + index;
 | 
			
		||||
            let mut bar_window = pixel_layer.window_mut(0, row * TILE_SIZE, pixel_layer.width() / 2, TILE_SIZE).unwrap();
 | 
			
		||||
            let mut label_window = text_layer.window_mut(middle, row, middle, 1).unwrap();
 | 
			
		||||
            let row = 2 + index;
 | 
			
		||||
            let mut bar_window = pixel_layer
 | 
			
		||||
                .window_mut(0, row * TILE_SIZE, pixel_layer.width(), TILE_SIZE)
 | 
			
		||||
                .unwrap();
 | 
			
		||||
            let mut label_window = text_layer
 | 
			
		||||
                .window_mut(0, row, text_layer.width(), 1)
 | 
			
		||||
                .unwrap();
 | 
			
		||||
            bar.draw(&mut label_window, &mut bar_window);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            if !bar.is_enabled() {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
        if let Some(next_upgrade) = self.unlock_queue.front() {
 | 
			
		||||
            text_layer
 | 
			
		||||
                .window_mut(0, text_layer.height() - 2, text_layer.width(), 1)
 | 
			
		||||
                .unwrap()
 | 
			
		||||
                .set_row_str(
 | 
			
		||||
                    0,
 | 
			
		||||
                    &format!("Next unlock: {} {}", next_upgrade.cost, next_upgrade.name),
 | 
			
		||||
                )
 | 
			
		||||
                .unwrap();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            bar.draw(&mut bar_window);
 | 
			
		||||
            label_window.set_row_str(0, self.names[index]).unwrap();
 | 
			
		||||
        text_layer
 | 
			
		||||
            .window_mut(0, text_layer.height() - 1, text_layer.width() / 2, 1)
 | 
			
		||||
            .unwrap()
 | 
			
		||||
            .set_row_str(0, &format!("Score: {}", self.total_currency))
 | 
			
		||||
            .unwrap();
 | 
			
		||||
 | 
			
		||||
        if self.unlocks > 0 {
 | 
			
		||||
            text_layer
 | 
			
		||||
                .window_mut(
 | 
			
		||||
                    text_layer.width() / 2,
 | 
			
		||||
                    text_layer.height() - 1,
 | 
			
		||||
                    text_layer.width() / 2,
 | 
			
		||||
                    1,
 | 
			
		||||
                )
 | 
			
		||||
                .unwrap()
 | 
			
		||||
                .set_row_str(0, &format!(" Unlocks: {}", self.unlocks))
 | 
			
		||||
                .unwrap();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										38
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										38
									
								
								src/main.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,13 +1,17 @@
 | 
			
		|||
use game::Game;
 | 
			
		||||
use servicepoint::{BinaryOperation, BitVecCommand, Bitmap, CharGrid, CharGridCommand, ClearCommand, CompressionCode, UdpSocketExt, FRAME_PACING, TILE_HEIGHT, TILE_WIDTH};
 | 
			
		||||
use servicepoint::{
 | 
			
		||||
    BinaryOperation, BitVecCommand, Bitmap, CharGrid, CharGridCommand, ClearCommand,
 | 
			
		||||
    CompressionCode, FRAME_PACING, TILE_HEIGHT, TILE_WIDTH, UdpSocketExt,
 | 
			
		||||
};
 | 
			
		||||
use std::{
 | 
			
		||||
    net::UdpSocket,
 | 
			
		||||
    thread::sleep,
 | 
			
		||||
    time::{Duration, Instant}
 | 
			
		||||
    time::{Duration, Instant},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
mod bar;
 | 
			
		||||
mod game;
 | 
			
		||||
mod upgrades;
 | 
			
		||||
 | 
			
		||||
type Currency = f64;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -20,6 +24,8 @@ const DESTINATION: &str = "127.0.0.1:2342";
 | 
			
		|||
//const DESTINATION: &str = "172.23.42.29:2342";
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    env_logger::init();
 | 
			
		||||
 | 
			
		||||
    let mut state = Game::new();
 | 
			
		||||
    let connection = UdpSocket::bind_connect(DESTINATION).unwrap();
 | 
			
		||||
    connection.send_command(ClearCommand);
 | 
			
		||||
| 
						 | 
				
			
			@ -33,22 +39,30 @@ fn main() {
 | 
			
		|||
        let delta = current_time - last_refresh;
 | 
			
		||||
        last_refresh = current_time;
 | 
			
		||||
 | 
			
		||||
        (state, _) = state.progress(delta);
 | 
			
		||||
        state.progress(delta);
 | 
			
		||||
 | 
			
		||||
        chars.fill(' ');
 | 
			
		||||
        pixels.fill(false);
 | 
			
		||||
 | 
			
		||||
        let mut chars_view = chars.window_mut(0, 0, chars.width(), chars.height()).unwrap();
 | 
			
		||||
        let mut pixels_view = pixels.window_mut(0,0,pixels.width(), pixels.height()).unwrap();
 | 
			
		||||
        let mut chars_view = chars
 | 
			
		||||
            .window_mut(0, 0, chars.width(), chars.height())
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        let mut pixels_view = pixels
 | 
			
		||||
            .window_mut(0, 0, pixels.width(), pixels.height())
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        state.draw(&mut chars_view, &mut pixels_view);
 | 
			
		||||
 | 
			
		||||
        connection.send_command(CharGridCommand::from(chars.clone())).unwrap();
 | 
			
		||||
        connection.send_command(BitVecCommand {
 | 
			
		||||
            bitvec: pixels.clone().into(),
 | 
			
		||||
            compression: CompressionCode::default(),
 | 
			
		||||
            operation: BinaryOperation::Or,
 | 
			
		||||
            offset: 0,
 | 
			
		||||
        }).unwrap();
 | 
			
		||||
        connection
 | 
			
		||||
            .send_command(CharGridCommand::from(chars.clone()))
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        connection
 | 
			
		||||
            .send_command(BitVecCommand {
 | 
			
		||||
                bitvec: pixels.clone().into(),
 | 
			
		||||
                compression: CompressionCode::default(),
 | 
			
		||||
                operation: BinaryOperation::Or,
 | 
			
		||||
                offset: 0,
 | 
			
		||||
            })
 | 
			
		||||
            .unwrap();
 | 
			
		||||
 | 
			
		||||
        sleep(FRAME_PACING);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										123
									
								
								src/upgrades.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/upgrades.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,123 @@
 | 
			
		|||
use crate::Currency;
 | 
			
		||||
use crate::game::Game;
 | 
			
		||||
use std::collections::VecDeque;
 | 
			
		||||
use std::fmt::{Debug, Formatter, Write};
 | 
			
		||||
 | 
			
		||||
pub(crate) struct Upgrade {
 | 
			
		||||
    pub(crate) name: &'static str,
 | 
			
		||||
    pub(crate) cost: Currency,
 | 
			
		||||
    pub(crate) apply: Box<dyn Fn(&mut Game)>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Debug for Upgrade {
 | 
			
		||||
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
 | 
			
		||||
        f.write_fmt(format_args!(
 | 
			
		||||
            "Upgrade {{ name: {:?}, cost: {:?} }}",
 | 
			
		||||
            self.name, self.cost
 | 
			
		||||
        ))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(crate) fn get_upgrades() -> VecDeque<Upgrade> {
 | 
			
		||||
    vec![
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "Start Powering infrastructure",
 | 
			
		||||
            cost: 0f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.bars[0].enabled = true;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "More power",
 | 
			
		||||
            cost: 10f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.bars[0].productivity *= 2.0;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "",
 | 
			
		||||
            cost: 23f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.global_productivity *= 1.1;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "The answer",
 | 
			
		||||
            cost: 42f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.global_speed *= 1.1;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "Start Dusting ServicePoint",
 | 
			
		||||
            cost: 64f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.bars[1].enabled = true;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "Start Activating colorful lights",
 | 
			
		||||
            cost: 256f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.bars[2].enabled = true;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "Start Dimming darkroom",
 | 
			
		||||
            cost: 1024f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.bars[3].enabled = true;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "Start Refilling Matemat",
 | 
			
		||||
            cost: 4096f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.bars[4].enabled = true;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "Start Pre-heating convectiomat",
 | 
			
		||||
            cost: 16384f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.bars[5].enabled = true;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "Start Resetting chair heights",
 | 
			
		||||
            cost: 65536f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.bars[6].enabled = true;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "Start Untangling 'block chain'",
 | 
			
		||||
            cost: 262144f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.bars[7].enabled = true;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "Start Refilling sticker box",
 | 
			
		||||
            cost: 1048576f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.bars[8].enabled = true;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "Start Setting room to public",
 | 
			
		||||
            cost: 4194304f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.bars[9].enabled = true;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
        Upgrade {
 | 
			
		||||
            name: "Start Welcoming creatures",
 | 
			
		||||
            cost: 16777216f64,
 | 
			
		||||
            apply: Box::new(|game| {
 | 
			
		||||
                game.bars[10].enabled = true;
 | 
			
		||||
            }),
 | 
			
		||||
        },
 | 
			
		||||
    ]
 | 
			
		||||
    .into()
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue