From 2e467aca96307743bec0c7f042e36dbde05dfc31 Mon Sep 17 00:00:00 2001 From: Logan Date: Sun, 25 Aug 2024 01:20:52 -0500 Subject: [PATCH] Changed into a CGI script --- Cargo.lock | 215 +++++++++++++++++++++++++++++---------------------- Cargo.toml | 4 +- src/draw.rs | 3 + src/lib.rs | 207 ------------------------------------------------- src/main.rs | 116 +++++++++++++++++++++++++++ src/sim.rs | 23 +++--- src/tests.rs | 19 ----- 7 files changed, 252 insertions(+), 335 deletions(-) delete mode 100644 src/lib.rs create mode 100644 src/main.rs delete mode 100644 src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 51ccbc8..d98fe02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,11 +81,11 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "ash" -version = "0.37.3+1.3.251" +version = "0.38.0+1.3.281" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" dependencies = [ - "libloading 0.7.4", + "libloading", ] [[package]] @@ -134,18 +134,18 @@ dependencies = [ [[package]] name = "bit-set" -version = "0.5.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +checksum = "f0481a0e032742109b1133a095184ee93d88f3dc9e0d28a5d033dc77a073f44f" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" -version = "0.6.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22" [[package]] name = "bit_field" @@ -161,9 +161,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitstream-io" @@ -376,15 +376,24 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "d3d12" -version = "0.19.0" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307" +checksum = "bdbd1f579714e3c809ebd822c81ef148b1ceaeb3d535352afc73fd0c4c6a0017" dependencies = [ - "bitflags 2.4.1", - "libloading 0.8.1", + "bitflags 2.6.0", + "libloading", "winapi", ] +[[package]] +name = "document-features" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" +dependencies = [ + "litrs", +] + [[package]] name = "either" version = "1.9.0" @@ -431,6 +440,7 @@ dependencies = [ "futures-intrusive", "gif", "image", + "rust-cgi", "tokio", "wgpu", ] @@ -454,6 +464,12 @@ dependencies = [ "spin", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "foreign-types" version = "0.5.0" @@ -633,9 +649,9 @@ dependencies = [ [[package]] name = "glutin_wgl_sys" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" +checksum = "0a4e1951bbd9434a81aa496fe59ccc2235af3820d27b85f9314e279609211e2c" dependencies = [ "gl_generator", ] @@ -646,7 +662,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "gpu-alloc-types", ] @@ -656,14 +672,14 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", ] [[package]] name = "gpu-allocator" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884" +checksum = "fdd4240fc91d3433d5e5b0fc5b67672d771850dc19bbee03c1381e19322803d7" dependencies = [ "log", "presser", @@ -674,22 +690,22 @@ dependencies = [ [[package]] name = "gpu-descriptor" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" +checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "gpu-descriptor-types", "hashbrown", ] [[package]] name = "gpu-descriptor-types" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bf0b36e6f090b7e1d8a4b49c0cb81c1f8376f72198c65dd3ad9ff3556b8b78c" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", ] [[package]] @@ -717,10 +733,10 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "com", "libc", - "libloading 0.8.1", + "libloading", "thiserror", "widestring", "winapi", @@ -744,6 +760,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "image" version = "0.25.1" @@ -813,6 +840,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + [[package]] name = "jni-sys" version = "0.3.0" @@ -836,9 +869,9 @@ checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -850,7 +883,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" dependencies = [ "libc", - "libloading 0.8.1", + "libloading", "pkg-config", ] @@ -883,16 +916,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - [[package]] name = "libloading" version = "0.8.1" @@ -903,6 +926,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + [[package]] name = "lock_api" version = "0.4.11" @@ -955,11 +984,11 @@ checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "metal" -version = "0.27.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" +checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "block", "core-graphics-types", "foreign-types", @@ -997,17 +1026,18 @@ dependencies = [ [[package]] name = "naga" -version = "0.19.2" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e3524642f53d9af419ab5e8dd29d3ba155708267667c2f3f06c88c9e130843" +checksum = "8bd5a652b6faf21496f2cfd88fc49989c8db0825d1f6746b1a71a6ede24a63ad" dependencies = [ + "arrayvec", "bit-set", - "bitflags 2.4.1", + "bitflags 2.6.0", + "cfg_aliases", "codespan-reporting", "hexf-parse", "indexmap", "log", - "num-traits", "rustc-hash", "spirv", "termcolor", @@ -1116,16 +1146,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" dependencies = [ "malloc_buf", - "objc_exception", -] - -[[package]] -name = "objc_exception" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" -dependencies = [ - "cc", ] [[package]] @@ -1390,9 +1410,9 @@ dependencies = [ [[package]] name = "renderdoc-sys" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216080ab382b992234dda86873c18d4c48358f5cfcb70fd693d7f6f2131b628b" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] name = "rgb" @@ -1403,6 +1423,15 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "rust-cgi" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f429f64b3929e733331d856e47ac00afb9dd8cda39f0a740c5622c886754acfa" +dependencies = [ + "http", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -1523,7 +1552,7 @@ version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", ] [[package]] @@ -1584,18 +1613,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", @@ -1726,19 +1755,20 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", @@ -1751,9 +1781,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" dependencies = [ "cfg-if", "js-sys", @@ -1763,9 +1793,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1773,9 +1803,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", @@ -1786,15 +1816,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", @@ -1808,13 +1838,13 @@ checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" [[package]] name = "wgpu" -version = "0.19.4" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd7311dbd2abcfebaabf1841a2824ed7c8be443a0f29166e5d3c6a53a762c01" +checksum = "e1d1c4ba43f80542cf63a0a6ed3134629ae73e8ab51e4b765a67f3aa062eb433" dependencies = [ "arrayvec", - "cfg-if", "cfg_aliases", + "document-features", "js-sys", "log", "naga", @@ -1833,15 +1863,15 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.19.4" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b94525fc99ba9e5c9a9e24764f2bc29bad0911a7446c12f446a8277369bf3a" +checksum = "0348c840d1051b8e86c3bcd31206080c5e71e5933dabd79be1ce732b0b2f089a" dependencies = [ "arrayvec", "bit-vec", - "bitflags 2.4.1", + "bitflags 2.6.0", "cfg_aliases", - "codespan-reporting", + "document-features", "indexmap", "log", "naga", @@ -1852,22 +1882,21 @@ dependencies = [ "rustc-hash", "smallvec", "thiserror", - "web-sys", "wgpu-hal", "wgpu-types", ] [[package]] name = "wgpu-hal" -version = "0.19.4" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1a4924366df7ab41a5d8546d6534f1f33231aa5b3f72b9930e300f254e39c3" +checksum = "f6bbf4b4de8b2a83c0401d9e5ae0080a2792055f25859a02bf9be97952bbed4f" dependencies = [ "android_system_properties", "arrayvec", "ash", "bit-set", - "bitflags 2.4.1", + "bitflags 2.6.0", "block", "cfg_aliases", "core-graphics-types", @@ -1881,7 +1910,7 @@ dependencies = [ "js-sys", "khronos-egl", "libc", - "libloading 0.8.1", + "libloading", "log", "metal", "naga", @@ -1904,11 +1933,11 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "0.19.2" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b671ff9fb03f78b46ff176494ee1ebe7d603393f42664be55b64dc8d53969805" +checksum = "bc9d91f0e2c4b51434dfa6db77846f2793149d8e73f800fa2e41f52b8eac3c5d" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "js-sys", "web-sys", ] diff --git a/Cargo.toml b/Cargo.toml index b554e5c..63ea0d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,14 +6,14 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -# log = "0.4" image = "0.25" gif = "0.13" futures = "0.3" tokio = {version="1.37", features=["full"]} -wgpu = {version="0.19"} +wgpu = {version="22"} bytemuck = {version="1.14", features=["derive"]} futures-intrusive = "0.5" +rust-cgi = "0.7" [profile.dev] diff --git a/src/draw.rs b/src/draw.rs index 034b352..e32d3fb 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -244,14 +244,17 @@ impl QuickDraw { multiview: None, label: Some("Render Pipeline"), layout: Some(&render_pipeline_layout), + cache: None, vertex: wgpu::VertexState { module: &vert, entry_point: "vs_main", buffers: &[Vertex::desc(), Circle::desc()], + compilation_options: PipelineCompilationOptions::default(), }, fragment: Some(wgpu::FragmentState { module: &frag, entry_point: "fs_main", + compilation_options: PipelineCompilationOptions::default(), targets: &[Some(wgpu::ColorTargetState { format: texture_desc.format, blend: Some(wgpu::BlendState::ALPHA_BLENDING), diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index a5f2b35..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,207 +0,0 @@ -#![feature(future_join)] -use std::{ - cell::RefCell, - future::join, - io::{Cursor, Write}, - path::Path, - sync::Arc, -}; - -use tokio::sync::Mutex; - -use draw::QuickDraw; -use gif::Frame; -use image::{ImageBuffer, Rgb}; - -pub mod draw; -pub mod helper; -pub mod sim; -pub mod tests; - -const WIDTH: f32 = 512.0; -const HEIGHT: f32 = 512.0; - -pub async fn preprocess( - image: ImageBuffer, Vec>, - radius: f32, -) -> (sim::Simulation, usize, usize) { - let (sim, it, max_circles) = - sim::Simulation::simulate_image(WIDTH, HEIGHT, radius, image).await; - (sim, it, max_circles) -} - -pub async fn simulate( - draw: Arc>, - mut sim: Simulation, - it: usize, - step: usize, - max_circles: usize, -) -> Vec> { - let _draw = draw; - let mut draw = _draw.lock().await; - draw.resize(WIDTH as u32, HEIGHT as u32, max_circles).await; - let mut frames = vec![]; - // let progress = - // make_progress("Simulating ", ((it - sim.clock) / - // sim.substeps) as u64); - while sim.clock < it { - let circles = &sim - .circles - .iter() - .map(|c| draw::Circle { - position: [c.position.x, c.position.y], - radius: c.radius, - color: [c.color.0, c.color.1, c.color.2, 255], - }) - .collect::>(); - let bytes_future = draw.draw_circles(circles); - let steps = sim.steps(step); - let mut bytes = join!(bytes_future, steps).await.0; - let frame = - gif::Frame::from_rgba_speed(WIDTH as u16, HEIGHT as u16, &mut bytes, 10); - frames.push(frame); - // progress.inc(step as u64); - } - // progress.finish(); - frames -} - -pub async fn encode(frames: Vec>, repeat: bool) -> Vec { - let mut buffer = Vec::::new(); - let mut encoder = - gif::Encoder::new(&mut buffer, WIDTH as u16, HEIGHT as u16, &[]).unwrap(); - for mut frame in frames { - frame.delay = 1; - encoder.write_frame(&frame).unwrap(); - } - if repeat { - encoder.set_repeat(gif::Repeat::Infinite).unwrap(); - } - drop(encoder); - buffer -} - -// use clap::Parser; -use sim::Simulation; -// #[derive(Parser, Debug)] -// #[command(author, version, about, long_about = None)] -// struct Args { -// /// Input file to process. All common image types are -// /// supported, see the `image` crate docs for specific -// /// compatibility -// #[arg(short = 'i', value_hint = -// clap::ValueHint::DirPath)] input: std::path::PathBuf, -// -// /// Output file path ('./output.gif' by default) -// #[arg(short = 'o', value_hint = -// clap::ValueHint::DirPath)] -// output: Option, -// -// /// How many physics-steps between frames. Affects the -// /// speed and length of the animation -// #[arg(short = 's')] -// step: Option, -// -// /// Radius of the circle, smaller means more detailed -// but /// slower to compute (8.0 by default, must be -// between /// 1.0 and 50.0 inclusive) -// #[arg(short = 'r')] -// radius: Option, -// -// /// Loop the GIF -// #[arg(short = 'l', long = "loop")] -// looping: bool, -// } -// -// fn open_image>(path: P) -> -// ImageBuffer, Vec> { let image = match -// image::io::Reader::open(path) { Ok(i) => i, -// Err(e) => { -// eprintln!("Error opening file for processing: "); -// eprintln!("{}", e); -// std::process::exit(1); -// }, -// }; -// -// let decoded = match image.decode() { -// Ok(d) => d, -// Err(e) => { -// eprintln!("Error processing file: "); -// eprintln!("{}", e); -// std::process::exit(1); -// }, -// }; -// decoded.to_rgb8() -// } - -#[derive(Debug, Clone)] -pub enum Error { - CantGuessFormat, - DecodeError, -} - -pub async fn make_quickdraw() -> Option>> { - Some(Arc::new(Mutex::new(QuickDraw::new(512, 512, 1000).await?))) -} - -pub async fn make_gif( - input: &[u8], - draw: Arc>, -) -> Result, Error> { - let step = 20; - let radius = 7.0; - let image = image::io::Reader::new(Cursor::new(input.to_vec().as_slice())) - .with_guessed_format() - .map_err(|_| Error::CantGuessFormat)? - .decode() - .map_err(|_| Error::DecodeError)? - .to_rgb8(); - let (sim, it, max) = preprocess(image, radius).await; - let frames = simulate(draw, sim, it, step, max).await; - let gif = encode(frames, true).await; - Ok(gif) -} - -// fn main() { -// let args = Args::parse(); -// -// let output = -// args.output.unwrap_or("output.gif".into()); let step = -// args.step.unwrap_or(20) as usize; if step == 0 { -// eprintln!("Physics step cannot be 0"); -// std::process::exit(1); -// } -// let radius = args.radius.unwrap_or(8.0); -// if radius < 1.0 || radius > 50.0 { -// eprintln!("Invalid radius {}", radius); -// eprintln!("Must be between 1.0 and 50.0 inclusive"); -// std::process::exit(1); -// } -// -// let image = open_image(args.input); -// let (sim, it, max) = -// pollster::block_on(preprocess(image, radius)); -// let mut draw = pollster::block_on(QuickDraw::new(512, -// 512, 1000)); let frames = -// pollster::block_on(simulate(&mut draw, sim, it, step, -// max)); let gif = pollster::block_on(encode(frames, -// args.looping)); let mut file = match -// std::fs::File::create(output.clone()) { Ok(f) => f, -// Err(e) => { -// eprintln!("Error opening file for writing:"); -// eprintln!("{}", e); -// std::process::exit(1); -// }, -// }; -// -// match file.write(&gif) { -// Ok(_) => { -// println!("Successfully created file at '{}'", -// output.display()); }, -// Err(e) => { -// eprintln!("Error writing output file: "); -// eprintln!("{}", e); -// std::process::exit(1); -// }, -// }; -// } diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..d8acbf5 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,116 @@ +#![feature(future_join)] +use std::{io::Cursor, sync::Arc}; + +use tokio::sync::Mutex; + +use draw::QuickDraw; +use gif::Frame; +use image::{ImageBuffer, Rgb}; + +pub mod draw; +pub mod helper; +pub mod sim; + +const WIDTH: f32 = 512.0; +const HEIGHT: f32 = 512.0; + +pub async fn preprocess( + image: ImageBuffer, Vec>, + radius: f32, +) -> (sim::Simulation, usize, usize) { + let (sim, it, max_circles) = + sim::Simulation::simulate_image(WIDTH, HEIGHT, radius, image); + (sim, it, max_circles) +} + +pub async fn simulate( + draw: Arc>, + mut sim: Simulation, + it: usize, + step: usize, + max_circles: usize, +) -> Vec> { + let _draw = draw; + let mut draw = _draw.lock().await; + draw.resize(WIDTH as u32, HEIGHT as u32, max_circles).await; + let mut frames = vec![]; + while sim.clock < it { + let circles = &sim + .circles + .iter() + .map(|c| draw::Circle { + position: [c.position.x, c.position.y], + radius: c.radius, + color: [c.color.0, c.color.1, c.color.2, 255], + }) + .collect::>(); + sim.steps(step); + let mut bytes = draw.draw_circles(circles).await; + let frame = + gif::Frame::from_rgba_speed(WIDTH as u16, HEIGHT as u16, &mut bytes, 10); + frames.push(frame); + } + frames +} + +pub async fn encode(frames: Vec>, repeat: bool) -> Vec { + let mut buffer = Vec::::new(); + let mut encoder = + gif::Encoder::new(&mut buffer, WIDTH as u16, HEIGHT as u16, &[]).unwrap(); + for mut frame in frames { + frame.delay = 1; + encoder.write_frame(&frame).unwrap(); + } + if repeat { + encoder.set_repeat(gif::Repeat::Infinite).unwrap(); + } + drop(encoder); + buffer +} + +use sim::Simulation; + +#[derive(Debug, Clone)] +pub enum Error { + CantGuessFormat, + DecodeError, +} + +pub async fn make_quickdraw() -> Option>> { + Some(Arc::new(Mutex::new(QuickDraw::new(512, 512, 1000).await?))) +} + +pub async fn make_gif( + input: &[u8], + draw: Arc>, +) -> Result, Error> { + const STEP: usize = 20; + const RADIUS: f32 = 7.0; + let image = image::io::Reader::new(Cursor::new(input.to_vec().as_slice())) + .with_guessed_format() + .map_err(|_| Error::CantGuessFormat)? + .decode() + .map_err(|_| Error::DecodeError)? + .to_rgb8(); + let (sim, it, max) = preprocess(image, RADIUS).await; + let frames = simulate(draw, sim, it, STEP, max).await; + let gif = encode(frames, true).await; + Ok(gif) +} + +use rust_cgi as cgi; + +const CONTENT_TYPE: &'static str = "Content-Type: image/gif"; + +rust_cgi::cgi_main!(|req: cgi::http::Request>| -> rust_cgi::Response { + let qd = match futures::executor::block_on(make_quickdraw()) { + Some(qd) => qd, + None => return cgi::text_response(500, "Failed to initialize WGPU"), + }; + let image = req.into_body(); + let gif = match futures::executor::block_on(make_gif(&image, qd)) { + Ok(gif) => gif, + Err(_) => return cgi::text_response(500, "Failed to process image"), + }; + rust_cgi::binary_response(200, CONTENT_TYPE, gif) +}); diff --git a/src/sim.rs b/src/sim.rs index eb954eb..e8467ae 100644 --- a/src/sim.rs +++ b/src/sim.rs @@ -55,10 +55,7 @@ impl Simulation { } #[inline] - async fn assign_colors_from_image( - &mut self, - img: ImageBuffer, Vec>, - ) { + fn assign_colors_from_image(&mut self, img: ImageBuffer, Vec>) { let (width, height) = (img.width() as f32 - 1.0, img.height() as f32 - 1.0); for (pos, index) in self.circles.iter().map(|c| (c.position, c.index)) { let img_x = @@ -73,7 +70,7 @@ impl Simulation { } #[inline] - pub async fn simulate_image( + pub fn simulate_image( width: f32, height: f32, circle_radius: f32, @@ -90,17 +87,17 @@ impl Simulation { // (sim.max_circles + Self::POST_PROCESS) as u64, // ); while sim.circles() < sim.max_circles { - sim.step().await; + sim.step(); // progress.inc(2); } for _ in 0..Self::POST_PROCESS { - sim.step().await; + sim.step(); // progress.inc(1); } // progress.finish(); let total_iterations = sim.clock; let max_circles = sim.circles.len(); - sim.assign_colors_from_image(img).await; + sim.assign_colors_from_image(img); sim.circles.clear(); sim.clock = sim.rand_seed; (sim, total_iterations, max_circles) @@ -218,7 +215,7 @@ impl Simulation { } #[inline] - pub async fn step(&mut self) { + pub fn step(&mut self) { if self.circles.len() < self.max_circles { self.launch(); } @@ -236,13 +233,11 @@ impl Simulation { } #[inline] - pub async fn steps(&mut self, steps: usize) { + pub fn steps(&mut self, steps: usize) { for _ in 0..steps { - self.step().await; + self.step(); } } - pub fn circles(&self) -> usize { - self.circles.len() - } + pub fn circles(&self) -> usize { self.circles.len() } } diff --git a/src/tests.rs b/src/tests.rs deleted file mode 100644 index 2b53a78..0000000 --- a/src/tests.rs +++ /dev/null @@ -1,19 +0,0 @@ -#[cfg(test)] -#[test] -fn bench_async() { - use std::io::Write; - // flexi_logger::Logger::try_with_str("debug").unwrap(); - - let image = image::io::Reader::open( - "resources/mona - lisa.png", - ) - .unwrap() - .decode() - .unwrap() - .to_rgb8(); - // let gif = pollster::block_on(crate::generate_async(image, None)); - // let mut file = - // std::fs::File::create("test.gif").unwrap(); - // file.write(&gif).unwrap(); -}