├── .babelrc ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── Web.toml ├── docs ├── favicon.ico ├── impact.css ├── impact.js ├── impact.wasm └── index.html ├── package.json ├── pnpm-lock.yaml ├── postcss.config.js ├── rollup.config.js ├── scss └── impact.scss ├── src ├── components │ ├── control_container.rs │ ├── map_container.rs │ ├── messages_container.rs │ ├── mod.rs │ ├── player_container.rs │ └── resource_container.rs ├── main.rs └── types │ ├── actions.rs │ ├── buttons.rs │ ├── flags.rs │ ├── messages.rs │ ├── mod.rs │ ├── player.rs │ ├── resources.rs │ ├── tiles.rs │ ├── time.rs │ └── transformers.rs └── static ├── favicon.ico └── index.html /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/env", 5 | { 6 | "modules": false 7 | } 8 | ] 9 | ] 10 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /css 3 | /target 4 | **/*.rs.bk 5 | /release 6 | static/*.css 7 | .#* 8 | .vscode* 9 | /rls 10 | *.log -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "anymap" 5 | version = "0.12.1" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | 8 | [[package]] 9 | name = "backtrace" 10 | version = "0.3.44" 11 | source = "registry+https://github.com/rust-lang/crates.io-index" 12 | dependencies = [ 13 | "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", 14 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 15 | "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)", 16 | "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 17 | ] 18 | 19 | [[package]] 20 | name = "backtrace-sys" 21 | version = "0.1.32" 22 | source = "registry+https://github.com/rust-lang/crates.io-index" 23 | dependencies = [ 24 | "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", 25 | "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)", 26 | ] 27 | 28 | [[package]] 29 | name = "base-x" 30 | version = "0.2.6" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | 33 | [[package]] 34 | name = "bincode" 35 | version = "1.0.1" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | dependencies = [ 38 | "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 39 | "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", 40 | ] 41 | 42 | [[package]] 43 | name = "boolinator" 44 | version = "2.4.0" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | 47 | [[package]] 48 | name = "bumpalo" 49 | version = "3.2.0" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | 52 | [[package]] 53 | name = "byteorder" 54 | version = "1.3.4" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | 57 | [[package]] 58 | name = "bytes" 59 | version = "0.4.12" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | dependencies = [ 62 | "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 63 | "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 64 | ] 65 | 66 | [[package]] 67 | name = "cc" 68 | version = "1.0.50" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | 71 | [[package]] 72 | name = "cfg-if" 73 | version = "0.1.10" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | 76 | [[package]] 77 | name = "discard" 78 | version = "1.0.4" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | 81 | [[package]] 82 | name = "failure" 83 | version = "0.1.6" 84 | source = "registry+https://github.com/rust-lang/crates.io-index" 85 | dependencies = [ 86 | "backtrace 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)", 87 | "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 88 | ] 89 | 90 | [[package]] 91 | name = "failure_derive" 92 | version = "0.1.6" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | dependencies = [ 95 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 96 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 97 | "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", 98 | "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", 99 | ] 100 | 101 | [[package]] 102 | name = "fnv" 103 | version = "1.0.6" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | 106 | [[package]] 107 | name = "http" 108 | version = "0.1.21" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | dependencies = [ 111 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 112 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 113 | "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 114 | ] 115 | 116 | [[package]] 117 | name = "impact" 118 | version = "0.1.1" 119 | dependencies = [ 120 | "stdweb 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", 121 | "yew 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 122 | ] 123 | 124 | [[package]] 125 | name = "iovec" 126 | version = "0.1.4" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | dependencies = [ 129 | "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)", 130 | ] 131 | 132 | [[package]] 133 | name = "itoa" 134 | version = "0.4.5" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | 137 | [[package]] 138 | name = "lazy_static" 139 | version = "1.4.0" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | 142 | [[package]] 143 | name = "libc" 144 | version = "0.2.67" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | 147 | [[package]] 148 | name = "log" 149 | version = "0.4.8" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | dependencies = [ 152 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 153 | ] 154 | 155 | [[package]] 156 | name = "proc-macro-hack" 157 | version = "0.5.11" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | dependencies = [ 160 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 161 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 162 | "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", 163 | ] 164 | 165 | [[package]] 166 | name = "proc-macro-nested" 167 | version = "0.1.3" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | 170 | [[package]] 171 | name = "proc-macro2" 172 | version = "0.4.30" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | dependencies = [ 175 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 176 | ] 177 | 178 | [[package]] 179 | name = "proc-macro2" 180 | version = "1.0.9" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | dependencies = [ 183 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 184 | ] 185 | 186 | [[package]] 187 | name = "quote" 188 | version = "0.6.13" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | dependencies = [ 191 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 192 | ] 193 | 194 | [[package]] 195 | name = "quote" 196 | version = "1.0.2" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | dependencies = [ 199 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 200 | ] 201 | 202 | [[package]] 203 | name = "rustc-demangle" 204 | version = "0.1.16" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | 207 | [[package]] 208 | name = "rustc_version" 209 | version = "0.2.3" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | dependencies = [ 212 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 213 | ] 214 | 215 | [[package]] 216 | name = "ryu" 217 | version = "1.0.2" 218 | source = "registry+https://github.com/rust-lang/crates.io-index" 219 | 220 | [[package]] 221 | name = "semver" 222 | version = "0.9.0" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | dependencies = [ 225 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 226 | ] 227 | 228 | [[package]] 229 | name = "semver-parser" 230 | version = "0.7.0" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | 233 | [[package]] 234 | name = "serde" 235 | version = "1.0.104" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | dependencies = [ 238 | "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", 239 | ] 240 | 241 | [[package]] 242 | name = "serde_derive" 243 | version = "1.0.104" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | dependencies = [ 246 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 247 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 248 | "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", 249 | ] 250 | 251 | [[package]] 252 | name = "serde_json" 253 | version = "1.0.48" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | dependencies = [ 256 | "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 257 | "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 258 | "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", 259 | ] 260 | 261 | [[package]] 262 | name = "sha1" 263 | version = "0.6.0" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | 266 | [[package]] 267 | name = "slab" 268 | version = "0.4.2" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | 271 | [[package]] 272 | name = "stdweb" 273 | version = "0.4.20" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | dependencies = [ 276 | "discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 277 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 278 | "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", 279 | "serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", 280 | "stdweb-derive 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 281 | "stdweb-internal-macros 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 282 | "stdweb-internal-runtime 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 283 | "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", 284 | ] 285 | 286 | [[package]] 287 | name = "stdweb-derive" 288 | version = "0.5.3" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | dependencies = [ 291 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 292 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 293 | "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", 294 | "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", 295 | "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", 296 | ] 297 | 298 | [[package]] 299 | name = "stdweb-internal-macros" 300 | version = "0.2.9" 301 | source = "registry+https://github.com/rust-lang/crates.io-index" 302 | dependencies = [ 303 | "base-x 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 304 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 305 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 306 | "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", 307 | "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", 308 | "serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", 309 | "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 310 | "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", 311 | ] 312 | 313 | [[package]] 314 | name = "stdweb-internal-runtime" 315 | version = "0.1.5" 316 | source = "registry+https://github.com/rust-lang/crates.io-index" 317 | 318 | [[package]] 319 | name = "syn" 320 | version = "0.15.44" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | dependencies = [ 323 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 324 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 325 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 326 | ] 327 | 328 | [[package]] 329 | name = "syn" 330 | version = "1.0.16" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | dependencies = [ 333 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 334 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 335 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 336 | ] 337 | 338 | [[package]] 339 | name = "synstructure" 340 | version = "0.12.3" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | dependencies = [ 343 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 344 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 345 | "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", 346 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 347 | ] 348 | 349 | [[package]] 350 | name = "unicode-xid" 351 | version = "0.1.0" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | 354 | [[package]] 355 | name = "unicode-xid" 356 | version = "0.2.0" 357 | source = "registry+https://github.com/rust-lang/crates.io-index" 358 | 359 | [[package]] 360 | name = "wasm-bindgen" 361 | version = "0.2.58" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | dependencies = [ 364 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 365 | "wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", 366 | ] 367 | 368 | [[package]] 369 | name = "wasm-bindgen-backend" 370 | version = "0.2.58" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | dependencies = [ 373 | "bumpalo 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 374 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 375 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 376 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 377 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 378 | "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", 379 | "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", 380 | ] 381 | 382 | [[package]] 383 | name = "wasm-bindgen-macro" 384 | version = "0.2.58" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | dependencies = [ 387 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 388 | "wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", 389 | ] 390 | 391 | [[package]] 392 | name = "wasm-bindgen-macro-support" 393 | version = "0.2.58" 394 | source = "registry+https://github.com/rust-lang/crates.io-index" 395 | dependencies = [ 396 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 397 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 398 | "syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", 399 | "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", 400 | "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", 401 | ] 402 | 403 | [[package]] 404 | name = "wasm-bindgen-shared" 405 | version = "0.2.58" 406 | source = "registry+https://github.com/rust-lang/crates.io-index" 407 | 408 | [[package]] 409 | name = "yew" 410 | version = "0.7.0" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | dependencies = [ 413 | "anymap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", 414 | "bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 415 | "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 416 | "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 417 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 418 | "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", 419 | "proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 420 | "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", 421 | "serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", 422 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 423 | "stdweb 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", 424 | "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", 425 | "yew-macro 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 426 | ] 427 | 428 | [[package]] 429 | name = "yew-macro" 430 | version = "0.7.0" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | dependencies = [ 433 | "boolinator 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 434 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 435 | "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", 436 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 437 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 438 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 439 | ] 440 | 441 | [metadata] 442 | "checksum anymap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344" 443 | "checksum backtrace 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e4036b9bf40f3cf16aba72a3d65e8a520fc4bafcdc7079aea8f848c58c5b5536" 444 | "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" 445 | "checksum base-x 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b20b618342cf9891c292c4f5ac2cde7287cc5c87e87e9c769d617793607dec1" 446 | "checksum bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f2fb9e29e72fd6bc12071533d5dc7664cb01480c59406f656d7ac25c7bd8ff7" 447 | "checksum boolinator 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9" 448 | "checksum bumpalo 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742" 449 | "checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" 450 | "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" 451 | "checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" 452 | "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 453 | "checksum discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" 454 | "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" 455 | "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" 456 | "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" 457 | "checksum http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" 458 | "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 459 | "checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" 460 | "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 461 | "checksum libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)" = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" 462 | "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 463 | "checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" 464 | "checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" 465 | "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" 466 | "checksum proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" 467 | "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" 468 | "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" 469 | "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 470 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 471 | "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" 472 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 473 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 474 | "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" 475 | "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" 476 | "checksum serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25" 477 | "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" 478 | "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 479 | "checksum stdweb 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" 480 | "checksum stdweb-derive 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" 481 | "checksum stdweb-internal-macros 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" 482 | "checksum stdweb-internal-runtime 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" 483 | "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" 484 | "checksum syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" 485 | "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" 486 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 487 | "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 488 | "checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" 489 | "checksum wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" 490 | "checksum wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" 491 | "checksum wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" 492 | "checksum wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601" 493 | "checksum yew 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba6bd5613792c44a919bb112bb2c7325b76ac0c0cfef4cfcc101db0e292ddb13" 494 | "checksum yew-macro 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b0a74f618cd84beb91ed9d9e0eda0256b44f1f334b4f73ebc38ef5038aebb2" 495 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "impact" 3 | version = "0.1.1" 4 | authors = ["deciduously "] 5 | 6 | [dependencies] 7 | 8 | stdweb = "0.4" 9 | yew = "0.7" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Ben Lovy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # impact 2 | An incremental game skeleton. Very much WIP. 3 | 4 | It's incremental, but not realtime. For now, a second passes each time an Action happens, which is not ideal...bulk actions will take way too long. Eventually I will fine tune this so that each action has a duration, meaning adding messages to the console won't clog it up. 5 | 6 | ![screenhot](https://i.imgur.com/siTfdFc.png). 7 | 8 | Play the first thrilling 30 seconds [here](http://deciduously.com/impact). 9 | 10 | ## Requirements 11 | 12 | * [Rust](https://www.rust-lang.org/en-US/) 2018 with the `wasm32-unknown-unknown` target. 13 | * [cargo-web](https://github.com/koute/cargo-web) 14 | * [NPM/Node](https://nodejs.org/en/download/) 15 | 16 | You can use stable rust and Emscripten/asmjs but do you really *want* to? 17 | 18 | ## Usage 19 | 20 | * `yarn clean` - Clean build artifacts. 21 | * `yarn dev` - Start a development server on `localhost:8000` and watch for changes to either Rust or SCSS. 22 | * `yarn prod` - Build a production bundle at `release/` and serve on `localhost:8080`. 23 | 24 | Note - the `wasm32-unknown-unknown` target does not currently support debug builds, so the dev server runs a release build of the rust code. For now, the only difference with with the production build is the JS minifier (negligible gain) and lack of hot reloading. 25 | 26 | ## Crates 27 | 28 | * [stdweb](https://github.com/koute/stdweb) - DOM manipulation 29 | * [yew](https://github.com/DenisKolodin/yew) - Client-side Rust->Wasm framework. A little Elm-ish, a litte React-ish, a lot experimental 30 | 31 | ## Acknowledgements 32 | 33 | Many thinks to [OvermindDL1](https://github.com/overminddl1)'s [blog series](http://blog.overminddl1.com/tags/overbots/). A lot of this is similar to his OCaml structure where applicable, and going through that tutorial gave me the idea and structure to even attempt this. The SCSS scripts and flexbox setup are his until I tackle my own. While I decided not to go with realtime incremental for this project the basic engine is very similar to his Overbots structure at least at this point in development, but, you know, in `yew`. His [`bucklescript-tea`](https://github.com/OvermindDL1/bucklescript-tea) is also an amazing project and you should check it out! 34 | 35 | Also of course the [yew examples](https://github.com/DenisKolodin/yew/tree/master/examples) were invaluable in overcoming the humps. I'm still not positive I'm getting the event pattern down proper but time will tell! 36 | -------------------------------------------------------------------------------- /Web.toml: -------------------------------------------------------------------------------- 1 | default-target = "wasm32-unknown-unknown" 2 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deciduously/impact/960142e3871018f47267c554e4fce21f4f8c637f/docs/favicon.ico -------------------------------------------------------------------------------- /docs/impact.css: -------------------------------------------------------------------------------- 1 | .impact { 2 | display: flex; 3 | flex-direction: column; 4 | height: 100%; 5 | width: 100%; } 6 | .impact .container { 7 | border: solid 1px #000; 8 | display: flex; 9 | flex-direction: column; 10 | overflow: hidden; } 11 | .impact .container > .title { 12 | border-bottom: solid 1px #000; 13 | font-weight: bold; 14 | text-align: center; } 15 | .impact .container > .scroller { 16 | overflow: auto; } 17 | .impact .header { 18 | border-bottom: solid 1px #000; 19 | flex: 0; 20 | font-size: 72px; 21 | font-weight: bold; 22 | text-align: center; } 23 | .impact .body { 24 | display: flex; 25 | flex: 1; 26 | flex-direction: row; } 27 | .impact .body .time { 28 | flex: 0; 29 | border-bottom: solid 1px #000; 30 | font-size: 14px; } 31 | .impact .container-resources { 32 | flex: 0 0 256px; 33 | order: 0; } 34 | .impact .container-resources .resource { 35 | border: dashed 1px #000; 36 | display: flex; 37 | flex: 0; 38 | flex-direction: row; } 39 | .impact .container-resources .resource-title { 40 | display: flex; 41 | flex: 2; 42 | font-weight: bold; 43 | width: 50%; } 44 | .impact .container-resources .resource-amt { 45 | display: flex; 46 | flex: 1; 47 | font-style: italic; 48 | padding-left: 8px; } 49 | .impact .container-resources .resource-delta { 50 | display: flex; 51 | flex: 1; 52 | font-style: italic; 53 | padding-left: 2px; } 54 | .impact .container-control { 55 | flex: 0 0 256px; } 56 | .impact .container-control .control-button { 57 | flex: 1; } 58 | .impact .container-map { 59 | flex: 1 0 256px; 60 | order: 1; } 61 | .impact .container-messages { 62 | flex: 0 0 192px; } 63 | .impact .container-messages .message-time { 64 | border-bottom: solid 1px #000; 65 | flex: 0; 66 | font-weight: bold; 67 | text-align: center; } 68 | -------------------------------------------------------------------------------- /docs/impact.js: -------------------------------------------------------------------------------- 1 | function _typeof(obj) { 2 | "@babel/helpers - typeof"; 3 | 4 | if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { 5 | _typeof = function (obj) { 6 | return typeof obj; 7 | }; 8 | } else { 9 | _typeof = function (obj) { 10 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 11 | }; 12 | } 13 | 14 | return _typeof(obj); 15 | } 16 | 17 | if (typeof Rust === "undefined") { 18 | var Rust = {}; 19 | } 20 | 21 | (function (root, factory) { 22 | if (typeof define === "function" && define.amd) { 23 | define([], factory); 24 | } else if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === "object" && module.exports) { 25 | module.exports = factory(); 26 | } else { 27 | Rust.impact = factory(); 28 | } 29 | })(undefined, function () { 30 | return function (module_factory) { 31 | var instance = module_factory(); 32 | 33 | if ((typeof process === "undefined" ? "undefined" : _typeof(process)) === "object" && _typeof(process.versions) === "object" && typeof process.versions.node === "string") { 34 | var fs = require("fs"); 35 | 36 | var path = require("path"); 37 | 38 | var wasm_path = path.join(__dirname, "impact.wasm"); 39 | var buffer = fs.readFileSync(wasm_path); 40 | var mod = new WebAssembly.Module(buffer); 41 | var wasm_instance = new WebAssembly.Instance(mod, instance.imports); 42 | return instance.initialize(wasm_instance); 43 | } else { 44 | var file = fetch("impact.wasm", { 45 | credentials: "same-origin" 46 | }); 47 | var wasm_instance = typeof WebAssembly.instantiateStreaming === "function" ? WebAssembly.instantiateStreaming(file, instance.imports).then(function (result) { 48 | return result.instance; 49 | }) : file.then(function (response) { 50 | return response.arrayBuffer(); 51 | }).then(function (bytes) { 52 | return WebAssembly.compile(bytes); 53 | }).then(function (mod) { 54 | return WebAssembly.instantiate(mod, instance.imports); 55 | }); 56 | return wasm_instance.then(function (wasm_instance) { 57 | var exports = instance.initialize(wasm_instance); 58 | console.log("Finished loading Rust wasm module 'impact'"); 59 | return exports; 60 | })["catch"](function (error) { 61 | console.log("Error loading Rust wasm module 'impact':", error); 62 | throw error; 63 | }); 64 | } 65 | }(function () { 66 | var Module = {}; 67 | Module.STDWEB_PRIVATE = {}; // This is based on code from Emscripten's preamble.js. 68 | 69 | Module.STDWEB_PRIVATE.to_utf8 = function to_utf8(str, addr) { 70 | var HEAPU8 = Module.HEAPU8; 71 | 72 | for (var i = 0; i < str.length; ++i) { 73 | // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8. 74 | // See http://unicode.org/faq/utf_bom.html#utf16-3 75 | // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629 76 | var u = str.charCodeAt(i); // possibly a lead surrogate 77 | 78 | if (u >= 0xD800 && u <= 0xDFFF) { 79 | u = 0x10000 + ((u & 0x3FF) << 10) | str.charCodeAt(++i) & 0x3FF; 80 | } 81 | 82 | if (u <= 0x7F) { 83 | HEAPU8[addr++] = u; 84 | } else if (u <= 0x7FF) { 85 | HEAPU8[addr++] = 0xC0 | u >> 6; 86 | HEAPU8[addr++] = 0x80 | u & 63; 87 | } else if (u <= 0xFFFF) { 88 | HEAPU8[addr++] = 0xE0 | u >> 12; 89 | HEAPU8[addr++] = 0x80 | u >> 6 & 63; 90 | HEAPU8[addr++] = 0x80 | u & 63; 91 | } else if (u <= 0x1FFFFF) { 92 | HEAPU8[addr++] = 0xF0 | u >> 18; 93 | HEAPU8[addr++] = 0x80 | u >> 12 & 63; 94 | HEAPU8[addr++] = 0x80 | u >> 6 & 63; 95 | HEAPU8[addr++] = 0x80 | u & 63; 96 | } else if (u <= 0x3FFFFFF) { 97 | HEAPU8[addr++] = 0xF8 | u >> 24; 98 | HEAPU8[addr++] = 0x80 | u >> 18 & 63; 99 | HEAPU8[addr++] = 0x80 | u >> 12 & 63; 100 | HEAPU8[addr++] = 0x80 | u >> 6 & 63; 101 | HEAPU8[addr++] = 0x80 | u & 63; 102 | } else { 103 | HEAPU8[addr++] = 0xFC | u >> 30; 104 | HEAPU8[addr++] = 0x80 | u >> 24 & 63; 105 | HEAPU8[addr++] = 0x80 | u >> 18 & 63; 106 | HEAPU8[addr++] = 0x80 | u >> 12 & 63; 107 | HEAPU8[addr++] = 0x80 | u >> 6 & 63; 108 | HEAPU8[addr++] = 0x80 | u & 63; 109 | } 110 | } 111 | }; 112 | 113 | Module.STDWEB_PRIVATE.noop = function () {}; 114 | 115 | Module.STDWEB_PRIVATE.to_js = function to_js(address) { 116 | var kind = Module.HEAPU8[address + 12]; 117 | 118 | if (kind === 0) { 119 | return undefined; 120 | } else if (kind === 1) { 121 | return null; 122 | } else if (kind === 2) { 123 | return Module.HEAP32[address / 4]; 124 | } else if (kind === 3) { 125 | return Module.HEAPF64[address / 8]; 126 | } else if (kind === 4) { 127 | var pointer = Module.HEAPU32[address / 4]; 128 | var length = Module.HEAPU32[(address + 4) / 4]; 129 | return Module.STDWEB_PRIVATE.to_js_string(pointer, length); 130 | } else if (kind === 5) { 131 | return false; 132 | } else if (kind === 6) { 133 | return true; 134 | } else if (kind === 7) { 135 | var pointer = Module.STDWEB_PRIVATE.arena + Module.HEAPU32[address / 4]; 136 | var length = Module.HEAPU32[(address + 4) / 4]; 137 | var _output = []; 138 | 139 | for (var i = 0; i < length; ++i) { 140 | _output.push(Module.STDWEB_PRIVATE.to_js(pointer + i * 16)); 141 | } 142 | 143 | return _output; 144 | } else if (kind === 8) { 145 | var arena = Module.STDWEB_PRIVATE.arena; 146 | var value_array_pointer = arena + Module.HEAPU32[address / 4]; 147 | var length = Module.HEAPU32[(address + 4) / 4]; 148 | var key_array_pointer = arena + Module.HEAPU32[(address + 8) / 4]; 149 | var _output = {}; 150 | 151 | for (var i = 0; i < length; ++i) { 152 | var key_pointer = Module.HEAPU32[(key_array_pointer + i * 8) / 4]; 153 | var key_length = Module.HEAPU32[(key_array_pointer + 4 + i * 8) / 4]; 154 | var key = Module.STDWEB_PRIVATE.to_js_string(key_pointer, key_length); 155 | var value = Module.STDWEB_PRIVATE.to_js(value_array_pointer + i * 16); 156 | _output[key] = value; 157 | } 158 | 159 | return _output; 160 | } else if (kind === 9) { 161 | return Module.STDWEB_PRIVATE.acquire_js_reference(Module.HEAP32[address / 4]); 162 | } else if (kind === 10 || kind === 12 || kind === 13) { 163 | var adapter_pointer = Module.HEAPU32[address / 4]; 164 | var pointer = Module.HEAPU32[(address + 4) / 4]; 165 | var deallocator_pointer = Module.HEAPU32[(address + 8) / 4]; 166 | var num_ongoing_calls = 0; 167 | var drop_queued = false; 168 | 169 | var _output = function output() { 170 | if (pointer === 0 || drop_queued === true) { 171 | if (kind === 10) { 172 | throw new ReferenceError("Already dropped Rust function called!"); 173 | } else if (kind === 12) { 174 | throw new ReferenceError("Already dropped FnMut function called!"); 175 | } else { 176 | throw new ReferenceError("Already called or dropped FnOnce function called!"); 177 | } 178 | } 179 | 180 | var function_pointer = pointer; 181 | 182 | if (kind === 13) { 183 | _output.drop = Module.STDWEB_PRIVATE.noop; 184 | pointer = 0; 185 | } 186 | 187 | if (num_ongoing_calls !== 0) { 188 | if (kind === 12 || kind === 13) { 189 | throw new ReferenceError("FnMut function called multiple times concurrently!"); 190 | } 191 | } 192 | 193 | var args = Module.STDWEB_PRIVATE.alloc(16); 194 | Module.STDWEB_PRIVATE.serialize_array(args, arguments); 195 | 196 | try { 197 | num_ongoing_calls += 1; 198 | Module.STDWEB_PRIVATE.dyncall("vii", adapter_pointer, [function_pointer, args]); 199 | var result = Module.STDWEB_PRIVATE.tmp; 200 | Module.STDWEB_PRIVATE.tmp = null; 201 | } finally { 202 | num_ongoing_calls -= 1; 203 | } 204 | 205 | if (drop_queued === true && num_ongoing_calls === 0) { 206 | _output.drop(); 207 | } 208 | 209 | return result; 210 | }; 211 | 212 | _output.drop = function () { 213 | if (num_ongoing_calls !== 0) { 214 | drop_queued = true; 215 | return; 216 | } 217 | 218 | _output.drop = Module.STDWEB_PRIVATE.noop; 219 | var function_pointer = pointer; 220 | pointer = 0; 221 | 222 | if (function_pointer != 0) { 223 | Module.STDWEB_PRIVATE.dyncall("vi", deallocator_pointer, [function_pointer]); 224 | } 225 | }; 226 | 227 | return _output; 228 | } else if (kind === 14) { 229 | var pointer = Module.HEAPU32[address / 4]; 230 | var length = Module.HEAPU32[(address + 4) / 4]; 231 | var array_kind = Module.HEAPU32[(address + 8) / 4]; 232 | var pointer_end = pointer + length; 233 | 234 | switch (array_kind) { 235 | case 0: 236 | return Module.HEAPU8.subarray(pointer, pointer_end); 237 | 238 | case 1: 239 | return Module.HEAP8.subarray(pointer, pointer_end); 240 | 241 | case 2: 242 | return Module.HEAPU16.subarray(pointer, pointer_end); 243 | 244 | case 3: 245 | return Module.HEAP16.subarray(pointer, pointer_end); 246 | 247 | case 4: 248 | return Module.HEAPU32.subarray(pointer, pointer_end); 249 | 250 | case 5: 251 | return Module.HEAP32.subarray(pointer, pointer_end); 252 | 253 | case 6: 254 | return Module.HEAPF32.subarray(pointer, pointer_end); 255 | 256 | case 7: 257 | return Module.HEAPF64.subarray(pointer, pointer_end); 258 | } 259 | } else if (kind === 15) { 260 | return Module.STDWEB_PRIVATE.get_raw_value(Module.HEAPU32[address / 4]); 261 | } 262 | }; 263 | 264 | Module.STDWEB_PRIVATE.serialize_object = function serialize_object(address, value) { 265 | var keys = Object.keys(value); 266 | var length = keys.length; 267 | var key_array_pointer = Module.STDWEB_PRIVATE.alloc(length * 8); 268 | var value_array_pointer = Module.STDWEB_PRIVATE.alloc(length * 16); 269 | Module.HEAPU8[address + 12] = 8; 270 | Module.HEAPU32[address / 4] = value_array_pointer; 271 | Module.HEAPU32[(address + 4) / 4] = length; 272 | Module.HEAPU32[(address + 8) / 4] = key_array_pointer; 273 | 274 | for (var i = 0; i < length; ++i) { 275 | var key = keys[i]; 276 | var key_address = key_array_pointer + i * 8; 277 | Module.STDWEB_PRIVATE.to_utf8_string(key_address, key); 278 | Module.STDWEB_PRIVATE.from_js(value_array_pointer + i * 16, value[key]); 279 | } 280 | }; 281 | 282 | Module.STDWEB_PRIVATE.serialize_array = function serialize_array(address, value) { 283 | var length = value.length; 284 | var pointer = Module.STDWEB_PRIVATE.alloc(length * 16); 285 | Module.HEAPU8[address + 12] = 7; 286 | Module.HEAPU32[address / 4] = pointer; 287 | Module.HEAPU32[(address + 4) / 4] = length; 288 | 289 | for (var i = 0; i < length; ++i) { 290 | Module.STDWEB_PRIVATE.from_js(pointer + i * 16, value[i]); 291 | } 292 | }; // New browsers and recent Node 293 | 294 | 295 | var cachedEncoder = typeof TextEncoder === "function" ? new TextEncoder("utf-8") // Old Node (before v11) 296 | : (typeof util === "undefined" ? "undefined" : _typeof(util)) === "object" && util && typeof util.TextEncoder === "function" ? new util.TextEncoder("utf-8") // Old browsers 297 | : null; 298 | 299 | if (cachedEncoder != null) { 300 | Module.STDWEB_PRIVATE.to_utf8_string = function to_utf8_string(address, value) { 301 | var buffer = cachedEncoder.encode(value); 302 | var length = buffer.length; 303 | var pointer = 0; 304 | 305 | if (length > 0) { 306 | pointer = Module.STDWEB_PRIVATE.alloc(length); 307 | Module.HEAPU8.set(buffer, pointer); 308 | } 309 | 310 | Module.HEAPU32[address / 4] = pointer; 311 | Module.HEAPU32[(address + 4) / 4] = length; 312 | }; 313 | } else { 314 | Module.STDWEB_PRIVATE.to_utf8_string = function to_utf8_string(address, value) { 315 | var length = Module.STDWEB_PRIVATE.utf8_len(value); 316 | var pointer = 0; 317 | 318 | if (length > 0) { 319 | pointer = Module.STDWEB_PRIVATE.alloc(length); 320 | Module.STDWEB_PRIVATE.to_utf8(value, pointer); 321 | } 322 | 323 | Module.HEAPU32[address / 4] = pointer; 324 | Module.HEAPU32[(address + 4) / 4] = length; 325 | }; 326 | } 327 | 328 | Module.STDWEB_PRIVATE.from_js = function from_js(address, value) { 329 | var kind = Object.prototype.toString.call(value); 330 | 331 | if (kind === "[object String]") { 332 | Module.HEAPU8[address + 12] = 4; 333 | Module.STDWEB_PRIVATE.to_utf8_string(address, value); 334 | } else if (kind === "[object Number]") { 335 | if (value === (value | 0)) { 336 | Module.HEAPU8[address + 12] = 2; 337 | Module.HEAP32[address / 4] = value; 338 | } else { 339 | Module.HEAPU8[address + 12] = 3; 340 | Module.HEAPF64[address / 8] = value; 341 | } 342 | } else if (value === null) { 343 | Module.HEAPU8[address + 12] = 1; 344 | } else if (value === undefined) { 345 | Module.HEAPU8[address + 12] = 0; 346 | } else if (value === false) { 347 | Module.HEAPU8[address + 12] = 5; 348 | } else if (value === true) { 349 | Module.HEAPU8[address + 12] = 6; 350 | } else if (kind === "[object Symbol]") { 351 | var id = Module.STDWEB_PRIVATE.register_raw_value(value); 352 | Module.HEAPU8[address + 12] = 15; 353 | Module.HEAP32[address / 4] = id; 354 | } else { 355 | var refid = Module.STDWEB_PRIVATE.acquire_rust_reference(value); 356 | Module.HEAPU8[address + 12] = 9; 357 | Module.HEAP32[address / 4] = refid; 358 | } 359 | }; // New browsers and recent Node 360 | 361 | 362 | var cachedDecoder = typeof TextDecoder === "function" ? new TextDecoder("utf-8") // Old Node (before v11) 363 | : (typeof util === "undefined" ? "undefined" : _typeof(util)) === "object" && util && typeof util.TextDecoder === "function" ? new util.TextDecoder("utf-8") // Old browsers 364 | : null; 365 | 366 | if (cachedDecoder != null) { 367 | Module.STDWEB_PRIVATE.to_js_string = function to_js_string(index, length) { 368 | return cachedDecoder.decode(Module.HEAPU8.subarray(index, index + length)); 369 | }; 370 | } else { 371 | // This is ported from Rust's stdlib; it's faster than 372 | // the string conversion from Emscripten. 373 | Module.STDWEB_PRIVATE.to_js_string = function to_js_string(index, length) { 374 | var HEAPU8 = Module.HEAPU8; 375 | index = index | 0; 376 | length = length | 0; 377 | var end = (index | 0) + (length | 0); 378 | var output = ""; 379 | 380 | while (index < end) { 381 | var x = HEAPU8[index++]; 382 | 383 | if (x < 128) { 384 | output += String.fromCharCode(x); 385 | continue; 386 | } 387 | 388 | var init = x & 0x7F >> 2; 389 | var y = 0; 390 | 391 | if (index < end) { 392 | y = HEAPU8[index++]; 393 | } 394 | 395 | var ch = init << 6 | y & 63; 396 | 397 | if (x >= 0xE0) { 398 | var z = 0; 399 | 400 | if (index < end) { 401 | z = HEAPU8[index++]; 402 | } 403 | 404 | var y_z = (y & 63) << 6 | z & 63; 405 | ch = init << 12 | y_z; 406 | 407 | if (x >= 0xF0) { 408 | var w = 0; 409 | 410 | if (index < end) { 411 | w = HEAPU8[index++]; 412 | } 413 | 414 | ch = (init & 7) << 18 | (y_z << 6 | w & 63); 415 | output += String.fromCharCode(0xD7C0 + (ch >> 10)); 416 | ch = 0xDC00 + (ch & 0x3FF); 417 | } 418 | } 419 | 420 | output += String.fromCharCode(ch); 421 | continue; 422 | } 423 | 424 | return output; 425 | }; 426 | } 427 | 428 | Module.STDWEB_PRIVATE.id_to_ref_map = {}; 429 | Module.STDWEB_PRIVATE.id_to_refcount_map = {}; 430 | Module.STDWEB_PRIVATE.ref_to_id_map = new WeakMap(); // Not all types can be stored in a WeakMap 431 | 432 | Module.STDWEB_PRIVATE.ref_to_id_map_fallback = new Map(); 433 | Module.STDWEB_PRIVATE.last_refid = 1; 434 | Module.STDWEB_PRIVATE.id_to_raw_value_map = {}; 435 | Module.STDWEB_PRIVATE.last_raw_value_id = 1; 436 | 437 | Module.STDWEB_PRIVATE.acquire_rust_reference = function (reference) { 438 | if (reference === undefined || reference === null) { 439 | return 0; 440 | } 441 | 442 | var id_to_refcount_map = Module.STDWEB_PRIVATE.id_to_refcount_map; 443 | var id_to_ref_map = Module.STDWEB_PRIVATE.id_to_ref_map; 444 | var ref_to_id_map = Module.STDWEB_PRIVATE.ref_to_id_map; 445 | var ref_to_id_map_fallback = Module.STDWEB_PRIVATE.ref_to_id_map_fallback; 446 | var refid = ref_to_id_map.get(reference); 447 | 448 | if (refid === undefined) { 449 | refid = ref_to_id_map_fallback.get(reference); 450 | } 451 | 452 | if (refid === undefined) { 453 | refid = Module.STDWEB_PRIVATE.last_refid++; 454 | 455 | try { 456 | ref_to_id_map.set(reference, refid); 457 | } catch (e) { 458 | ref_to_id_map_fallback.set(reference, refid); 459 | } 460 | } 461 | 462 | if (refid in id_to_ref_map) { 463 | id_to_refcount_map[refid]++; 464 | } else { 465 | id_to_ref_map[refid] = reference; 466 | id_to_refcount_map[refid] = 1; 467 | } 468 | 469 | return refid; 470 | }; 471 | 472 | Module.STDWEB_PRIVATE.acquire_js_reference = function (refid) { 473 | return Module.STDWEB_PRIVATE.id_to_ref_map[refid]; 474 | }; 475 | 476 | Module.STDWEB_PRIVATE.increment_refcount = function (refid) { 477 | Module.STDWEB_PRIVATE.id_to_refcount_map[refid]++; 478 | }; 479 | 480 | Module.STDWEB_PRIVATE.decrement_refcount = function (refid) { 481 | var id_to_refcount_map = Module.STDWEB_PRIVATE.id_to_refcount_map; 482 | 483 | if (0 == --id_to_refcount_map[refid]) { 484 | var id_to_ref_map = Module.STDWEB_PRIVATE.id_to_ref_map; 485 | var ref_to_id_map_fallback = Module.STDWEB_PRIVATE.ref_to_id_map_fallback; 486 | var reference = id_to_ref_map[refid]; 487 | delete id_to_ref_map[refid]; 488 | delete id_to_refcount_map[refid]; 489 | ref_to_id_map_fallback["delete"](reference); 490 | } 491 | }; 492 | 493 | Module.STDWEB_PRIVATE.register_raw_value = function (value) { 494 | var id = Module.STDWEB_PRIVATE.last_raw_value_id++; 495 | Module.STDWEB_PRIVATE.id_to_raw_value_map[id] = value; 496 | return id; 497 | }; 498 | 499 | Module.STDWEB_PRIVATE.unregister_raw_value = function (id) { 500 | delete Module.STDWEB_PRIVATE.id_to_raw_value_map[id]; 501 | }; 502 | 503 | Module.STDWEB_PRIVATE.get_raw_value = function (id) { 504 | return Module.STDWEB_PRIVATE.id_to_raw_value_map[id]; 505 | }; 506 | 507 | Module.STDWEB_PRIVATE.alloc = function alloc(size) { 508 | return Module.web_malloc(size); 509 | }; 510 | 511 | Module.STDWEB_PRIVATE.dyncall = function (signature, ptr, args) { 512 | return Module.web_table.get(ptr).apply(null, args); 513 | }; // This is based on code from Emscripten's preamble.js. 514 | 515 | 516 | Module.STDWEB_PRIVATE.utf8_len = function utf8_len(str) { 517 | var len = 0; 518 | 519 | for (var i = 0; i < str.length; ++i) { 520 | // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8. 521 | // See http://unicode.org/faq/utf_bom.html#utf16-3 522 | var u = str.charCodeAt(i); // possibly a lead surrogate 523 | 524 | if (u >= 0xD800 && u <= 0xDFFF) { 525 | u = 0x10000 + ((u & 0x3FF) << 10) | str.charCodeAt(++i) & 0x3FF; 526 | } 527 | 528 | if (u <= 0x7F) { 529 | ++len; 530 | } else if (u <= 0x7FF) { 531 | len += 2; 532 | } else if (u <= 0xFFFF) { 533 | len += 3; 534 | } else if (u <= 0x1FFFFF) { 535 | len += 4; 536 | } else if (u <= 0x3FFFFFF) { 537 | len += 5; 538 | } else { 539 | len += 6; 540 | } 541 | } 542 | 543 | return len; 544 | }; 545 | 546 | Module.STDWEB_PRIVATE.prepare_any_arg = function (value) { 547 | var arg = Module.STDWEB_PRIVATE.alloc(16); 548 | Module.STDWEB_PRIVATE.from_js(arg, value); 549 | return arg; 550 | }; 551 | 552 | Module.STDWEB_PRIVATE.acquire_tmp = function (dummy) { 553 | var value = Module.STDWEB_PRIVATE.tmp; 554 | Module.STDWEB_PRIVATE.tmp = null; 555 | return value; 556 | }; 557 | 558 | var HEAP8 = null; 559 | var HEAP16 = null; 560 | var HEAP32 = null; 561 | var HEAPU8 = null; 562 | var HEAPU16 = null; 563 | var HEAPU32 = null; 564 | var HEAPF32 = null; 565 | var HEAPF64 = null; 566 | Object.defineProperty(Module, 'exports', { 567 | value: {} 568 | }); 569 | 570 | function __web_on_grow() { 571 | var buffer = Module.instance.exports.memory.buffer; 572 | HEAP8 = new Int8Array(buffer); 573 | HEAP16 = new Int16Array(buffer); 574 | HEAP32 = new Int32Array(buffer); 575 | HEAPU8 = new Uint8Array(buffer); 576 | HEAPU16 = new Uint16Array(buffer); 577 | HEAPU32 = new Uint32Array(buffer); 578 | HEAPF32 = new Float32Array(buffer); 579 | HEAPF64 = new Float64Array(buffer); 580 | Module.HEAP8 = HEAP8; 581 | Module.HEAP16 = HEAP16; 582 | Module.HEAP32 = HEAP32; 583 | Module.HEAPU8 = HEAPU8; 584 | Module.HEAPU16 = HEAPU16; 585 | Module.HEAPU32 = HEAPU32; 586 | Module.HEAPF32 = HEAPF32; 587 | Module.HEAPF64 = HEAPF64; 588 | } 589 | 590 | return { 591 | imports: { 592 | env: { 593 | "__cargo_web_snippet_08a3b15e1358700ac92bc556f9e9b8af660fc2c7": function __cargo_web_snippet_08a3b15e1358700ac92bc556f9e9b8af660fc2c7($0, $1) { 594 | $0 = Module.STDWEB_PRIVATE.to_js($0); 595 | $1 = Module.STDWEB_PRIVATE.to_js($1); 596 | $0.nodeValue = $1; 597 | }, 598 | "__cargo_web_snippet_0aced9e2351ced72f1ff99645a129132b16c0d3c": function __cargo_web_snippet_0aced9e2351ced72f1ff99645a129132b16c0d3c($0) { 599 | var value = Module.STDWEB_PRIVATE.get_raw_value($0); 600 | return Module.STDWEB_PRIVATE.register_raw_value(value); 601 | }, 602 | "__cargo_web_snippet_0da47658267a7497de743e1b0892f992ba6ca6ef": function __cargo_web_snippet_0da47658267a7497de743e1b0892f992ba6ca6ef($0, $1) { 603 | $0 = Module.STDWEB_PRIVATE.to_js($0); 604 | $1 = Module.STDWEB_PRIVATE.to_js($1); 605 | $0.type = $1; 606 | }, 607 | "__cargo_web_snippet_0e54fd9c163fcf648ce0a395fde4500fd167a40b": function __cargo_web_snippet_0e54fd9c163fcf648ce0a395fde4500fd167a40b($0) { 608 | var r = Module.STDWEB_PRIVATE.acquire_js_reference($0); 609 | return r instanceof DOMException && r.name === "InvalidCharacterError"; 610 | }, 611 | "__cargo_web_snippet_2908dbb08792df5e699e324eec3e29fd6a57c2c9": function __cargo_web_snippet_2908dbb08792df5e699e324eec3e29fd6a57c2c9($0) { 612 | var o = Module.STDWEB_PRIVATE.acquire_js_reference($0); 613 | return o instanceof HTMLInputElement; 614 | }, 615 | "__cargo_web_snippet_3c5e83d16a83fc7147ec91e2506438012952f55a": function __cargo_web_snippet_3c5e83d16a83fc7147ec91e2506438012952f55a($0) { 616 | var o = Module.STDWEB_PRIVATE.acquire_js_reference($0); 617 | return o instanceof Element; 618 | }, 619 | "__cargo_web_snippet_46518012593da937dd5f35c2fc1c5e1dcade260b": function __cargo_web_snippet_46518012593da937dd5f35c2fc1c5e1dcade260b($0, $1, $2, $3) { 620 | $1 = Module.STDWEB_PRIVATE.to_js($1); 621 | $2 = Module.STDWEB_PRIVATE.to_js($2); 622 | $3 = Module.STDWEB_PRIVATE.to_js($3); 623 | Module.STDWEB_PRIVATE.from_js($0, function () { 624 | try { 625 | return { 626 | value: function () { 627 | return $1.insertBefore($2, $3); 628 | }(), 629 | success: true 630 | }; 631 | } catch (error) { 632 | return { 633 | error: error, 634 | success: false 635 | }; 636 | } 637 | }()); 638 | }, 639 | "__cargo_web_snippet_465ffdf4814bf5d08a3abdf8fe5e61a220b98c34": function __cargo_web_snippet_465ffdf4814bf5d08a3abdf8fe5e61a220b98c34($0) { 640 | var o = Module.STDWEB_PRIVATE.acquire_js_reference($0); 641 | return o instanceof Node; 642 | }, 643 | "__cargo_web_snippet_614a3dd2adb7e9eac4a0ec6e59d37f87e0521c3b": function __cargo_web_snippet_614a3dd2adb7e9eac4a0ec6e59d37f87e0521c3b($0, $1) { 644 | $1 = Module.STDWEB_PRIVATE.to_js($1); 645 | Module.STDWEB_PRIVATE.from_js($0, function () { 646 | return $1.error; 647 | }()); 648 | }, 649 | "__cargo_web_snippet_690311d2f9134ac0983620c38a9e6460d4165607": function __cargo_web_snippet_690311d2f9134ac0983620c38a9e6460d4165607($0, $1) { 650 | $1 = Module.STDWEB_PRIVATE.to_js($1); 651 | Module.STDWEB_PRIVATE.from_js($0, function () { 652 | return $1.nextSibling; 653 | }()); 654 | }, 655 | "__cargo_web_snippet_6a77b2f2accec26fefbfa0d864061d26f40f8f6f": function __cargo_web_snippet_6a77b2f2accec26fefbfa0d864061d26f40f8f6f($0) { 656 | $0 = Module.STDWEB_PRIVATE.to_js($0); 657 | $0.type = ""; 658 | }, 659 | "__cargo_web_snippet_6fcce0aae651e2d748e085ff1f800f87625ff8c8": function __cargo_web_snippet_6fcce0aae651e2d748e085ff1f800f87625ff8c8($0) { 660 | Module.STDWEB_PRIVATE.from_js($0, function () { 661 | return document; 662 | }()); 663 | }, 664 | "__cargo_web_snippet_72fc447820458c720c68d0d8e078ede631edd723": function __cargo_web_snippet_72fc447820458c720c68d0d8e078ede631edd723($0, $1, $2) { 665 | console.error('Panic location:', Module.STDWEB_PRIVATE.to_js_string($0, $1) + ':' + $2); 666 | }, 667 | "__cargo_web_snippet_7c8dfab835dc8a552cd9d67f27d26624590e052c": function __cargo_web_snippet_7c8dfab835dc8a552cd9d67f27d26624590e052c($0) { 668 | var r = Module.STDWEB_PRIVATE.acquire_js_reference($0); 669 | return r instanceof DOMException && r.name === "SyntaxError"; 670 | }, 671 | "__cargo_web_snippet_80d6d56760c65e49b7be8b6b01c1ea861b046bf0": function __cargo_web_snippet_80d6d56760c65e49b7be8b6b01c1ea861b046bf0($0) { 672 | Module.STDWEB_PRIVATE.decrement_refcount($0); 673 | }, 674 | "__cargo_web_snippet_84339b1bf72a580059a6e0ff9499e53759aef5b9": function __cargo_web_snippet_84339b1bf72a580059a6e0ff9499e53759aef5b9($0) { 675 | var o = Module.STDWEB_PRIVATE.acquire_js_reference($0); 676 | return o instanceof MouseEvent && o.type === "click"; 677 | }, 678 | "__cargo_web_snippet_85b9ecbdb8513465b790546acfd0cd530441b8a4": function __cargo_web_snippet_85b9ecbdb8513465b790546acfd0cd530441b8a4($0) { 679 | $0 = Module.STDWEB_PRIVATE.to_js($0); 680 | $0.stopPropagation(); 681 | }, 682 | "__cargo_web_snippet_8a049af1e4867892fca647811a9472e4c5832053": function __cargo_web_snippet_8a049af1e4867892fca647811a9472e4c5832053($0, $1) { 683 | $0 = Module.STDWEB_PRIVATE.to_js($0); 684 | $1 = Module.STDWEB_PRIVATE.to_js($1); 685 | $0.add($1); 686 | }, 687 | "__cargo_web_snippet_91749aeb589cd0f9b17cbc01b2872ba709817982": function __cargo_web_snippet_91749aeb589cd0f9b17cbc01b2872ba709817982($0, $1, $2) { 688 | $1 = Module.STDWEB_PRIVATE.to_js($1); 689 | $2 = Module.STDWEB_PRIVATE.to_js($2); 690 | Module.STDWEB_PRIVATE.from_js($0, function () { 691 | try { 692 | return { 693 | value: function () { 694 | return $1.createElement($2); 695 | }(), 696 | success: true 697 | }; 698 | } catch (error) { 699 | return { 700 | error: error, 701 | success: false 702 | }; 703 | } 704 | }()); 705 | }, 706 | "__cargo_web_snippet_97495987af1720d8a9a923fa4683a7b683e3acd6": function __cargo_web_snippet_97495987af1720d8a9a923fa4683a7b683e3acd6($0, $1) { 707 | console.error('Panic error message:', Module.STDWEB_PRIVATE.to_js_string($0, $1)); 708 | }, 709 | "__cargo_web_snippet_99c4eefdc8d4cc724135163b8c8665a1f3de99e4": function __cargo_web_snippet_99c4eefdc8d4cc724135163b8c8665a1f3de99e4($0, $1, $2, $3) { 710 | $1 = Module.STDWEB_PRIVATE.to_js($1); 711 | $2 = Module.STDWEB_PRIVATE.to_js($2); 712 | $3 = Module.STDWEB_PRIVATE.to_js($3); 713 | Module.STDWEB_PRIVATE.from_js($0, function () { 714 | var listener = $1; 715 | $2.addEventListener($3, listener); 716 | return listener; 717 | }()); 718 | }, 719 | "__cargo_web_snippet_9f22d4ca7bc938409787341b7db181f8dd41e6df": function __cargo_web_snippet_9f22d4ca7bc938409787341b7db181f8dd41e6df($0) { 720 | Module.STDWEB_PRIVATE.increment_refcount($0); 721 | }, 722 | "__cargo_web_snippet_a152e8d0e8fac5476f30c1d19e4ab217dbcba73d": function __cargo_web_snippet_a152e8d0e8fac5476f30c1d19e4ab217dbcba73d($0, $1, $2) { 723 | $1 = Module.STDWEB_PRIVATE.to_js($1); 724 | $2 = Module.STDWEB_PRIVATE.to_js($2); 725 | Module.STDWEB_PRIVATE.from_js($0, function () { 726 | try { 727 | return { 728 | value: function () { 729 | return $1.querySelector($2); 730 | }(), 731 | success: true 732 | }; 733 | } catch (error) { 734 | return { 735 | error: error, 736 | success: false 737 | }; 738 | } 739 | }()); 740 | }, 741 | "__cargo_web_snippet_a1f43b583e011a9bbeae64030b81f677e6c29005": function __cargo_web_snippet_a1f43b583e011a9bbeae64030b81f677e6c29005($0, $1) { 742 | $0 = Module.STDWEB_PRIVATE.to_js($0); 743 | $1 = Module.STDWEB_PRIVATE.to_js($1); 744 | $0.checked = $1; 745 | }, 746 | "__cargo_web_snippet_ab05f53189dacccf2d365ad26daa407d4f7abea9": function __cargo_web_snippet_ab05f53189dacccf2d365ad26daa407d4f7abea9($0, $1) { 747 | $1 = Module.STDWEB_PRIVATE.to_js($1); 748 | Module.STDWEB_PRIVATE.from_js($0, function () { 749 | return $1.value; 750 | }()); 751 | }, 752 | "__cargo_web_snippet_afafe9a462a05084fec65cacc7d6598e145ff3e3": function __cargo_web_snippet_afafe9a462a05084fec65cacc7d6598e145ff3e3($0, $1, $2) { 753 | $1 = Module.STDWEB_PRIVATE.to_js($1); 754 | $2 = Module.STDWEB_PRIVATE.to_js($2); 755 | Module.STDWEB_PRIVATE.from_js($0, function () { 756 | return $1.createTextNode($2); 757 | }()); 758 | }, 759 | "__cargo_web_snippet_b06dde4acf09433b5190a4b001259fe5d4abcbc2": function __cargo_web_snippet_b06dde4acf09433b5190a4b001259fe5d4abcbc2($0, $1) { 760 | $1 = Module.STDWEB_PRIVATE.to_js($1); 761 | Module.STDWEB_PRIVATE.from_js($0, function () { 762 | return $1.success; 763 | }()); 764 | }, 765 | "__cargo_web_snippet_bb618d13cbb219642bd219af99ee1519e5658d77": function __cargo_web_snippet_bb618d13cbb219642bd219af99ee1519e5658d77($0, $1) { 766 | $1 = Module.STDWEB_PRIVATE.to_js($1); 767 | Module.STDWEB_PRIVATE.from_js($0, function () { 768 | return $1.classList; 769 | }()); 770 | }, 771 | "__cargo_web_snippet_c023351d5bff43ef3dd317b499821cd4e71492f0": function __cargo_web_snippet_c023351d5bff43ef3dd317b499821cd4e71492f0($0) { 772 | var r = Module.STDWEB_PRIVATE.acquire_js_reference($0); 773 | return r instanceof DOMException && r.name === "HierarchyRequestError"; 774 | }, 775 | "__cargo_web_snippet_c26ddf75f581148e029dfcd95c037bb50d502e43": function __cargo_web_snippet_c26ddf75f581148e029dfcd95c037bb50d502e43($0, $1) { 776 | $0 = Module.STDWEB_PRIVATE.to_js($0); 777 | $1 = Module.STDWEB_PRIVATE.to_js($1); 778 | $0.value = $1; 779 | }, 780 | "__cargo_web_snippet_cd41a77d0178ae27c833ef2950e5f1a48a1455c1": function __cargo_web_snippet_cd41a77d0178ae27c833ef2950e5f1a48a1455c1($0, $1, $2) { 781 | $1 = Module.STDWEB_PRIVATE.to_js($1); 782 | $2 = Module.STDWEB_PRIVATE.to_js($2); 783 | Module.STDWEB_PRIVATE.from_js($0, function () { 784 | try { 785 | return { 786 | value: function () { 787 | return $1.removeChild($2); 788 | }(), 789 | success: true 790 | }; 791 | } catch (error) { 792 | return { 793 | error: error, 794 | success: false 795 | }; 796 | } 797 | }()); 798 | }, 799 | "__cargo_web_snippet_da2febd72f9938d90bc2bf2905643f595b07abd9": function __cargo_web_snippet_da2febd72f9938d90bc2bf2905643f595b07abd9($0, $1, $2) { 800 | $0 = Module.STDWEB_PRIVATE.to_js($0); 801 | $1 = Module.STDWEB_PRIVATE.to_js($1); 802 | $2 = Module.STDWEB_PRIVATE.to_js($2); 803 | $0.setAttribute($1, $2); 804 | }, 805 | "__cargo_web_snippet_db12d53e9596e9bc7860a8231ec85044629926e7": function __cargo_web_snippet_db12d53e9596e9bc7860a8231ec85044629926e7($0) { 806 | var o = Module.STDWEB_PRIVATE.acquire_js_reference($0); 807 | return o instanceof HTMLTextAreaElement; 808 | }, 809 | "__cargo_web_snippet_dc2fd915bd92f9e9c6a3bd15174f1414eee3dbaf": function __cargo_web_snippet_dc2fd915bd92f9e9c6a3bd15174f1414eee3dbaf() { 810 | console.error('Encountered a panic!'); 811 | }, 812 | "__cargo_web_snippet_de2896a7ccf316486788a4d0bc433c25d2f1a12b": function __cargo_web_snippet_de2896a7ccf316486788a4d0bc433c25d2f1a12b($0) { 813 | var r = Module.STDWEB_PRIVATE.acquire_js_reference($0); 814 | return r instanceof DOMException && r.name === "NotFoundError"; 815 | }, 816 | "__cargo_web_snippet_e741b9d9071097746386b2c2ec044a2bc73e688c": function __cargo_web_snippet_e741b9d9071097746386b2c2ec044a2bc73e688c($0, $1) { 817 | $0 = Module.STDWEB_PRIVATE.to_js($0); 818 | $1 = Module.STDWEB_PRIVATE.to_js($1); 819 | $0.appendChild($1); 820 | }, 821 | "__cargo_web_snippet_e9638d6405ab65f78daf4a5af9c9de14ecf1e2ec": function __cargo_web_snippet_e9638d6405ab65f78daf4a5af9c9de14ecf1e2ec($0) { 822 | $0 = Module.STDWEB_PRIVATE.to_js($0); 823 | Module.STDWEB_PRIVATE.unregister_raw_value($0); 824 | }, 825 | "__cargo_web_snippet_ec62bad51093fd25faa38be3170e100862e191f3": function __cargo_web_snippet_ec62bad51093fd25faa38be3170e100862e191f3($0, $1) { 826 | $0 = Module.STDWEB_PRIVATE.to_js($0); 827 | $1 = Module.STDWEB_PRIVATE.to_js($1); 828 | $0.remove($1); 829 | }, 830 | "__cargo_web_snippet_f03767d5868baf486b51c1e3988d0ce100e850ca": function __cargo_web_snippet_f03767d5868baf486b51c1e3988d0ce100e850ca($0, $1) { 831 | $1 = Module.STDWEB_PRIVATE.to_js($1); 832 | Module.STDWEB_PRIVATE.from_js($0, function () { 833 | return $1.lastChild; 834 | }()); 835 | }, 836 | "__cargo_web_snippet_f6358c198ebcc61c9da370cca2679c0b8bc81a7b": function __cargo_web_snippet_f6358c198ebcc61c9da370cca2679c0b8bc81a7b($0, $1) { 837 | $0 = Module.STDWEB_PRIVATE.to_js($0); 838 | $1 = Module.STDWEB_PRIVATE.to_js($1); 839 | $0.removeAttribute($1); 840 | }, 841 | "__cargo_web_snippet_f750c7bda400081b4d7209f43f9d59214d39f6ea": function __cargo_web_snippet_f750c7bda400081b4d7209f43f9d59214d39f6ea($0, $1, $2) { 842 | $0 = Module.STDWEB_PRIVATE.to_js($0); 843 | $1 = Module.STDWEB_PRIVATE.to_js($1); 844 | $2 = Module.STDWEB_PRIVATE.to_js($2); 845 | var listener = $0; 846 | $1.removeEventListener($2, listener); 847 | listener.drop(); 848 | }, 849 | "__cargo_web_snippet_ff5103e6cc179d13b4c7a785bdce2708fd559fc0": function __cargo_web_snippet_ff5103e6cc179d13b4c7a785bdce2708fd559fc0($0) { 850 | Module.STDWEB_PRIVATE.tmp = Module.STDWEB_PRIVATE.to_js($0); 851 | }, 852 | "__web_on_grow": __web_on_grow 853 | } 854 | }, 855 | initialize: function initialize(instance) { 856 | Object.defineProperty(Module, 'instance', { 857 | value: instance 858 | }); 859 | Object.defineProperty(Module, 'web_malloc', { 860 | value: Module.instance.exports.__web_malloc 861 | }); 862 | Object.defineProperty(Module, 'web_free', { 863 | value: Module.instance.exports.__web_free 864 | }); 865 | Object.defineProperty(Module, 'web_table', { 866 | value: Module.instance.exports.__indirect_function_table 867 | }); 868 | 869 | __web_on_grow(); 870 | 871 | Module.instance.exports.main(); 872 | return Module.exports; 873 | } 874 | }; 875 | }); 876 | }); 877 | -------------------------------------------------------------------------------- /docs/impact.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deciduously/impact/960142e3871018f47267c554e4fce21f4f8c637f/docs/impact.wasm -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | IMPACT 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "impact", 4 | "version": "0.1.1", 5 | "description": "Survive the crash!", 6 | "main": "impact.js", 7 | "repository": "https://github.com/deciduously/impact", 8 | "author": "deciduously ", 9 | "license": "MIT", 10 | "scripts": { 11 | "build:js": "rollup -c", 12 | "build:rs": "cargo web deploy --release", 13 | "build:scss": "node-sass --include-path scss scss/impact.scss css/impact.css", 14 | "build:css": "postcss --use autoprefixer -o static/impact.css css/impact.css", 15 | "build:style": "run-s build:scss build:css", 16 | "build:copy": "cp css/impact.css release/ && cp target/deploy/impact.wasm release/ && cp target/deploy/index.html release/ && cp target/deploy/favicon.ico release/", 17 | "build": "run-s clean:deploy build:rs build:js build:style build:copy", 18 | "clean:deploy": "rm -rf /release", 19 | "prod": "run-s build serve", 20 | "serve": "serve -p 8080 release", 21 | "watch:rs": "cargo web start --release", 22 | "test": "echo \"Error: no tests!\" && exit 1" 23 | }, 24 | "devDependencies": { 25 | "@babel/core": "^7.8.6", 26 | "@babel/preset-env": "^7.8.6", 27 | "@rollup/plugin-wasm": "^3.0.0", 28 | "autoprefixer": "^9.7.4", 29 | "cssnano": "^4.1.10", 30 | "node-sass": "^4.13.1", 31 | "npm-run-all": "^4.1.5", 32 | "postcss": "^7.0.27", 33 | "postcss-cli": "^7.1.0", 34 | "postcss-scss": "^2.0.0", 35 | "rollup": "^1.31.1", 36 | "rollup-plugin-babel": "^4.3.3", 37 | "rollup-plugin-postcss": "^2.1.1", 38 | "rollup-plugin-uglify": "^6.0.4", 39 | "serve": "^11.3.0" 40 | } 41 | } -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | syntax: 'postcss-scss', 3 | plugins: [ 4 | require("autoprefixer"), 5 | require("cssnano")({ 6 | preset: "default" 7 | }) 8 | ] 9 | }; -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import babel from "rollup-plugin-babel" 2 | import uglify from "rollup-plugin-uglify" 3 | 4 | export default { 5 | input: './target/deploy/impact.js', 6 | output: { 7 | name: 'impact', 8 | file: './release/impact.js', 9 | format: 'es', 10 | }, 11 | plugins: [ 12 | babel({ 13 | exclude: 'node_modules/**' 14 | }), 15 | uglify 16 | ] 17 | }; 18 | -------------------------------------------------------------------------------- /scss/impact.scss: -------------------------------------------------------------------------------- 1 | .impact { 2 | display: flex; 3 | flex-direction: column; 4 | height: 100%; 5 | width: 100%; 6 | 7 | .container { 8 | border: solid 1px #000; 9 | display: flex; 10 | flex-direction: column; 11 | overflow: hidden; 12 | 13 | >.title { 14 | border-bottom: solid 1px #000; 15 | font-weight: bold; 16 | text-align: center; 17 | } 18 | 19 | >.scroller { 20 | overflow: auto; 21 | } 22 | } 23 | 24 | .header { 25 | border-bottom: solid 1px #000; 26 | flex: 0; 27 | font-size: 72px; 28 | font-weight: bold; 29 | text-align: center; 30 | } 31 | 32 | .body { 33 | display: flex; 34 | flex: 1; 35 | flex-direction: row; 36 | 37 | .time { 38 | flex: 0; 39 | border-bottom: solid 1px #000; 40 | font-size: 14px; 41 | } 42 | 43 | } 44 | 45 | .container-resources { 46 | flex: 0 0 256px; 47 | order: 0; 48 | 49 | .resource { 50 | border: dashed 1px #000; 51 | display: flex; 52 | flex: 0; 53 | flex-direction: row; 54 | } 55 | 56 | .resource-title { 57 | display: flex; 58 | flex: 2; 59 | font-weight: bold; 60 | width: 50%; 61 | } 62 | 63 | .resource-amt { 64 | display: flex; 65 | flex: 1; 66 | font-style: italic; 67 | padding-left: 8px; 68 | } 69 | 70 | .resource-delta { 71 | display: flex; 72 | flex: 1; 73 | font-style: italic; 74 | padding-left: 2px; 75 | } 76 | } 77 | 78 | .container-control { 79 | flex: 0 0 256px; 80 | 81 | .control-button { 82 | flex: 1; 83 | } 84 | } 85 | 86 | .container-map { 87 | flex: 1 0 256px; 88 | order: 1; 89 | } 90 | 91 | .container-messages { 92 | flex: 0 0 192px; 93 | 94 | .message-time { 95 | border-bottom: solid 1px #000; 96 | flex: 0; 97 | font-weight: bold; 98 | text-align: center; 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/components/control_container.rs: -------------------------------------------------------------------------------- 1 | use types::{ 2 | actions::msg_from_actions, 3 | buttons::{Button, ButtonID, Buttons}, 4 | }; 5 | use yew::prelude::{Callback, Component, ComponentLink, Html, Renderable, ShouldRender}; 6 | 7 | type ImpactMsg = super::super::Msg; 8 | 9 | pub struct ControlContainer { 10 | title: String, 11 | buttons: Buttons, 12 | onsignal: Option>, 13 | } 14 | 15 | pub enum Msg { 16 | ButtonPressed(ImpactMsg), 17 | } 18 | 19 | #[derive(PartialEq, Clone)] 20 | pub struct Props { 21 | pub buttons: Buttons, 22 | pub onsignal: Option>, 23 | } 24 | 25 | impl Default for Props { 26 | fn default() -> Self { 27 | Props { 28 | buttons: Buttons::new(), 29 | onsignal: None, 30 | } 31 | } 32 | } 33 | 34 | impl Component for ControlContainer { 35 | type Message = Msg; 36 | type Properties = Props; 37 | 38 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 39 | ControlContainer { 40 | title: "Control".to_string(), 41 | buttons: props.buttons, 42 | onsignal: props.onsignal, 43 | } 44 | } 45 | 46 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 47 | match msg { 48 | Msg::ButtonPressed(msg) => { 49 | if let Some(ref mut callback) = self.onsignal { 50 | callback.emit(msg); 51 | } 52 | } 53 | } 54 | false 55 | } 56 | 57 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 58 | self.buttons = props.buttons; 59 | self.onsignal = props.onsignal; 60 | true 61 | } 62 | } 63 | 64 | impl Renderable for ControlContainer { 65 | fn view(&self) -> Html { 66 | let view_button = |bid: &ButtonID| { 67 | let button = Button::by_index(*bid).unwrap(); 68 | let m = msg_from_actions(&button.action()); 69 | html! { 70 | 71 | 72 | 73 | } 74 | }; 75 | // issue 121 workaround for multiple classes 76 | html! { 77 |
78 |
{&self.title}
79 |
80 | { for self.buttons.iter().map(view_button) } 81 |
82 |
83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/components/map_container.rs: -------------------------------------------------------------------------------- 1 | use types::tiles::{Tile}; 2 | use yew::prelude::{Callback, Component, ComponentLink, Html, Renderable, ShouldRender}; 3 | 4 | type ImpactMsg = super::super::Msg; 5 | 6 | pub struct MapContainer { 7 | title: String, 8 | tile: Tile, 9 | onsignal: Option>, 10 | } 11 | 12 | pub enum Msg {} 13 | 14 | #[derive(PartialEq, Clone)] 15 | pub struct Props { 16 | pub tile: Tile, 17 | pub onsignal: Option>, 18 | } 19 | 20 | impl Default for Props { 21 | fn default() -> Self { 22 | Props { 23 | tile: Tile::default(), 24 | onsignal: None, 25 | } 26 | } 27 | } 28 | 29 | impl Component for MapContainer { 30 | type Message = Msg; 31 | type Properties = Props; 32 | 33 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 34 | MapContainer { 35 | title: "Map".into(), 36 | tile: props.tile, 37 | onsignal: props.onsignal, 38 | } 39 | } 40 | 41 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 42 | true 43 | } 44 | 45 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 46 | self.tile = props.tile; 47 | self.onsignal = props.onsignal; 48 | true 49 | } 50 | } 51 | 52 | impl Renderable for MapContainer { 53 | fn view(&self) -> Html { 54 | let view_tile = |tile: &Tile| { 55 | // Tiles arent going to have controls of their own 56 | // Clean this out before doing anything else. 57 | html! { 58 | <> 59 |
{&format!("{}", tile)}
60 |
{&tile.art}
61 | 62 | } 63 | }; 64 | html! { 65 |
66 |
{&self.title}
67 |
68 | { view_tile(&self.tile) } 69 |
70 |
71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/components/messages_container.rs: -------------------------------------------------------------------------------- 1 | use types::messages::Message; 2 | use yew::prelude::{Component, ComponentLink, Html, Renderable, ShouldRender}; 3 | 4 | pub struct MessagesContainer { 5 | title: String, 6 | messages: Vec, 7 | } 8 | 9 | pub enum Msg {} 10 | 11 | #[derive(PartialEq, Clone)] 12 | pub struct Props { 13 | pub messages: Vec, 14 | } 15 | 16 | impl Default for Props { 17 | fn default() -> Self { 18 | Props { 19 | messages: Vec::new(), 20 | } 21 | } 22 | } 23 | 24 | impl Component for MessagesContainer { 25 | type Message = Msg; 26 | type Properties = Props; 27 | 28 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 29 | MessagesContainer { 30 | title: "Messages".into(), 31 | messages: props.messages, 32 | } 33 | } 34 | 35 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 36 | true 37 | } 38 | 39 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 40 | self.messages = props.messages; 41 | true 42 | } 43 | } 44 | 45 | impl Renderable for MessagesContainer { 46 | fn view(&self) -> Html { 47 | let view_message = |message: &Message| { 48 | html! { 49 |
  • 50 | 51 | {&format!("{}", message.time)} 52 | 53 | {" "}{message.content.to_string()} 54 |
  • 55 | } 56 | }; 57 | html! { 58 |
    59 |
    {&self.title}
    60 |
    61 |
      { for self.messages.iter().rev().map(view_message) }
    62 |
    63 |
    64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/components/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod control_container; 2 | pub mod map_container; 3 | pub mod messages_container; 4 | pub mod player_container; 5 | pub mod resource_container; 6 | -------------------------------------------------------------------------------- /src/components/player_container.rs: -------------------------------------------------------------------------------- 1 | use components::map_container::MapContainer; 2 | use types::{player::Player, tiles::defined_tiles}; 3 | use yew::prelude::{Component, ComponentLink, Html, Renderable, ShouldRender}; 4 | 5 | // type ImpactMsg = super::super::Msg; 6 | 7 | pub struct PlayerContainer { 8 | player: Player, 9 | } 10 | 11 | pub enum Msg {} 12 | 13 | #[derive(PartialEq, Clone)] 14 | pub struct Props { 15 | pub player: Player, 16 | } 17 | 18 | impl Default for Props { 19 | fn default() -> Self { 20 | Props { 21 | player: Player::default(), 22 | } 23 | } 24 | } 25 | 26 | impl Component for PlayerContainer { 27 | type Message = Msg; 28 | type Properties = Props; 29 | 30 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 31 | PlayerContainer { 32 | player: props.player, 33 | } 34 | } 35 | 36 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 37 | true 38 | } 39 | 40 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 41 | self.player = props.player; 42 | true 43 | } 44 | } 45 | 46 | impl Renderable for PlayerContainer { 47 | fn view(&self) -> Html { 48 | html! { 49 |
    50 |
    {&self.player.name}
    51 |
    52 | { format!("Name: {}, Current tile: {}", self.player.name, self.player.current_tile) } 53 |
    54 | 55 |
    56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/components/resource_container.rs: -------------------------------------------------------------------------------- 1 | use types::resources::{Resource, Resources}; 2 | use yew::prelude::{Component, ComponentLink, Html, Renderable, ShouldRender}; 3 | 4 | pub struct ResourceContainer { 5 | title: String, 6 | resources: Resources, 7 | } 8 | 9 | pub enum Msg {} 10 | 11 | #[derive(PartialEq, Clone)] 12 | pub struct Props { 13 | pub resources: Resources, 14 | } 15 | 16 | impl Default for Props { 17 | fn default() -> Self { 18 | Props { 19 | resources: Resources::new(), 20 | } 21 | } 22 | } 23 | 24 | impl Component for ResourceContainer { 25 | type Message = Msg; 26 | type Properties = Props; 27 | 28 | fn create(props: Self::Properties, _: ComponentLink) -> Self { 29 | ResourceContainer { 30 | title: "Resources".to_string(), 31 | resources: props.resources, 32 | } 33 | } 34 | 35 | fn update(&mut self, _msg: Self::Message) -> ShouldRender { 36 | true 37 | } 38 | 39 | fn change(&mut self, props: Self::Properties) -> ShouldRender { 40 | self.resources = props.resources; 41 | true 42 | } 43 | } 44 | 45 | impl Renderable for ResourceContainer { 46 | // TODO individual Resources-ids and inner/chidren ids after scroller 47 | fn view(&self) -> Html { 48 | let view_resource = |(resource, (amt, delta)): (&Resource, &(i64, i64))| { 49 | // TODO resource-delta 50 | html! { 51 |
    52 | {&format!("{:?}", resource)} 53 | {amt} 54 | {&format!("{}/sec", delta)} 55 |
    56 | } 57 | }; 58 | html! { 59 |
    60 |
    {&self.title}
    61 |
    { for self.resources.iter().map(view_resource) }
    62 |
    63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #![recursion_limit="256"] 2 | 3 | #[macro_use] 4 | extern crate yew; 5 | 6 | mod components; 7 | mod types; 8 | 9 | use components::{ 10 | control_container::ControlContainer, messages_container::MessagesContainer, 11 | player_container::PlayerContainer, resource_container::ResourceContainer, 12 | }; 13 | use types::{ 14 | actions::{apply_timeactions, Action}, 15 | buttons::Buttons, 16 | flags::BoolFlags, 17 | messages::Message, 18 | player::Player, 19 | resources::Resources, 20 | tiles::Tiles, 21 | time::Time, 22 | transformers::apply_transformers, 23 | }; 24 | use yew::prelude::{Component, ComponentLink, Html, Renderable, ShouldRender}; 25 | 26 | fn main() { 27 | yew::start_app::(); 28 | } 29 | 30 | pub struct Model { 31 | time: Time, 32 | resource_values: Resources, 33 | messages: Vec, 34 | bool_flags: BoolFlags, 35 | //int_flags: IntFlags, 36 | //float_flags: FloatFlags, 37 | tiles: Tiles, 38 | buttons: Buttons, 39 | player: Player, 40 | } 41 | 42 | #[derive(Debug, Clone)] 43 | pub enum Msg { 44 | Tick, 45 | PerformAction(Action), 46 | Bulk(Vec), 47 | } 48 | 49 | impl Component for Model { 50 | type Message = Msg; 51 | type Properties = (); 52 | 53 | fn create(_: Self::Properties, _: ComponentLink) -> Self { 54 | let mut ret = Model { 55 | time: Time::new(), 56 | resource_values: Resources::new(), 57 | messages: Vec::new(), 58 | bool_flags: BoolFlags::new(), 59 | //int_flags: IntFlags::new(), 60 | //float_flags: FloatFlags::new(), 61 | tiles: Tiles::new(), 62 | buttons: Buttons::new(), 63 | player: Player::new(), 64 | }; 65 | Action::AddTile(0).perform(&mut ret); 66 | ret 67 | } 68 | 69 | fn update(&mut self, msg: Self::Message) -> ShouldRender { 70 | match msg { 71 | Msg::Tick => { 72 | self.time.increment(); 73 | apply_transformers(self); 74 | apply_timeactions(self); 75 | true 76 | } 77 | Msg::PerformAction(action) => { 78 | action.perform(self); 79 | self.update(Msg::Tick); // TODO - THIS IS A CORE MECHANIC - IS THIS REALLY EACH ACTION 80 | true 81 | } 82 | Msg::Bulk(list) => { 83 | for msg in list { 84 | self.update(msg); 85 | } 86 | true 87 | } 88 | } 89 | } 90 | } 91 | 92 | impl Renderable for Model { 93 | fn view(&self) -> Html { 94 | html! { 95 | <> 96 |
    97 |
    {"IMPACT"}
    98 |
    99 | {&format!("Time: {}", self.time)} 100 | 101 | 102 | 103 |
    104 | 105 |
    106 | 109 | 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/types/actions.rs: -------------------------------------------------------------------------------- 1 | use super::super::{Model, Msg}; 2 | use types::{ 3 | buttons::{Button, ButtonID}, 4 | flags::BoolFlag, 5 | messages::Message, 6 | resources::Resource, 7 | tiles::{defined_tiles, TileID}, 8 | time::Time, 9 | transformers::Transformation, 10 | }; 11 | 12 | #[derive(Debug, Clone, PartialEq, Eq)] 13 | pub enum Action { 14 | Noop, // Just wait a tick 15 | AddMessage(String), 16 | SetBoolFlag(BoolFlag), 17 | ClearBoolFlag(BoolFlag), 18 | SetResourceValue(Resource, i64), 19 | AddResourceValue(Resource, i64), 20 | AddResourceDelta(Resource, i64), 21 | //SetIntFlag(IntFlag, i64), 22 | //SetFloatFlag(FloatFlag, i64), 23 | EnableButton(ButtonID), 24 | DisableButton(ButtonID), 25 | AddTile(TileID), 26 | } 27 | 28 | impl Action { 29 | pub fn perform(&self, model: &mut Model) { 30 | use self::Action::*; 31 | match self { 32 | Noop => {} 33 | SetBoolFlag(f) => { 34 | model.bool_flags.insert(*f, true); 35 | //apply delta 36 | if let Some(tf) = f.transformer() { 37 | for eff in tf.effects() { 38 | match eff { 39 | Transformation::Generate(r, delta) => { 40 | Action::AddResourceDelta(r, delta).perform(model); 41 | } 42 | Transformation::Consume(r, delta) => { 43 | Action::AddResourceDelta(r, -delta).perform(model); 44 | } 45 | } 46 | } 47 | } 48 | } 49 | ClearBoolFlag(f) => { 50 | model.bool_flags.insert(*f, false); 51 | //remove delta 52 | // TODO: POTENTIAL BUG 53 | // you should check if it's already false or not 54 | if let Some(tf) = f.transformer() { 55 | for eff in tf.effects() { 56 | match eff { 57 | Transformation::Generate(r, delta) => { 58 | Action::AddResourceDelta(r, -delta).perform(model); 59 | } 60 | Transformation::Consume(r, delta) => { 61 | Action::AddResourceDelta(r, delta).perform(model); 62 | } 63 | } 64 | } 65 | } 66 | } 67 | SetResourceValue(resource, amt) => { 68 | model.resource_values.insert(*resource, (*amt, 0)); 69 | } 70 | AddResourceValue(resource, delta) => { 71 | // TODO add min/maxes, and check here 72 | let r = model.resource_values.entry(*resource).or_insert((0, 0)); 73 | r.0 += *delta; 74 | } 75 | AddResourceDelta(resource, delta) => { 76 | let r = model.resource_values.entry(*resource).or_insert((0, 0)); 77 | r.1 += *delta; 78 | } 79 | AddMessage(message) => { 80 | model 81 | .messages 82 | .push(Message::new(message.to_string(), model.time)); 83 | } 84 | //SetIntFlag(f, amt) => { 85 | // model.int_flags.insert(*f, *amt); 86 | //} 87 | //SetFloatFlag(f, amt) => { 88 | // model.float_flags.insert(*f, *amt as f64); 89 | //} 90 | EnableButton(bid) => { 91 | if Button::by_index(*bid).is_some() { 92 | model.buttons.push(*bid); 93 | } 94 | } 95 | DisableButton(bid) => { 96 | if Button::by_index(*bid).is_some() { 97 | let mut button_idx: i32 = -1; 98 | for i in 0..model.buttons.len() { 99 | if model.buttons[i as usize] == *bid { 100 | button_idx = i as i32; 101 | } 102 | } 103 | if button_idx >= 0 { 104 | model.buttons.remove(button_idx as usize); 105 | } 106 | } 107 | } 108 | AddTile(tid) => { 109 | let new_tile = defined_tiles(*tid).unwrap(); 110 | model.tiles.insert(*tid, new_tile.clone()); 111 | let new_buttons = new_tile.buttons.clone(); 112 | for b in new_buttons { 113 | model.buttons.push(b); 114 | } 115 | } 116 | }; 117 | } 118 | } 119 | 120 | // TODO use references/boxes better? maybe avoid the clone? 121 | pub fn msg_from_actions(actions: &[Action]) -> Msg { 122 | if actions.is_empty() { 123 | return Msg::PerformAction(self::Action::Noop); 124 | } else if actions.len() == 1 { 125 | return Msg::PerformAction(actions[0].clone()); 126 | } 127 | 128 | let mut pas = Vec::new(); 129 | for a in actions.iter() { 130 | pas.push(Msg::PerformAction(a.clone())); 131 | } 132 | Msg::Bulk(pas) 133 | } 134 | 135 | #[derive(Debug, Clone)] 136 | pub struct TimeAction { 137 | pub time: Time, 138 | pub action: Action, //Vec? 139 | } 140 | 141 | impl TimeAction { 142 | pub fn new(tick: u64, action: Action) -> Self { 143 | TimeAction { 144 | time: Time::from(tick), 145 | action, 146 | } 147 | } 148 | } 149 | 150 | pub fn apply_timeactions(model: &mut Model) { 151 | // TODO where the heck should these live? 152 | // I don't want to reallocate the whole thing every time... 153 | let timeactions = vec![ 154 | TimeAction::new(1, Action::EnableButton(1)), 155 | TimeAction::new(15, Action::AddMessage("It's been 15 SECONDS".to_string())), 156 | ]; 157 | for ta in timeactions.iter() { 158 | if ta.time == model.time { 159 | ta.action.perform(model); 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /src/types/buttons.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | use types::{actions::Action, flags::BoolFlag, resources::Resource}; 3 | 4 | // These are your "actions available" 5 | 6 | pub type ButtonID = u32; 7 | 8 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] 9 | pub enum Button { 10 | Wait, 11 | ActivateOxygen, 12 | OpenToolbox, 13 | ApplyTape, 14 | FiddleControls, 15 | OpenDoor, 16 | } 17 | 18 | impl Button { 19 | pub fn action(self) -> Vec { 20 | match self { 21 | Button::Wait => vec![Action::Noop], 22 | Button::ActivateOxygen => vec![ 23 | Action::SetBoolFlag(BoolFlag::OxygenMonitor), 24 | Action::SetResourceValue(Resource::Oxygen, 1000), 25 | Action::SetBoolFlag(BoolFlag::LeakyTank), 26 | Action::AddMessage("Oxygen Monitor Up".into()), 27 | Action::AddMessage("Losing 10 Oxygen per second - tank leaky".into()), 28 | Action::DisableButton(1), 29 | Action::EnableButton(2), 30 | Action::EnableButton(5), 31 | ], 32 | Button::OpenToolbox => vec![ 33 | Action::AddMessage( 34 | "You unceremoniously dump the toolbox contents all over the ship".into(), 35 | ), 36 | Action::EnableButton(3), 37 | Action::EnableButton(4), 38 | Action::DisableButton(2), 39 | ], 40 | Button::ApplyTape => vec![ 41 | Action::ClearBoolFlag(BoolFlag::LeakyTank), 42 | Action::AddMessage("Leak stopped - for now.".into()), 43 | Action::DisableButton(3), 44 | ], 45 | Button::FiddleControls => vec![ 46 | Action::SetResourceValue(Resource::Power, 1), 47 | Action::SetBoolFlag(BoolFlag::PowerRegen), 48 | Action::AddMessage("You hear a loud bang from the bottom of the ship".into()), 49 | Action::AddMessage( 50 | "Your fuel cells are on and recharging from your excess oxygen".into(), 51 | ), 52 | Action::DisableButton(4), 53 | ], 54 | Button::OpenDoor => vec![ 55 | Action::AddMessage("You push the airlock open and immediately DIE.".into()), 56 | Action::AddMessage("Just kidding - everything is fine.".into()), 57 | Action::SetResourceValue(Resource::Chutzpah, 50), 58 | Action::AddTile(1), 59 | Action::DisableButton(5), 60 | ], 61 | } 62 | } 63 | 64 | pub fn by_index(idx: ButtonID) -> Option