From 1a7776b335d5515c66eada7382fd589ab764f1c7 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Sun, 4 Feb 2024 11:53:29 -0500 Subject: [PATCH] Build the animation --- Cargo.lock | 334 ++++++++++++++++++++++++++++++++++++++- falling-sand/Cargo.toml | 13 +- falling-sand/src/main.rs | 53 ++++++- 3 files changed, 381 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7039c06..66126d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -120,6 +120,17 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + [[package]] name = "async-channel" version = "2.1.1" @@ -133,6 +144,126 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "async-executor" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +dependencies = [ + "async-lock 3.3.0", + "async-task", + "concurrent-queue", + "fastrand 2.0.1", + "futures-lite 2.2.0", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.1.1", + "async-executor", + "async-io 2.3.1", + "async-lock 3.3.0", + "blocking", + "futures-lite 2.2.0", + "once_cell", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg 1.1.0", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log 0.4.20", + "parking", + "polling 2.8.0", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", +] + +[[package]] +name = "async-io" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f97ab0c5b00a7cdbe5a371b9a782ee7be1316095885c8a4ea1daf490eb0ef65" +dependencies = [ + "async-lock 3.3.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.2.0", + "parking", + "polling 3.3.2", + "rustix 0.38.28", + "slab", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener 4.0.1", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io 1.13.0", + "async-lock 2.8.0", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite 1.13.0", + "gloo-timers", + "kv-log-macro", + "log 0.4.20", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" + [[package]] name = "atoi" version = "2.0.0" @@ -142,6 +273,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "atomic-write-file" version = "0.1.2" @@ -264,6 +401,22 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "blocking" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +dependencies = [ + "async-channel 2.1.1", + "async-lock 3.3.0", + "async-task", + "fastrand 2.0.1", + "futures-io", + "futures-lite 2.2.0", + "piper", + "tracing", +] + [[package]] name = "build_html" version = "2.4.0" @@ -865,12 +1018,24 @@ dependencies = [ name = "falling-sand" version = "0.1.0" dependencies = [ + "async-channel 2.1.1", + "async-std", "cairo-rs", "gio", "glib", "glib-build-tools 0.17.10", "gtk4", "libadwaita", + "tokio", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", ] [[package]] @@ -939,7 +1104,7 @@ checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" name = "fitnesstrax" version = "0.3.0" dependencies = [ - "async-channel", + "async-channel 2.1.1", "chrono", "chrono-tz", "dimensioned 0.8.0", @@ -1136,6 +1301,34 @@ version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-lite" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" +dependencies = [ + "fastrand 2.0.1", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.29" @@ -1392,6 +1585,18 @@ dependencies = [ "system-deps", ] +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "gm-control-panel" version = "0.1.0" @@ -1763,7 +1968,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.5.5", "tokio", "tower-service", "tracing", @@ -1890,6 +2095,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + [[package]] name = "intl-memoizer" version = "0.5.1" @@ -1909,6 +2123,17 @@ dependencies = [ "unic-langid", ] +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "ipnet" version = "2.9.0" @@ -1938,7 +2163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix", + "rustix 0.38.28", "windows-sys 0.48.0", ] @@ -2017,6 +2242,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log 0.4.20", +] + [[package]] name = "language-tags" version = "0.2.2" @@ -2093,6 +2327,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + [[package]] name = "linux-raw-sys" version = "0.4.12" @@ -2123,6 +2363,9 @@ name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +dependencies = [ + "value-bag", +] [[package]] name = "logger" @@ -2675,6 +2918,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand 2.0.1", + "futures-io", +] + [[package]] name = "pkcs1" version = "0.7.5" @@ -2736,6 +2990,36 @@ dependencies = [ "miniz_oxide 0.7.1", ] +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg 1.1.0", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log 0.4.20", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "polling" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545c980a3880efd47b2e262f6a4bb6daad6555cf3367aa9c4e52895f69537a41" +dependencies = [ + "cfg-if", + "concurrent-queue", + "pin-project-lite", + "rustix 0.38.28", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -3185,6 +3469,20 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + [[package]] name = "rustix" version = "0.38.28" @@ -3194,7 +3492,7 @@ dependencies = [ "bitflags 2.4.1", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.12", "windows-sys 0.52.0", ] @@ -3454,6 +3752,16 @@ version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "socket2" version = "0.5.5" @@ -3798,9 +4106,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", - "fastrand", + "fastrand 2.0.1", "redox_syscall", - "rustix", + "rustix 0.38.28", "windows-sys 0.48.0", ] @@ -3941,7 +4249,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.5", "tokio-macros", "windows-sys 0.48.0", ] @@ -4327,6 +4635,12 @@ dependencies = [ "getrandom", ] +[[package]] +name = "value-bag" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126e423afe2dd9ac52142e7e9d5ce4135d7e13776c529d27fd6bc49f19e3280b" + [[package]] name = "vcpkg" version = "0.2.15" @@ -4372,6 +4686,12 @@ dependencies = [ "libc", ] +[[package]] +name = "waker-fn" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" + [[package]] name = "want" version = "0.3.1" diff --git a/falling-sand/Cargo.toml b/falling-sand/Cargo.toml index 17167fc..43d0795 100644 --- a/falling-sand/Cargo.toml +++ b/falling-sand/Cargo.toml @@ -6,11 +6,14 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -adw = { version = "0.5", package = "libadwaita", features = [ "v1_4" ] } -cairo-rs = { version = "0.18" } -gio = { version = "0.18" } -glib = { version = "0.18" } -gtk = { version = "0.7", package = "gtk4", features = [ "v4_10" ] } +adw = { version = "0.5", package = "libadwaita", features = [ "v1_4" ] } +async-std = { version = "1" } +async-channel = { version = "2" } +cairo-rs = { version = "0.18" } +gio = { version = "0.18" } +glib = { version = "0.18" } +gtk = { version = "0.7", package = "gtk4", features = [ "v4_10" ] } +tokio = { version = "1", features = [ "full" ] } [build-dependencies] glib-build-tools = "0.17" \ No newline at end of file diff --git a/falling-sand/src/main.rs b/falling-sand/src/main.rs index 0f43070..8778eff 100644 --- a/falling-sand/src/main.rs +++ b/falling-sand/src/main.rs @@ -1,6 +1,7 @@ +use async_channel::Sender; use glib::Object; use gtk::{prelude::*, subclass::prelude::*}; -use std::cell::RefCell; +use std::{cell::RefCell, time::Duration}; const WIDTH: usize = 601; const HEIGHT: usize = 601; @@ -35,7 +36,6 @@ impl Default for SandView { s.set_draw_func({ let s = s.clone(); move |_, context, width, height| { - println!("{} {}", width, height); context.set_source_rgb(0., 0., 0.); let _ = context.paint(); context.set_source_rgb(0.1, 0.1, 0.1); @@ -76,6 +76,7 @@ impl Default for SandView { impl SandView { fn set_area(&self, area: SandArea) { *self.imp().area.borrow_mut() = area; + self.queue_draw(); } } @@ -109,7 +110,19 @@ impl SandArea { } pub fn tick(self) -> Self { - unimplemented!() + let mut new_grains = vec![false; self.width * self.height]; + for x in 0..self.width { + for y in 1..self.height { + let addr_above = self.addr(x, y - 1); + let addr = self.addr(x, y); + new_grains[addr] = self.grains[addr_above]; + } + } + Self { + width: self.width, + height: self.height, + grains: new_grains, + } } fn addr(&self, x: usize, y: usize) -> usize { @@ -117,22 +130,48 @@ impl SandArea { } } +async fn animate(sender: Sender) { + let mut sand_area = SandArea::default(); + sand_area.add_grain(20, 20); + loop { + std::thread::sleep(Duration::from_millis(1000 / 60)); + sand_area = sand_area.tick(); + sender.send(sand_area.clone()).await; + } +} + fn main() { let app = gtk::Application::builder() .application_id("com.luminescent-dreams.falling-sand") .build(); + let (sender, receiver) = async_channel::bounded(5); + + let runtime = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap(); + let background_thread = runtime.spawn(animate(sender)); + app.connect_activate(move |app| { let window = gtk::ApplicationWindow::new(app); window.present(); let view = SandView::default(); - let mut sand_area = SandArea::default(); - sand_area.add_grain(20, 20); - view.set_area(sand_area.clone()); - window.set_child(Some(&view)); + + glib::spawn_future_local({ + let view = view.clone(); + let receiver = receiver.clone(); + async move { + while let Ok(area) = receiver.recv().await { + view.set_area(area); + } + } + }); }); app.run(); + + let _ = runtime.block_on(background_thread); }