diff --git a/Cargo.lock b/Cargo.lock index 6726e901..49ca691f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,6 +48,21 @@ dependencies = [ "memchr 2.7.2", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "allocator-api2" version = "0.2.18" @@ -102,6 +117,29 @@ version = "2.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "220a2c618ab466efe41d0eace94dfeff1c35e3aa47891bdb95e1c0fefffd3c99" +[[package]] +name = "atk" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4af014b17dd80e8af9fa689b2d4a211ddba6eb583c1622f35d0cb543f6b17e4" +dependencies = [ + "atk-sys", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "251e0b7d90e33e0ba930891a505a9a35ece37b2dd37a14f3ffc306c13b980009" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -131,9 +169,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.22.1" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" @@ -287,11 +325,115 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "cadmium-native" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", + "tauri", + "tauri-build", +] + +[[package]] +name = "cairo-rs" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +dependencies = [ + "bitflags 2.5.0", + "cairo-sys-rs", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "camino" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cargo_toml" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a969e13a7589e9e3e4207e153bae624ade2b5622fb4684a4923b23ec3d57719" +dependencies = [ + "serde", + "toml 0.8.2", +] + [[package]] name = "cc" -version = "1.0.98" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] [[package]] name = "cfg-if" @@ -328,7 +470,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets", + "windows-targets 0.52.5", ] [[package]] @@ -396,12 +538,55 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.4.2" @@ -411,6 +596,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-deque" version = "0.8.5" @@ -436,6 +630,53 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.66", +] + +[[package]] +name = "ctor" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" +dependencies = [ + "quote", + "syn 2.0.66", +] + [[package]] name = "darling" version = "0.20.9" @@ -563,6 +804,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "dlib" version = "0.5.2" @@ -612,9 +864,9 @@ checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" [[package]] name = "dtoa-short" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" dependencies = [ "dtoa", ] @@ -1143,6 +1395,69 @@ dependencies = [ "web-sys", ] +[[package]] +name = "gobject-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gtk" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93c4f5e0e20b60e10631a5f06da7fe3dda744b05ad0ea71fee2f47adf865890c" +dependencies = [ + "atk", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771437bf1de2c1c0b496c11505bdf748e26066bbe942dfc8f614c9460f6d7722" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk3-macros" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6063efb63db582968fb7df72e1ae68aa6360dcfb0a75143f34fc7d616bad75e" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "hash32" version = "0.3.1" @@ -1180,9 +1495,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.5.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "heck" @@ -1224,7 +1539,7 @@ checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", - "itoa 1.0.9", + "itoa 1.0.11", ] [[package]] @@ -1239,12 +1554,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "futures-core", + "futures-util", "http", "http-body", "pin-project-lite", @@ -1252,9 +1567,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "9f3935c160d00ac752e09787e6e6bfc26494c2183cc922f1bc678a60d4733bc2" [[package]] name = "hyper" @@ -1268,7 +1583,7 @@ dependencies = [ "http", "http-body", "httparse", - "itoa 1.0.9", + "itoa 1.0.11", "pin-project-lite", "smallvec", "tokio", @@ -1306,7 +1621,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core 0.51.1", + "windows-core 0.52.0", ] [[package]] @@ -1329,19 +1644,139 @@ dependencies = [ ] [[package]] -name = "ident_case" -version = "1.0.1" +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", + "smallvec", + "utf8_iter", ] [[package]] @@ -1366,10 +1801,34 @@ dependencies = [ "serde", ] +[[package]] +name = "infer" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb33622da908807a06f9513c19b3c1ad50fab3e4137d82a78107d502075aa199" +dependencies = [ + "cfb", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "isotope" version = "0.1.0" -source = "git+https://github.com/CADmium-Co/ISOtope.git#b060531aa3841103011168885c4fea47cc0dc490" +source = "git+https://github.com/CADmium-Co/ISOtope.git#f2f4590e552e3407ae19d811e56cd4c1c83039db" dependencies = [ "geo", "nalgebra", @@ -1415,6 +1874,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + [[package]] name = "itoa" version = "1.0.11" @@ -1599,6 +2064,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e" +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "lock_api" version = "0.4.12" @@ -1615,6 +2086,21 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + [[package]] name = "lz4_flex" version = "0.7.5" @@ -1712,6 +2198,15 @@ version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.3.17" @@ -1734,6 +2229,36 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "muda" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b959f97c97044e4c96e32e1db292a7d594449546a3c6b77ae613dc3a5b5145" +dependencies = [ + "cocoa", + "crossbeam-channel", + "dpi", + "gtk", + "keyboard-types", + "objc", + "once_cell", + "png", + "serde", + "thiserror", + "windows-sys 0.52.0", +] + [[package]] name = "nalgebra" version = "0.32.5" @@ -1762,6 +2287,47 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ndk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys", + "num_enum", + "raw-window-handle 0.5.2", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.4.1+23.1.7779620" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + [[package]] name = "nom" version = "3.2.1" @@ -2077,7 +2643,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.52.5", ] [[package]] @@ -2087,160 +2653,332 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] -name = "pkg-config" -version = "0.3.30" +name = "percent-encoding" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] -name = "plist" -version = "1.6.1" +name = "phf" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "base64 0.21.5", - "indexmap 2.1.0", - "line-wrap", - "quick-xml 0.31.0", - "serde", - "time", + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", ] [[package]] -name = "png" -version = "0.17.13" +name = "phf" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", + "phf_shared 0.10.0", ] [[package]] -name = "powerfmt" -version = "0.2.0" +name = "phf" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros 0.11.2", + "phf_shared 0.11.2", +] [[package]] -name = "ppv-lite86" -version = "0.2.17" +name = "phf_codegen" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] [[package]] -name = "precomputed-hash" -version = "0.1.1" +name = "phf_codegen" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] [[package]] -name = "proc-macro-crate" -version = "1.3.1" +name = "phf_generator" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" dependencies = [ - "once_cell", - "toml_edit 0.19.15", + "phf_shared 0.8.0", + "rand 0.7.3", ] [[package]] -name = "proc-macro-crate" -version = "2.0.2" +name = "phf_generator" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", + "phf_shared 0.10.0", + "rand 0.8.5", ] [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "phf_generator" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ - "proc-macro-error-attr", + "phf_shared 0.11.2", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", "proc-macro2", "quote", "syn 1.0.109", - "version_check", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "phf_macros" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", "proc-macro2", "quote", - "version_check", + "syn 2.0.66", ] [[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" +name = "phf_shared" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] [[package]] -name = "proc-macro2" -version = "1.0.85" +name = "phf_shared" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" dependencies = [ - "unicode-ident", + "siphasher", ] [[package]] -name = "quick-xml" -version = "0.22.0" +name = "phf_shared" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" dependencies = [ - "memchr 2.7.2", - "serde", + "siphasher", ] [[package]] -name = "quick-xml" -version = "0.31.0" +name = "pin-project" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ - "memchr 2.7.2", + "pin-project-internal", ] [[package]] -name = "quote" -version = "1.0.36" +name = "pin-project-internal" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", + "quote", + "syn 2.0.66", ] [[package]] -name = "rand" -version = "0.7.3" +name = "pin-project-lite" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", - "rand_pcg", -] +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] -name = "rand" -version = "0.8.5" +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "plist" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9" +dependencies = [ + "base64 0.21.7", + "indexmap 2.2.6", + "line-wrap", + "quick-xml 0.31.0", + "serde", + "time", +] + +[[package]] +name = "png" +version = "0.17.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +dependencies = [ + "toml_datetime", + "toml_edit 0.20.2", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quick-xml" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b" +dependencies = [ + "memchr 2.7.2", + "serde", +] + +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr 2.7.2", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ @@ -2287,6 +3025,36 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + [[package]] name = "rawpointer" version = "0.2.1" @@ -2344,32 +3112,47 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr 2.7.2", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr 2.7.2", - "regex-syntax", + "regex-syntax 0.8.4", ] [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" @@ -2526,7 +3309,7 @@ checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" dependencies = [ "proc-macro2", "quote", - "serde_derive_internals", + "serde_derive_internals 0.29.1", "syn 2.0.66", ] @@ -2567,6 +3350,9 @@ name = "semver" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] [[package]] name = "serde" @@ -2616,7 +3402,7 @@ version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ - "itoa 1.0.9", + "itoa 1.0.11", "ryu", "serde", ] @@ -2648,7 +3434,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.9", + "itoa 1.0.11", "ryu", "serde", ] @@ -2684,70 +3470,203 @@ dependencies = [ ] [[package]] -name = "simba" -version = "0.8.1" +name = "serialize-to-javascript" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" +checksum = "c9823f2d3b6a81d98228151fdeaf848206a7855a7a042bbf9bf870449a66cafb" dependencies = [ - "approx 0.5.1", - "num-complex", - "num-traits", - "paste", - "wide", + "serde", + "serde_json", + "serialize-to-javascript-impl", ] [[package]] -name = "smallvec" -version = "1.13.2" +name = "serialize-to-javascript-impl" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] -name = "spade" -version = "2.8.0" +name = "servo_arc" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b20a809169ae442497e41a997fc5f14e2eea04e6ac590816a910d5d8068c8c0" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" dependencies = [ - "hashbrown 0.14.5", - "num-traits", - "robust", - "smallvec", + "nodrop", + "stable_deref_trait", ] [[package]] -name = "stable_deref_trait" -version = "1.2.0" +name = "sha2" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] [[package]] -name = "state" -version = "0.6.0" +name = "sharded-slab" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ - "loom", + "lazy_static", ] [[package]] -name = "string_cache" -version = "0.8.7" +name = "simba" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" dependencies = [ - "new_debug_unreachable", - "once_cell", - "parking_lot", - "phf_shared 0.10.0", - "precomputed-hash", - "serde", + "approx 0.5.1", + "num-complex", + "num-traits", + "paste", + "wide", ] [[package]] -name = "string_cache_codegen" -version = "0.5.2" +name = "simd-adler32" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "softbuffer" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d09e57a5a6b300bf917329da0ff30a58737d83abb7b14f99a419c23e83007cb8" +dependencies = [ + "bytemuck", + "cfg_aliases", + "core-graphics", + "foreign-types", + "js-sys", + "log", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-quartz-core", + "raw-window-handle 0.6.2", + "redox_syscall", + "wasm-bindgen", + "wayland-sys", + "web-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "soup3" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f" +dependencies = [ + "futures-channel", + "gio", + "glib", + "libc", + "soup3-sys", +] + +[[package]] +name = "soup3-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "spade" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b20a809169ae442497e41a997fc5f14e2eea04e6ac590816a910d5d8068c8c0" +dependencies = [ + "hashbrown 0.14.5", + "num-traits", + "robust", + "smallvec", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "state" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" +dependencies = [ + "loom", +] + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared 0.10.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" dependencies = [ "phf_generator 0.10.0", "phf_shared 0.10.0", @@ -2772,11 +3691,11 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.26.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7993a8e3a9e88a00351486baae9522c91b123a088f76469e5bd5cc17198ea87" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", @@ -2795,7 +3714,7 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bbdb58577b6301f8d17ae2561f32002a5bae056d444e0f69e611e504a276204" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "serde", "serde_json", ] @@ -2828,6 +3747,17 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "system-deps" version = "6.2.2" @@ -3150,7 +4080,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", - "itoa", + "itoa 1.0.11", "num-conv", "powerfmt", "serde", @@ -3174,11 +4104,77 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.19.15", +] + +[[package]] +name = "toml" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.20.2", +] + [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -3187,6 +4183,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.2.6", + "serde", + "serde_spanned", "toml_datetime", "winnow", ] @@ -3197,7 +4195,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", @@ -3294,9 +4292,9 @@ dependencies = [ [[package]] name = "tray-icon" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b27516dfcfa22a9faaf192283a122bfbede38c1e59ef194e3c4db6549b419c0" +checksum = "3ad8319cca93189ea9ab1b290de0595960529750b6b8b501a399ed1ec3775d60" dependencies = [ "cocoa", "core-graphics", @@ -3517,26 +4515,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "unicode-ident" -version = "1.0.12" +name = "unic-char-property" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] [[package]] -name = "unicode-segmentation" -version = "1.11.0" +name = "unic-char-range" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-ucd-ident" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] [[package]] -name = "unicode-normalization" -version = "0.1.23" +name = "unic-ucd-version" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" dependencies = [ - "tinyvec", + "unic-common", ] +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + [[package]] name = "unicode-segmentation" version = "1.11.0" @@ -3545,9 +4569,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "url" -version = "2.5.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56" dependencies = [ "form_urlencoded", "idna", @@ -3574,6 +4598,18 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "uuid" version = "1.8.0" @@ -3698,9 +4734,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -3772,67 +4808,340 @@ dependencies = [ ] [[package]] -name = "wide" -version = "0.7.22" +name = "webkit2gtk" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c5cb32c74fe55350a3272ba792f050613e692253ae0d89ad5d83eb0dcea15e1" +checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a" dependencies = [ - "bytemuck", - "safe_arch", + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup3", + "webkit2gtk-sys", ] [[package]] -name = "windows-core" -version = "0.52.0" +name = "webkit2gtk-sys" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c" dependencies = [ - "windows-targets", + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pkg-config", + "soup3-sys", + "system-deps", ] [[package]] -name = "windows-targets" -version = "0.52.5" +name = "webview2-com" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "5c914dd492a52f0377bef56fd1b6e74a79090f9ee631d625d5b505a00e4538b6" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "webview2-com-macros", + "webview2-com-sys", + "windows 0.56.0", + "windows-core 0.56.0", + "windows-implement", + "windows-interface", ] [[package]] -name = "windows-version" -version = "0.1.1" +name = "webview2-com-macros" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6998aa457c9ba8ff2fb9f13e9d2a930dabcea28f1d0ab94d687d8b3654844515" +checksum = "ac1345798ecd8122468840bcdf1b95e5dc6d2206c5e4b0eafa078d061f59c9bc" dependencies = [ - "windows-targets 0.52.5", + "proc-macro2", + "quote", + "syn 2.0.66", ] [[package]] -name = "windows_aarch64_gnullvm" +name = "webview2-com-sys" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a46bcf03482ec28eeb764ca788f67998cde4213adfbbfa90462622058530f5e" +dependencies = [ + "thiserror", + "windows 0.56.0", + "windows-core 0.56.0", +] + +[[package]] +name = "wide" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a040b111774ab63a19ef46bbc149398ab372b4ccdcfd719e9814dbd7dfd76c8" +dependencies = [ + "bytemuck", + "safe_arch", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "window-vibrancy" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33082acd404763b315866e14a0d5193f3422c81086657583937a750cdd3ec340" +dependencies = [ + "cocoa", + "objc", + "raw-window-handle 0.6.2", + "windows-sys 0.52.0", + "windows-version", +] + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" +dependencies = [ + "windows-core 0.56.0", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-core" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-implement" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "windows-interface" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + +[[package]] +name = "windows-version" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6998aa457c9ba8ff2fb9f13e9d2a930dabcea28f1d0ab94d687d8b3654844515" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.5" @@ -3845,24 +5154,72 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.5" @@ -3878,6 +5235,91 @@ dependencies = [ "memchr 2.7.2", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "wry" +version = "0.40.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa597526af53f310a8e6218630c5024fdde8271f229e70d7d2fc70b52b8fb1e" +dependencies = [ + "base64 0.22.1", + "block", + "cocoa", + "core-graphics", + "crossbeam-channel", + "dpi", + "dunce", + "gdkx11", + "gtk", + "html5ever", + "http", + "javascriptcore-rs", + "jni", + "kuchikiki", + "libc", + "ndk", + "ndk-context", + "ndk-sys", + "objc", + "objc_id", + "once_cell", + "percent-encoding", + "raw-window-handle 0.6.2", + "sha2", + "soup3", + "tao-macros", + "thiserror", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows 0.56.0", + "windows-core 0.56.0", + "windows-version", + "x11-dl", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + [[package]] name = "xz2" version = "0.1.7" @@ -3887,6 +5329,30 @@ dependencies = [ "lzma-sys", ] +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.34" @@ -3906,3 +5372,46 @@ dependencies = [ "quote", "syn 2.0.66", ] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] diff --git a/README.md b/README.md index a9685f80..0e27cdad 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,8 @@ cargo test Simple exaples using the rust code can be found in `packages/cadmium/examples` Run simple rust example with: -``` + +```shell cargo run --example project_simple_extrusion ``` diff --git a/applications/web/src/components/AppBar.svelte b/applications/web/src/components/AppBar.svelte index 708f6a63..dd3dfcff 100644 --- a/applications/web/src/components/AppBar.svelte +++ b/applications/web/src/components/AppBar.svelte @@ -109,10 +109,10 @@
- +
- +
diff --git a/packages/cadmium-macros/src/lib.rs b/packages/cadmium-macros/src/lib.rs index 355da664..32f39452 100644 --- a/packages/cadmium-macros/src/lib.rs +++ b/packages/cadmium-macros/src/lib.rs @@ -10,6 +10,15 @@ pub fn message_handler_derive(input: proc_macro::TokenStream) -> proc_macro::Tok _ => panic!("MessageEnum can only be derived for enums"), }; + let variants_type = data.variants.iter().map(|variant| { + let syn::Fields::Unnamed(field) = &variant.fields else { + panic!("MessageEnum can only be derived for enums with unnamed fields"); + }; + + let field_type = &field.unnamed[0].ty; + quote! { #field_type } + }).collect::>(); + let variants = data.variants.iter().map(|variant| { println!("Message Handler: {}", variant.ident); let variant_name = &variant.ident; @@ -21,6 +30,7 @@ pub fn message_handler_derive(input: proc_macro::TokenStream) -> proc_macro::Tok let variant_names = data.variants.iter().map(|variant| &variant.ident).collect::>(); let variants_clone = variants.clone(); + let variants_clone2 = variants.clone(); quote! { impl #name { @@ -31,6 +41,14 @@ pub fn message_handler_derive(input: proc_macro::TokenStream) -> proc_macro::Tok } } + #( + impl From<#variants_type> for #name { + fn from(msg: #variants_type) -> Self { + #variants_clone2 + } + } + )* + impl std::fmt::Display for #name { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/packages/cadmium/examples/project_simple_extrusion.rs b/packages/cadmium/examples/project_simple_extrusion.rs index 98a7425b..58508d00 100644 --- a/packages/cadmium/examples/project_simple_extrusion.rs +++ b/packages/cadmium/examples/project_simple_extrusion.rs @@ -1,8 +1,8 @@ use cadmium::workbench::AddSketch; -use cadmium::solid::extrusion::{self, Direction, Mode}; +use cadmium::feature::extrusion::{self, Direction, Mode}; use cadmium::project::Project; use cadmium::message::MessageHandler as _; -use cadmium::isketch::{AddLine, AddPoint}; +use cadmium::isketch::primitive::{AddLine, AddPoint}; use cadmium::archetypes::PlaneDescription; fn main() { @@ -22,12 +22,12 @@ fn main() { AddLine { start: ur, end: ul }.handle_message(sketch.clone()).unwrap(); AddLine { start: ul, end: ll }.handle_message(sketch.clone()).unwrap(); - let faces = sketch.borrow().sketch().borrow().get_faces(); - extrusion::Add { sketch_id, faces, length: 25.0, offset: 0.0, direction: Direction::Normal, mode: Mode::New }.handle_message(wb_ref.clone()).unwrap(); + extrusion::Add { sketch_id, faces: vec![0], length: 25.0, offset: 0.0, direction: Direction::Normal, mode: Mode::New }.handle_message(wb_ref.clone()).unwrap(); let wb = wb_ref.borrow(); - let solid_ref = wb.solids.first_key_value().unwrap().1; - let solid = solid_ref.borrow(); + let feature_ref = wb.features.first_key_value().unwrap().1; + let solid_like = feature_ref.borrow().as_solid_like().to_solids().unwrap(); + let solid = solid_like.get(0).unwrap(); println!("{:?}", solid); diff --git a/packages/cadmium/src/archetypes.rs b/packages/cadmium/src/archetypes.rs index 3450df57..7d7988f0 100644 --- a/packages/cadmium/src/archetypes.rs +++ b/packages/cadmium/src/archetypes.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use truck_modeling::Plane as TruckPlane; use truck_modeling::InnerSpace; -use crate::solid::point::Point3; +use crate::feature::point::Point3; use crate::IDType; #[derive(Tsify, Debug, Clone, Serialize, Deserialize)] diff --git a/packages/cadmium/src/solid/extrusion.rs b/packages/cadmium/src/feature/extrusion.rs similarity index 60% rename from packages/cadmium/src/solid/extrusion.rs rename to packages/cadmium/src/feature/extrusion.rs index 2c3747f4..7501ce8e 100644 --- a/packages/cadmium/src/solid/extrusion.rs +++ b/packages/cadmium/src/feature/extrusion.rs @@ -1,7 +1,8 @@ -use std::cell::RefCell; +use std::cell::{RefCell, RefMut}; use std::rc::Rc; use isotope::decompose::face::Face; +use itertools::Itertools; use serde::{Deserialize, Serialize}; use truck_modeling::builder; use tsify_next::Tsify; @@ -15,9 +16,7 @@ use crate::workbench::Workbench; use crate::IDType; use super::get_isoface_wires; -use super::Feature; -use super::FeatureCell; -use super::SolidLike; +use super::{Feature, SolidLike}; #[derive(Tsify, Debug, Clone, Serialize, Deserialize)] #[tsify(into_wasm_abi, from_wasm_abi)] @@ -67,7 +66,7 @@ impl Extrusion { } impl SolidLike for Extrusion { - fn references(&self) -> Vec { + fn references(&self) -> Vec>> { // self.faces.iter().map(|f| FeatureCell::Face(f.clone())).collect() todo!("Extrusion::references") } @@ -93,7 +92,7 @@ impl SolidLike for Extrusion { Ok(self.faces .iter() .map(|f| { - let wires = get_isoface_wires(self.sketch.clone(), f).unwrap(); + let wires = get_isoface_wires(self.sketch.clone(), &f).unwrap(); let face = builder::try_attach_plane(&wires).unwrap(); // Can we calculate ALL the wires at once and not iter-sweep? @@ -105,11 +104,25 @@ impl SolidLike for Extrusion { } } +impl<'a> TryFrom<&'a mut Feature> for &'a mut Extrusion { + type Error = anyhow::Error; + + // The Feature enum has only 1 variant for now but that will change soon + #[allow(irrefutable_let_patterns)] + fn try_from(value: &'a mut Feature) -> Result { + let Feature::Extrusion(ref mut extrusion) = value else { + return Err(anyhow::anyhow!("Failed to convert Feature to Extrusion")) + }; + + Ok(extrusion) + } +} + #[derive(Tsify, Debug, Clone, Serialize, Deserialize)] #[tsify(from_wasm_abi, into_wasm_abi)] pub struct Add { pub sketch_id: IDType, - pub faces: Vec, // TODO: This should be a list of face IDs + pub faces: Vec, pub length: f64, pub offset: f64, pub direction: Direction, @@ -124,7 +137,7 @@ impl MessageHandler for Add { let sketch = workbench.get_sketch_by_id(self.sketch_id)?; let extrusion = Extrusion::new( - self.faces.clone(), + vec![], sketch.clone(), self.length, self.offset, @@ -132,13 +145,78 @@ impl MessageHandler for Add { self.mode.clone(), ); - // TODO: This is incorrect. We should adding Features to the workbench, not solids - // Until then we can't update or remove as we don't know which solids are associated with this extrusion - extrusion.to_solids()?.iter().for_each(|solid| { - let id = workbench.solids_next_id; - workbench.solids.insert(id, Rc::new(RefCell::new(solid.clone()))); - workbench.solids_next_id += 1; - }); + let id = workbench.features_next_id; + workbench.features.insert(id, Rc::new(RefCell::new(extrusion.to_feature()))); + workbench.features_next_id += 1; + let id = workbench.features_next_id - 1; + drop(workbench); + + // We can't keep the workbench borrow during the UpdateFaces + // as it also needs a mutable borrow of the workbench + UpdateFaces { + extrusion_id: id, + sketch_id: self.sketch_id, + faces: self.faces.clone(), + }.handle_message(workbench_ref.clone())?; + + Ok(Some(id)) + } +} + +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] +#[tsify(from_wasm_abi, into_wasm_abi)] +pub struct UpdateFaces { + pub extrusion_id: IDType, + pub sketch_id: IDType, + pub faces: Vec, +} + +impl MessageHandler for UpdateFaces { + // Parent to workbench to add to solids and be able to reference the sketch + type Parent = Rc>; + fn handle_message(&self, workbench_ref: Self::Parent) -> anyhow::Result> { + let workbench = workbench_ref.borrow_mut(); + let sketch = workbench.get_sketch_by_id(self.sketch_id)?; + let feature_ref = workbench.features.get(&self.extrusion_id).ok_or(anyhow::anyhow!("No feature with ID {} was found", self.extrusion_id))?; + let mut extrusion: RefMut<'_, Extrusion> = RefMut::map(feature_ref.borrow_mut(), |f| f.try_into().unwrap()); + + let faces = sketch.borrow() + .sketch().borrow() + .get_faces() + .iter() + .enumerate() + .filter_map(|(id, f)| if self.faces.contains(&(id as IDType)) { + Some(f.clone()) + } else { + None + }) + .collect_vec(); + + extrusion.faces = faces; + + Ok(None) + } +} + +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] +#[tsify(from_wasm_abi, into_wasm_abi)] +pub struct UpdateForm { + pub length: f64, + pub offset: f64, + pub direction: Direction, + pub mode: Mode, +} + +impl MessageHandler for UpdateForm { + // Parent to workbench to add to solids and be able to reference the sketch + type Parent = Rc>; + fn handle_message(&self, feature_ref: Self::Parent) -> anyhow::Result> { + let mut extrusion: RefMut<'_, Extrusion> = RefMut::map(feature_ref.borrow_mut(), |f| f.try_into().unwrap()); + + extrusion.length = self.length; + extrusion.offset = self.offset; + extrusion.direction = self.direction.clone(); + extrusion.mode = self.mode.clone(); Ok(None) } @@ -175,7 +253,7 @@ mod tests { // get a realization let workbench_ref = p.get_workbench_by_id(0).unwrap(); let workbench = workbench_ref.borrow(); - let solids = &workbench.solids; + let solids = &workbench.features; println!("[{}] solids: {:?}", file, solids.len()); assert_eq!(solids.len(), *expected_solids); // doesn't work yet! @@ -187,7 +265,8 @@ mod tests { let p = create_test_project(); let workbench_ref = p.get_workbench_by_id(0).unwrap(); let workbench = workbench_ref.borrow(); - let solid = workbench.solids.get(&0).unwrap().borrow(); + let feature = workbench.features.get(&0).unwrap().borrow(); + let solid = &feature.as_solid_like().to_solids().unwrap()[0]; solid.save_as_step("pkg/test.step"); solid.save_as_obj("pkg/test.obj", 0.001); diff --git a/packages/cadmium/src/solid/helpers.rs b/packages/cadmium/src/feature/helpers.rs similarity index 100% rename from packages/cadmium/src/solid/helpers.rs rename to packages/cadmium/src/feature/helpers.rs diff --git a/packages/cadmium/src/feature/mod.rs b/packages/cadmium/src/feature/mod.rs new file mode 100644 index 00000000..fab68b05 --- /dev/null +++ b/packages/cadmium/src/feature/mod.rs @@ -0,0 +1,57 @@ +use std::cell::RefCell; +use std::fmt::Debug; +use std::rc::Rc; + +use serde::Deserialize; +use serde::Serialize; +use tsify_next::Tsify; + +use crate::message::Identifiable; +use crate::workbench::Workbench; +use crate::IDType; + +pub mod extrusion; +pub mod helpers; +pub mod point; +pub mod prelude; +pub mod solid; + +use prelude::*; + +pub trait SolidLike: Debug { + fn references(&self) -> Vec>>; + fn get_truck_solids(&self) -> anyhow::Result>; + fn to_feature(&self) -> Feature; + + fn to_solids(&self) -> anyhow::Result> { + let truck_solids = self.get_truck_solids()?; + + Ok(truck_solids.iter().map(|truck_solid| { + Solid::from_truck_solid("".to_owned(), truck_solid.clone()) + }).collect()) + } +} + +#[derive(Tsify, Debug, Serialize, Deserialize, Clone)] +#[tsify(into_wasm_abi, from_wasm_abi)] +#[non_exhaustive] +pub enum Feature { + Extrusion(extrusion::Extrusion), +} + +impl Feature { + pub fn as_solid_like(&self) -> &dyn SolidLike { + match self { + Feature::Extrusion(extrusion) => extrusion, + } + } +} + +impl Identifiable for Rc> { + type Parent = Rc>; + const ID_NAME: &'static str = "feature_id"; + + fn from_parent_id(parent: &Self::Parent, id: IDType) -> anyhow::Result { + Ok(parent.borrow().features.get(&id).ok_or(anyhow::anyhow!("No feature with ID {} was found", id))?.clone()) + } +} diff --git a/packages/cadmium/src/solid/point.rs b/packages/cadmium/src/feature/point.rs similarity index 100% rename from packages/cadmium/src/solid/point.rs rename to packages/cadmium/src/feature/point.rs diff --git a/packages/cadmium/src/solid/prelude.rs b/packages/cadmium/src/feature/prelude.rs similarity index 92% rename from packages/cadmium/src/solid/prelude.rs rename to packages/cadmium/src/feature/prelude.rs index e7e9c058..07208943 100644 --- a/packages/cadmium/src/solid/prelude.rs +++ b/packages/cadmium/src/feature/prelude.rs @@ -1,3 +1,8 @@ +pub use super::helpers::*; +pub use super::solid::Solid; + +pub const MESH_TOLERANCE: f64 = 0.1; + pub use isotope::decompose::face::Face as ISOFace; pub use truck_modeling::Face as TruckFace; @@ -20,5 +25,3 @@ pub type TruckClosedSolid = TruckTopoSolid< truck_modeling::Curve, truck_modeling::Surface, >; - -pub use super::helpers::*; diff --git a/packages/cadmium/src/solid/mod.rs b/packages/cadmium/src/feature/solid.rs similarity index 74% rename from packages/cadmium/src/solid/mod.rs rename to packages/cadmium/src/feature/solid.rs index 6cd53025..6ec92f7c 100644 --- a/packages/cadmium/src/solid/mod.rs +++ b/packages/cadmium/src/feature/solid.rs @@ -1,8 +1,4 @@ -use std::cell::Ref; -use std::cell::RefCell; -use std::cell::RefMut; use std::fmt::Debug; -use std::rc::Rc; use serde::{Deserialize, Serialize}; use tsify_next::Tsify; @@ -16,74 +12,7 @@ use truck_stepio::out; use crate::archetypes::Vector2; use crate::archetypes::Vector3; -pub mod extrusion; -pub mod helpers; -pub mod point; -pub mod prelude; - -use prelude::*; - -const MESH_TOLERANCE: f64 = 0.1; - -pub trait SolidLike: Debug { - fn references(&self) -> Vec; - fn get_truck_solids(&self) -> anyhow::Result>; - fn to_feature(&self) -> Feature; - - fn to_solids(&self) -> anyhow::Result> { - let truck_solids = self.get_truck_solids()?; - - Ok(truck_solids.iter().map(|truck_solid| { - Solid::from_truck_solid("".to_owned(), truck_solid.clone()) - }).collect()) - } -} - -#[derive(Tsify, Debug, Serialize, Deserialize, Clone)] -#[tsify(into_wasm_abi, from_wasm_abi)] -pub enum Feature { - Extrusion(extrusion::Extrusion), -} - -impl Feature { - pub fn as_solid_like(&self) -> &dyn SolidLike { - match self { - Feature::Extrusion(extrusion) => extrusion, - } - } -} - -#[derive(Tsify, Debug, Serialize, Deserialize, Clone)] -#[tsify(into_wasm_abi, from_wasm_abi)] -pub enum FeatureCell { - Extrusion(Rc>), -} - -impl FeatureCell { - pub fn borrow(&self) -> Ref { - match self { - FeatureCell::Extrusion(e) => e.borrow(), - } - } - - pub fn borrow_mut(&self) -> RefMut { - match self { - FeatureCell::Extrusion(e) => e.borrow_mut(), - } - } - - pub fn as_ptr(&self) -> *const dyn SolidLike { - match self { - FeatureCell::Extrusion(e) => e.as_ptr(), - } - } -} - -impl PartialEq for FeatureCell { - fn eq(&self, other: &Self) -> bool { - std::ptr::eq(self.as_ptr(), other.as_ptr()) - } -} +use super::prelude::*; #[derive(Tsify, Debug, Serialize, Deserialize, Clone)] #[tsify(into_wasm_abi, from_wasm_abi)] diff --git a/packages/cadmium/src/isketch/compound.rs b/packages/cadmium/src/isketch/compound.rs new file mode 100644 index 00000000..54b29ce5 --- /dev/null +++ b/packages/cadmium/src/isketch/compound.rs @@ -0,0 +1,71 @@ +use std::cell::RefCell; +use std::fmt::Debug; +use std::rc::Rc; + +use isotope::primitives::PrimitiveCell; +use serde::{Deserialize, Serialize}; +use tsify_next::Tsify; + +use crate::message::{Identifiable, MessageHandler}; +use crate::IDType; + +use super::{compound_rectangle, ISketch}; + +pub trait CompoundLike: Debug { + fn references(&self) -> Vec; + fn created_references(&self) -> Vec; + fn populate_created_references(&self, sketch: &mut isotope::sketch::Sketch) -> anyhow::Result<()> { + for reference in self.created_references() { + sketch.add_primitive(reference)?; + } + Ok(()) + } +} + +#[derive(Tsify, Debug, Serialize, Deserialize, Clone)] +#[tsify(into_wasm_abi, from_wasm_abi)] +#[non_exhaustive] +pub enum Compound { + Rectangle(compound_rectangle::Rectangle), +} + +impl Identifiable for Rc> { + type Parent = Rc>; + const ID_NAME: &'static str = "compound_id"; + + fn from_parent_id(parent: &Self::Parent, id: IDType) -> anyhow::Result { + Ok(parent.borrow().compounds.get(&id).ok_or(anyhow::anyhow!("No feature with ID {} was found", id))?.clone()) + } +} + +impl Compound { + pub fn as_compound_like(&self) -> &dyn CompoundLike { + match self { + Compound::Rectangle(rectangle) => rectangle, + } + } +} + +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] +#[tsify(from_wasm_abi, into_wasm_abi)] +pub struct DeleteCompound { + id: IDType, +} + +impl MessageHandler for DeleteCompound { + type Parent = Rc>; + fn handle_message(&self, sketch_ref: Rc>) -> anyhow::Result> { + let mut isketch = sketch_ref.borrow_mut(); + let mut sketch = isketch.sketch.borrow_mut(); + let compound = isketch.compounds.get(&self.id).ok_or(anyhow::anyhow!("No compound with ID {} was found", self.id))?; + + for reference in compound.borrow().as_compound_like().created_references() { + let id = sketch.get_primitive_id(&reference).ok_or(anyhow::anyhow!("Failed to find primitive with reference {:?}", reference))?; + sketch.delete_primitive(id)?; + } + drop(sketch); + + isketch.compounds.remove(&self.id); + Ok(None) + } +} diff --git a/packages/cadmium/src/isketch/compound_rectangle.rs b/packages/cadmium/src/isketch/compound_rectangle.rs new file mode 100644 index 00000000..e550b320 --- /dev/null +++ b/packages/cadmium/src/isketch/compound_rectangle.rs @@ -0,0 +1,100 @@ +use std::cell::RefCell; +use std::rc::Rc; + +use isotope::primitives::line::Line; +use isotope::primitives::point2::Point2; +use isotope::primitives::PrimitiveCell; +use serde::{Deserialize, Serialize}; +use tsify_next::Tsify; + +use crate::message::MessageHandler; +use crate::IDType; + +use super::compound::{Compound, CompoundLike}; +use super::ISketch; + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct Rectangle { + start: Rc>, + end: Rc>, + new_points: [Rc>; 2], + new_lines: [Rc>; 4], +} + +impl Rectangle { + pub fn new(start: Rc>, end: Rc>) -> Self { + let start_point = start.borrow().clone(); + let end_point = end.borrow().clone(); + + let other_start = Rc::new(RefCell::new(Point2::new(start_point.x(), end_point.y()))); + let other_end = Rc::new(RefCell::new(Point2::new(end_point.x(), start_point.y()))); + + let new_lines = [ + Rc::new(RefCell::new(Line::new(start.clone(), other_start.clone()))), + Rc::new(RefCell::new(Line::new(other_start.clone(), end.clone()))), + Rc::new(RefCell::new(Line::new(end.clone(), other_end.clone()))), + Rc::new(RefCell::new(Line::new(other_end.clone(), start.clone()))), + ]; + Self { + start, + end, + new_points: [other_start, other_end], + new_lines, + } + } + +} + +impl CompoundLike for Rectangle { + fn references(&self) -> Vec { + vec![ + PrimitiveCell::Point2(self.start.clone()), + PrimitiveCell::Point2(self.end.clone()), + ] + } + + fn created_references(&self) -> Vec { + vec![ + PrimitiveCell::Point2(self.new_points[0].clone()), + PrimitiveCell::Point2(self.new_points[1].clone()), + PrimitiveCell::Line(self.new_lines[0].clone()), + PrimitiveCell::Line(self.new_lines[1].clone()), + PrimitiveCell::Line(self.new_lines[2].clone()), + PrimitiveCell::Line(self.new_lines[3].clone()), + ] + } +} + +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] +#[tsify(from_wasm_abi, into_wasm_abi)] +pub struct Add { + pub start: IDType, + pub end: IDType, +} + +impl MessageHandler for Add { + type Parent = Rc>; + fn handle_message(&self, sketch_ref: Rc>) -> anyhow::Result> { + let mut isketch = sketch_ref.borrow_mut(); + let mut sketch = isketch.sketch.borrow_mut(); + + let start_point = if let PrimitiveCell::Point2(point) = sketch.get_primitive_by_id(self.start).unwrap() { + point + } else { + return Err(anyhow::anyhow!("Start point is not a point")); + }; + let end_point = if let PrimitiveCell::Point2(point) = sketch.get_primitive_by_id(self.end).unwrap() { + point + } else { + return Err(anyhow::anyhow!("End point is not a point")); + }; + + let rectangle = Rectangle::new(start_point.clone(), end_point.clone()); + rectangle.populate_created_references(&mut sketch)?; + drop(sketch); + + let point_id = isketch.compounds_next_id; + isketch.compounds.insert(point_id, Rc::new(RefCell::new(Compound::Rectangle(rectangle)))); + isketch.compounds_next_id += 1; + Ok(Some(point_id))} +} diff --git a/packages/cadmium/src/isketch/mod.rs b/packages/cadmium/src/isketch/mod.rs new file mode 100644 index 00000000..a9d7f15b --- /dev/null +++ b/packages/cadmium/src/isketch/mod.rs @@ -0,0 +1,116 @@ +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::rc::Rc; + +use isotope::decompose::face::Face; +use isotope::primitives::point2::Point2 as ISOPoint2; +use isotope::primitives::PrimitiveCell; +use isotope::sketch::Sketch; +use serde::{Deserialize, Serialize}; +use tsify_next::Tsify; + + +use crate::IDType; +use crate::archetypes::{Plane, PlaneDescription}; +use crate::error::CADmiumError; +use crate::feature::point::Point3; +use crate::message::Identifiable; +use crate::workbench::Workbench; + +pub mod compound; +pub mod compound_rectangle; +pub mod primitive; + +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] +#[tsify(into_wasm_abi, from_wasm_abi)] +pub struct ISketch { + // TODO: Make it private with a setter + pub plane: Rc>, + + sketch: Rc>, + compounds: BTreeMap>>, + compounds_next_id: u64, + points_3d: BTreeMap, +} + +impl ISketch { + pub fn new(plane: Rc>) -> Self { + // The key difference between Sketch and RealSketch is that Sketch lives + // in 2D and RealSketch lives in 3D. So we need to convert the points + + let mut real_sketch = Self { + plane: plane.clone(), + points_3d: BTreeMap::new(), + compounds: BTreeMap::new(), + compounds_next_id: 0, + sketch: Rc::new(RefCell::new(Sketch::new())), + }; + + for (id, point) in real_sketch.sketch.borrow().get_all_points().iter() { + real_sketch.points_3d.insert(*id, Point3::from_plane_point(&plane.borrow().clone(), point)); + } + + real_sketch + } + + pub fn try_from_plane_description(wb: &Workbench, plane_description: &PlaneDescription) -> anyhow::Result { + let plane = match plane_description { + PlaneDescription::PlaneId(plane_id) => + wb.planes.get(plane_id).ok_or(anyhow::anyhow!("Failed to find plane with id {}", plane_id))?, + PlaneDescription::SolidFace { solid_id: _, normal: _ } => todo!("Implement SolidFace"), + }.clone(); + Ok(Self::new(plane)) + } + + /// Helper function to go from an isotope point2D to a point_3D, as calculated during new + pub fn get_point_3d(&self, point: Rc>) -> Result<(u64, Point3), CADmiumError> { + let cell = PrimitiveCell::Point2(point.clone()); + let point_id = self.sketch.borrow().get_primitive_id(&cell).unwrap(); + + if let Some(result) = self.points_3d.get(&point_id) { + Ok((point_id, result.clone())) + } else { + // TODO: While I'd like to calculate and add the point_3d here, we'll pollute everything with mut + // let point_3d = Point3::from_plane_point(&self.plane.borrow(), &point.borrow()); + + // Ok((point_id, + // self.points_3d + // .insert(point_id, point_3d) + // .ok_or(CADmiumError::Point3DCalculationFailed)?)) + Err(CADmiumError::Point3DCalculationFailed) + } + } + + pub fn sketch(&self) -> Rc> { + self.sketch.clone() + } + + pub fn faces(&self) -> Vec { + // TODO: How do we keep track of faces vs IDs? + self.sketch.borrow().get_merged_faces() + } + + pub fn find_point_ref(&self, x: f64, y: f64) -> Option>> { + self.sketch.borrow().primitives().iter().find_map(|(_, prim)| { + if let PrimitiveCell::Point2(point_ref) = prim { + let point = point_ref.borrow(); + if (point.x() - x).abs() < 0.0001 && (point.y() - y).abs() < 0.0001 { + Some(point_ref.clone()) + } else { + None + } + } else { + None + } + }) + } +} + +impl Identifiable for Rc> { + type Parent = Rc>; + const ID_NAME: &'static str = "sketch_id"; + + fn from_parent_id(parent: &Self::Parent, id: IDType) -> anyhow::Result { + Ok(parent.borrow().sketches.get(&id).ok_or(anyhow::anyhow!(""))?.clone()) + } +} diff --git a/packages/cadmium/src/isketch.rs b/packages/cadmium/src/isketch/primitive.rs similarity index 52% rename from packages/cadmium/src/isketch.rs rename to packages/cadmium/src/isketch/primitive.rs index cfd0d979..93ba086d 100644 --- a/packages/cadmium/src/isketch.rs +++ b/packages/cadmium/src/isketch/primitive.rs @@ -1,126 +1,17 @@ use std::cell::RefCell; -use std::collections::BTreeMap; use std::rc::Rc; -use isotope::decompose::face::Face; use isotope::primitives::line::Line; use isotope::primitives::point2::Point2 as ISOPoint2; use isotope::primitives::PrimitiveCell; -use isotope::sketch::Sketch; use serde::{Deserialize, Serialize}; use tsify_next::Tsify; -use crate::archetypes::{Plane, PlaneDescription}; -use crate::error::CADmiumError; -use crate::solid::point::Point3; +use crate::message::MessageHandler; use crate::IDType; +use crate::feature::point::Point3; -#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] -#[tsify(into_wasm_abi, from_wasm_abi)] -pub struct IPlane { - // TODO: Should hold its own ID - // pub id: String, - pub plane: Plane, - pub name: String, - pub width: f64, - pub height: f64, -} - -#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] -#[tsify(into_wasm_abi, from_wasm_abi)] -pub struct ISketch { - // TODO: Make it private with a setter - pub plane: Rc>, - - sketch: Rc>, - points_3d: BTreeMap, -} - -impl ISketch { - // TODO: Maybe pass the plane as refcell? - pub fn new(plane: Rc>) -> Self { - // The key difference between Sketch and RealSketch is that Sketch lives - // in 2D and RealSketch lives in 3D. So we need to convert the points - - let mut real_sketch = Self { - plane: plane.clone(), - points_3d: BTreeMap::new(), - // primitives: sketch.borrow().primitives().iter().map(|(id, prim)| (*id, prim.borrow().to_primitive())).collect(), - // constraints: sketch.borrow().constraints().iter().map(|c| c.borrow().get_type()).collect(), - sketch: Rc::new(RefCell::new(Sketch::new())), - }; - - for (id, point) in real_sketch.sketch.borrow().get_all_points().iter() { - real_sketch.points_3d.insert(*id, Point3::from_plane_point(&plane.borrow().clone(), point)); - } - - real_sketch - } - - pub fn try_from_plane_description(wb: &Workbench, plane_description: &PlaneDescription) -> anyhow::Result { - let plane = match plane_description { - PlaneDescription::PlaneId(plane_id) => - wb.planes.get(plane_id).ok_or(anyhow::anyhow!("Failed to find plane with id {}", plane_id))?, - PlaneDescription::SolidFace { solid_id: _, normal: _ } => todo!("Implement SolidFace"), - }.clone(); - Ok(Self::new(plane)) - } - - /// Helper function to go from an isotope point2D to a point_3D, as calculated during new - pub fn get_point_3d(&self, point: Rc>) -> Result<(u64, Point3), CADmiumError> { - let cell = PrimitiveCell::Point2(point.clone()); - let point_id = self.sketch.borrow().get_primitive_id(&cell).unwrap(); - - if let Some(result) = self.points_3d.get(&point_id) { - Ok((point_id, result.clone())) - } else { - // TODO: While I'd like to calculate and add the point_3d here, we'll pollute everything with mut - // let point_3d = Point3::from_plane_point(&self.plane.borrow(), &point.borrow()); - - // Ok((point_id, - // self.points_3d - // .insert(point_id, point_3d) - // .ok_or(CADmiumError::Point3DCalculationFailed)?)) - Err(CADmiumError::Point3DCalculationFailed) - } - } - - pub fn sketch(&self) -> Rc> { - self.sketch.clone() - } - - pub fn faces(&self) -> Vec { - // TODO: How do we keep track of faces vs IDs? - self.sketch.borrow().get_merged_faces() - } - - pub fn find_point_ref(&self, x: f64, y: f64) -> Option>> { - self.sketch.borrow().primitives().iter().find_map(|(_, prim)| { - if let PrimitiveCell::Point2(point_ref) = prim { - let point = point_ref.borrow(); - if (point.x() - x).abs() < 0.0001 && (point.y() - y).abs() < 0.0001 { - Some(point_ref.clone()) - } else { - None - } - } else { - None - } - }) - } -} - -use crate::message::{Identifiable, MessageHandler}; -use crate::workbench::Workbench; - -impl Identifiable for Rc> { - type Parent = Rc>; - const ID_NAME: &'static str = "sketch_id"; - - fn from_parent_id(parent: &Self::Parent, id: IDType) -> anyhow::Result { - Ok(parent.borrow().sketches.get(&id).ok_or(anyhow::anyhow!(""))?.clone()) - } -} +use super::ISketch; #[derive(Tsify, Debug, Clone, Serialize, Deserialize)] #[tsify(from_wasm_abi, into_wasm_abi)] diff --git a/packages/cadmium/src/lib.rs b/packages/cadmium/src/lib.rs index 8e7517fd..c4843fdf 100644 --- a/packages/cadmium/src/lib.rs +++ b/packages/cadmium/src/lib.rs @@ -9,7 +9,7 @@ pub mod error; pub mod isketch; pub mod message; pub mod project; -pub mod solid; +pub mod feature; #[macro_use] pub mod step; pub mod workbench; diff --git a/packages/cadmium/src/main.rs b/packages/cadmium/src/main.rs index 6eb890e2..247080ed 100644 --- a/packages/cadmium/src/main.rs +++ b/packages/cadmium/src/main.rs @@ -2,7 +2,7 @@ use std::ops::{Sub, SubAssign}; -use cadmium::solid::helpers::fuse; +use cadmium::feature::helpers::fuse; use truck_meshalgo::filters::OptimizingFilter; use truck_meshalgo::tessellation::{MeshableShape, MeshedShape}; use truck_modeling::builder::{translated, tsweep, vertex}; diff --git a/packages/cadmium/src/message/idwrap.rs b/packages/cadmium/src/message/idwrap.rs deleted file mode 100644 index c3d275d1..00000000 --- a/packages/cadmium/src/message/idwrap.rs +++ /dev/null @@ -1,159 +0,0 @@ -use std::fmt; - -use serde::de::{self, MapAccess, Visitor}; -use serde::ser::SerializeMap; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use tsify_next::Tsify; - -use crate::IDType; - -use super::{Identifiable, MessageHandler, ProjectMessageHandler}; - -#[derive(Tsify, Debug, Clone)] -#[tsify(from_wasm_abi)] -pub struct IDWrap Deserialize<'de> + wasm_bindgen::convert::RefFromWasmAbi> { - pub id: u64, - pub inner: T, -} - -impl Deserialize<'de> + wasm_bindgen::convert::RefFromWasmAbi> IDWrap { - pub fn new(id: IDType, h: T) -> Self { - Self { - id, - inner: h, - } - } - - pub fn id(&self) -> IDType { - self.id - } - - pub fn inner(&self) -> &T { - &self.inner - } -} - -// First level message handler -impl ProjectMessageHandler for IDWrap -where - T: MessageHandler + Serialize + for<'de> Deserialize<'de> + wasm_bindgen::convert::RefFromWasmAbi, - U: Identifiable, -{ - fn handle_project_message(&self, project: &mut crate::project::Project) -> anyhow::Result> { - let prnt = U::from_parent_id(project, self.id)?; - self.inner.handle_message(prnt) - } -} - -// Second level message handler -impl MessageHandler for IDWrap -where - T: MessageHandler + Serialize + for<'de> Deserialize<'de> + wasm_bindgen::convert::RefFromWasmAbi, - C: Identifiable, - P: Identifiable, -{ - type Parent = C::Parent; - fn handle_message(&self, parent: Self::Parent) -> anyhow::Result> { - let prnt = C::from_parent_id(&parent, self.id)?; - self.inner.handle_message(prnt) - } -} - -impl<'de, T, C> Deserialize<'de> for IDWrap -where - T: MessageHandler + Serialize + for<'dh> Deserialize<'dh> + wasm_bindgen::convert::RefFromWasmAbi, - C: Identifiable, -{ - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct IDWrapVisitor { - marker: std::marker::PhantomData T>, - } - - impl IDWrapVisitor { - fn new() -> Self { - IDWrapVisitor { - marker: std::marker::PhantomData, - } - } - } - - // Implementation of Visitor trait for IDWrapVisitor - impl<'de, T, C> Visitor<'de> for IDWrapVisitor> - where - T: MessageHandler + Serialize + for<'dh> Deserialize<'dh> + wasm_bindgen::convert::RefFromWasmAbi, - C: Identifiable, - { - type Value = IDWrap; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str(format!("a map with {}", C::ID_NAME).as_str()) - } - - fn visit_map(self, mut map: V) -> Result - where - V: MapAccess<'de>, - { - let mut parent_id = None; - let mut inner_map = serde_json::Map::new(); - - - // Loop through the map and extract fields - while let Some(key) = map.next_key::()? { - println!("Key: {:?}", key); - - if key == C::ID_NAME { - if parent_id.is_some() { - return Err(de::Error::duplicate_field("parent_id")); - } - parent_id = Some(map.next_value()?); - } else { - // Collect the rest of the map entries for inner deserialization - let value: serde_json::Value = map.next_value()?; - inner_map.insert(key, value); - } - } - - let id = parent_id.ok_or_else(|| de::Error::missing_field(C::ID_NAME))?; - let inner_value = serde_json::Value::Object(inner_map); - let inner = T::deserialize(inner_value).map_err(de::Error::custom)?; - - // Construct the nested IDWrap structure - Ok(IDWrap { - id, - inner, - }) - } - } - - deserializer.deserialize_map(IDWrapVisitor::new()) - } -} - -impl Serialize for IDWrap -where - T: MessageHandler + Serialize + for<'de> Deserialize<'de> + wasm_bindgen::convert::RefFromWasmAbi, - C: Identifiable, -{ - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - // Create a serializer map with the appropriate capacity - let mut map = serializer.serialize_map(Some(1))?; - // Add the id field using the name from the Identifiable trait - map.serialize_entry(C::ID_NAME, &self.id)?; - // Add the inner object fields - serde_json::to_value(&self.inner) - .map_err(serde::ser::Error::custom)? - .as_object() - .ok_or_else(|| serde::ser::Error::custom("Expected object"))? - .iter().try_for_each(|(k, v)| { - map.serialize_entry(k, v)?; - Ok(()) - })?; - map.end() - } -} diff --git a/packages/cadmium/src/message/idwrap/de.rs b/packages/cadmium/src/message/idwrap/de.rs new file mode 100644 index 00000000..36cf6d08 --- /dev/null +++ b/packages/cadmium/src/message/idwrap/de.rs @@ -0,0 +1,81 @@ +use std::fmt; + +use serde::de::{self, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; + +use crate::message::{Identifiable, MessageHandler}; + +use super::IDWrap; + +impl<'de, T, C> Deserialize<'de> for IDWrap +where + T: MessageHandler + Clone + Serialize + for<'dh> Deserialize<'dh> + wasm_bindgen::convert::RefFromWasmAbi, + C: Identifiable, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct IDWrapVisitor { + marker: std::marker::PhantomData T>, + } + + impl IDWrapVisitor { + fn new() -> Self { + IDWrapVisitor { + marker: std::marker::PhantomData, + } + } + } + + // Implementation of Visitor trait for IDWrapVisitor + impl<'de, T, C> Visitor<'de> for IDWrapVisitor> + where + T: MessageHandler + Clone + Serialize + for<'dh> Deserialize<'dh> + wasm_bindgen::convert::RefFromWasmAbi, + C: Identifiable, + { + type Value = IDWrap; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(format!("a map with {}", C::ID_NAME).as_str()) + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut parent_id = None; + let mut inner_map = serde_json::Map::new(); + + + // Loop through the map and extract fields + while let Some(key) = map.next_key::()? { + println!("Key: {:?}", key); + + if key == C::ID_NAME { + if parent_id.is_some() { + return Err(de::Error::duplicate_field("parent_id")); + } + parent_id = Some(map.next_value()?); + } else { + // Collect the rest of the map entries for inner deserialization + let value: serde_json::Value = map.next_value()?; + inner_map.insert(key, value); + } + } + + let id = parent_id.ok_or_else(|| de::Error::missing_field(C::ID_NAME))?; + let inner_value = serde_json::Value::Object(inner_map); + let inner = T::deserialize(inner_value).map_err(de::Error::custom)?; + + // Construct the nested IDWrap structure + Ok(IDWrap { + id, + inner, + }) + } + } + + deserializer.deserialize_map(IDWrapVisitor::new()) + } +} diff --git a/packages/cadmium/src/message/idwrap/mod.rs b/packages/cadmium/src/message/idwrap/mod.rs new file mode 100644 index 00000000..51b82a4f --- /dev/null +++ b/packages/cadmium/src/message/idwrap/mod.rs @@ -0,0 +1,67 @@ +use std::cell::RefCell; +use std::rc::Rc; + +use serde::{Deserialize, Serialize}; +use tsify_next::Tsify; + +use crate::workbench::Workbench; +use crate::IDType; + +mod de; +mod ser; + +use super::{Identifiable, MessageHandler, ProjectMessageHandler}; + +#[derive(Tsify, Debug, Clone)] +#[tsify(from_wasm_abi)] +pub struct IDWrap Deserialize<'de> + wasm_bindgen::convert::RefFromWasmAbi> { + pub id: u64, + pub inner: T, +} + +impl Deserialize<'de> + wasm_bindgen::convert::RefFromWasmAbi> IDWrap { + pub fn new(id: IDType, h: T) -> Self { + Self { + id, + inner: h, + } + } + + pub fn id(&self) -> IDType { + self.id + } + + pub fn inner(&self) -> &T { + &self.inner + } +} + +// First level message handler +impl<'a, T> ProjectMessageHandler for IDWrap +where + T: MessageHandler>> + Clone + Serialize + for<'de> Deserialize<'de> + wasm_bindgen::convert::RefFromWasmAbi, + crate::message::message::Message: From +{ + fn handle_project_message(&self, project: &mut crate::project::Project) -> anyhow::Result> { + let wb = T::Parent::from_parent_id(project, self.id)?; + let result = self.inner.handle_message(wb.clone())?; + + wb.borrow_mut().add_message_step(&self.clone().into()); + + Ok(result) + } +} + +// Second level message handler +impl MessageHandler for IDWrap +where + T: MessageHandler + Clone + Serialize + for<'de> Deserialize<'de> + wasm_bindgen::convert::RefFromWasmAbi, + C: Identifiable, + P: Identifiable, +{ + type Parent = C::Parent; + fn handle_message(&self, parent: Self::Parent) -> anyhow::Result> { + let msg_parent = C::from_parent_id(&parent, self.id)?; + self.inner.handle_message(msg_parent) + } +} diff --git a/packages/cadmium/src/message/idwrap/ser.rs b/packages/cadmium/src/message/idwrap/ser.rs new file mode 100644 index 00000000..4092bcb4 --- /dev/null +++ b/packages/cadmium/src/message/idwrap/ser.rs @@ -0,0 +1,33 @@ +use serde::ser::SerializeMap as _; +use serde::{Deserialize, Serialize, Serializer}; + +use crate::message::{Identifiable, MessageHandler}; + +use super::IDWrap; + + +impl Serialize for IDWrap +where + T: MessageHandler + Clone + Serialize + for<'de> Deserialize<'de> + wasm_bindgen::convert::RefFromWasmAbi, + C: Identifiable, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + // Create a serializer map with the appropriate capacity + let mut map = serializer.serialize_map(Some(1))?; + // Add the id field using the name from the Identifiable trait + map.serialize_entry(C::ID_NAME, &self.id)?; + // Add the inner object fields + serde_json::to_value(&self.inner) + .map_err(serde::ser::Error::custom)? + .as_object() + .ok_or_else(|| serde::ser::Error::custom("Expected object"))? + .iter().try_for_each(|(k, v)| { + map.serialize_entry(k, v)?; + Ok(()) + })?; + map.end() + } +} diff --git a/packages/cadmium/src/message/message.rs b/packages/cadmium/src/message/message.rs index e201b0bf..de5690de 100644 --- a/packages/cadmium/src/message/message.rs +++ b/packages/cadmium/src/message/message.rs @@ -15,15 +15,23 @@ pub enum Message { WorkbenchPointAdd(IDWrap), WorkbenchPlaneAdd(IDWrap), WorkbenchSketchAdd(IDWrap), - WorkbenchPointUpdate(IDWrap>), + WorkbenchSketchSetPlane(IDWrap), + WorkbenchPointUpdate(IDWrap>), - SketchAddPoint(IDWrap>), - SketchAddArc(IDWrap>), - SketchAddCircle(IDWrap>), - SketchAddLine(IDWrap>), - SketchDeletePrimitive(IDWrap>), + SketchAddPoint(IDWrap>), + SketchAddArc(IDWrap>), + SketchAddCircle(IDWrap>), + SketchAddLine(IDWrap>), + SketchAddRectangle(IDWrap>), + SketchDeleteCompound(IDWrap>), + SketchDeletePrimitive(IDWrap>), - SolidExtrusionAdd(IDWrap), + FeatureExtrusionAdd(IDWrap), + FeatureExtrusionUpdateFaces(IDWrap), + FeatureExtrusionUpdateForm(IDWrap>), + + StepRename(IDWrap>), + StepDelete(IDWrap), } #[derive(Tsify, Debug, Serialize, Deserialize)] diff --git a/packages/cadmium/src/project.rs b/packages/cadmium/src/project.rs index 3cfa709b..9226d3f3 100644 --- a/packages/cadmium/src/project.rs +++ b/packages/cadmium/src/project.rs @@ -101,38 +101,50 @@ impl ProjectMessageHandler for ProjectRename { pub mod tests { use crate::archetypes::PlaneDescription; - - use crate::isketch::AddLine; - use crate::isketch::AddPoint; + + use crate::isketch::primitive::{AddLine, AddPoint}; + use crate::message::idwrap::IDWrap; use crate::message::MessageHandler; - use crate::solid::extrusion; - use crate::solid::extrusion::Direction; - use crate::solid::extrusion::Mode; - use crate::workbench::AddSketch; + use crate::feature::extrusion; + use crate::feature::extrusion::{Direction, Mode}; + use crate::step; + use crate::workbench::{AddSketch, SetSketchPlane}; + use crate::IDType; use super::*; pub fn create_test_project() -> Project { - let p = Project::new("Test Project"); - let wb = p.workbenches.first().unwrap(); + let mut p = Project::new("Test Project"); let plane_description = PlaneDescription::PlaneId(0); - let sketch_id = AddSketch { plane_description }.handle_message(wb.clone()).unwrap().unwrap(); - let sketch = wb.borrow().get_sketch_by_id(sketch_id).unwrap(); - - let ll = AddPoint { x: 0.0, y: 0.0 }.handle_message(sketch.clone()).unwrap().unwrap(); - let lr = AddPoint { x: 40.0, y: 0.0 }.handle_message(sketch.clone()).unwrap().unwrap(); - let ul = AddPoint { x: 0.0, y: 40.0 }.handle_message(sketch.clone()).unwrap().unwrap(); - let ur = AddPoint { x: 40.0, y: 40.0 }.handle_message(sketch.clone()).unwrap().unwrap(); + let sketch_id = IDWrap { id: 0, inner: AddSketch { plane_description } }.handle_project_message(&mut p).unwrap().unwrap(); + + add_test_rectangle(&mut p, sketch_id, 0.0, 0.0, 40.0, 40.0); + + IDWrap { + id: 0, + inner: extrusion::Add { + sketch_id: 0, + faces: vec![0], + length: 25.0, + offset: 0.0, + direction: Direction::Normal, + mode: Mode::New + } + }.handle_project_message(&mut p).unwrap().unwrap(); - AddLine { start: ll, end: lr }.handle_message(sketch.clone()).unwrap(); - AddLine { start: lr, end: ur }.handle_message(sketch.clone()).unwrap(); - AddLine { start: ur, end: ul }.handle_message(sketch.clone()).unwrap(); - AddLine { start: ul, end: ll }.handle_message(sketch.clone()).unwrap(); + p + } - let faces = sketch.borrow().sketch().borrow().get_faces(); - extrusion::Add { sketch_id, faces, length: 25.0, offset: 0.0, direction: Direction::Normal, mode: Mode::New }.handle_message(wb.clone()).unwrap(); + pub fn add_test_rectangle(p: &mut Project, sketch_id: IDType, x_start: f64, y_start: f64, x_end: f64, y_end: f64) { + let ll = IDWrap { id: 0, inner: IDWrap { id: sketch_id, inner: AddPoint { x: x_start, y: y_start } } }.handle_project_message(p).unwrap().unwrap(); + let lr = IDWrap { id: 0, inner: IDWrap { id: sketch_id, inner: AddPoint { x: x_end, y: y_start } } }.handle_project_message(p).unwrap().unwrap(); + let ul = IDWrap { id: 0, inner: IDWrap { id: sketch_id, inner: AddPoint { x: x_start, y: y_end } } }.handle_project_message(p).unwrap().unwrap(); + let ur = IDWrap { id: 0, inner: IDWrap { id: sketch_id, inner: AddPoint { x: x_end, y: y_end } } }.handle_project_message(p).unwrap().unwrap(); - p + IDWrap { id: 0, inner: IDWrap { id: sketch_id, inner: AddLine { start: ll, end: lr } } }.handle_project_message(p).unwrap().unwrap(); + IDWrap { id: 0, inner: IDWrap { id: sketch_id, inner: AddLine { start: lr, end: ur } } }.handle_project_message(p).unwrap().unwrap(); + IDWrap { id: 0, inner: IDWrap { id: sketch_id, inner: AddLine { start: ur, end: ul } } }.handle_project_message(p).unwrap().unwrap(); + IDWrap { id: 0, inner: IDWrap { id: sketch_id, inner: AddLine { start: ul, end: ll } } }.handle_project_message(p).unwrap().unwrap(); } #[test] @@ -141,51 +153,35 @@ pub mod tests { let workbench_ref = p.get_workbench_by_id(0).unwrap(); let workbench = workbench_ref.borrow(); - let solids = &workbench.solids; + let solids = &workbench.features; println!("solids: {:?}", solids); assert_eq!(solids.len(), 1); } - // #[test] - // fn move_sketch() { - // let mut p = Project::new("Test Project"); - - // let right_plane_id = p.workbenches[0].plane_name_to_id("Right").unwrap(); - - // let message = &Message::SetSketchPlane { - // workbench_id: 0, - // sketch_id: "Sketch-0".to_owned(), - // plane_id: right_plane_id, - // }; - - // let result = p.handle_message(message); - // match result { - // Ok(res) => println!("{}", res), - // Err(e) => println!("{}", e), - // } - // // println!("{:?}", result); + #[test] + fn move_sketch() { + let p = create_test_project(); + let workbench_ref = p.get_workbench_by_id(0).unwrap(); - // let realization = p.get_realization(0, 1000); - // } + SetSketchPlane { + sketch_id: 0, + plane_description: PlaneDescription::PlaneId(1), + }.handle_message(workbench_ref.clone()).unwrap(); + } - // #[test] - // fn rename_plane() { - // let mut p = create_test_project(); + #[test] + fn rename_step() { + let p = create_test_project(); + let workbench_ref = p.get_workbench_by_id(0).unwrap(); + let workbench = workbench_ref.borrow(); + let new_name = "New Extrusion Name".to_string(); + let target = workbench.history.last().unwrap(); - // let message = &Message::RenameStep { - // workbench_id: 0, - // step_id: 1, - // new_name: "Top-2".to_owned(), - // }; + step::Rename { new_name: new_name.clone() }.handle_message(target.clone()).unwrap(); - // let result = message.handle(&mut p); - // match result { - // Ok(res) => println!("{}", res), - // Err(e) => println!("{}", e), - // } - // // let realization = p.get_realization(0, 1000); - // } + assert_eq!(target.borrow().name, new_name); + } #[test] #[ignore = "uses old filetype"] diff --git a/packages/cadmium/src/step.rs b/packages/cadmium/src/step.rs index 8cdc3056..84bf1374 100644 --- a/packages/cadmium/src/step.rs +++ b/packages/cadmium/src/step.rs @@ -1,10 +1,13 @@ +use std::cell::RefCell; use std::fmt::Display; +use std::rc::Rc; use serde::{Deserialize, Serialize}; use tsify_next::Tsify; use wasm_bindgen::prelude::*; -use crate::message::Message; +use crate::message::{Identifiable, Message, MessageHandler}; +use crate::workbench::Workbench; use crate::IDType; #[derive(Tsify, Clone, Debug, Serialize, Deserialize)] @@ -20,7 +23,7 @@ impl Step { pub fn new(id: IDType, data: Message) -> Self { Step { id, - name: "TODO".to_string(), + name: format!("{}-{}", data, id), suppressed: false, data, } @@ -33,6 +36,50 @@ impl Step { impl Display for Step { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}:{}-{}", self.name, self.data, self.id) + write!(f, "{}-{}", self.data, self.id) + } +} + + +impl Identifiable for Rc> { + type Parent = Rc>; + const ID_NAME: &'static str = "step_id"; + + fn from_parent_id(parent: &Self::Parent, id: IDType) -> anyhow::Result { + Ok(parent + .borrow() + .history.get(id as usize) + .ok_or(anyhow::anyhow!("No step with ID {} exists in the current workbench", id))? + .clone()) + } +} + +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] +#[tsify(from_wasm_abi, into_wasm_abi)] +pub struct Rename { + pub new_name: String, +} + +impl MessageHandler for Rename { + type Parent = Rc>; + fn handle_message(&self, step_ref: Self::Parent) -> anyhow::Result> { + let mut step = step_ref.borrow_mut(); + step.name = self.new_name.clone(); + Ok(None) + } +} + +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] +#[tsify(from_wasm_abi, into_wasm_abi)] +pub struct Delete { + pub step_id: IDType, +} + +impl MessageHandler for Delete { + type Parent = Rc>; + fn handle_message(&self, workbench_ref: Self::Parent) -> anyhow::Result> { + let mut workbench = workbench_ref.borrow_mut(); + workbench.history.remove(self.step_id as usize); + Ok(None) } } diff --git a/packages/cadmium/src/workbench.rs b/packages/cadmium/src/workbench.rs index 2d628be1..c5de03b4 100644 --- a/packages/cadmium/src/workbench.rs +++ b/packages/cadmium/src/workbench.rs @@ -5,8 +5,8 @@ use wasm_bindgen::prelude::*; use crate::archetypes::{Plane, PlaneDescription}; use crate::error::CADmiumError; use crate::isketch::ISketch; -use crate::solid::point::Point3; -use crate::solid::Solid; +use crate::feature::Feature; +use crate::feature::point::Point3; use crate::step::Step; use crate::IDType; @@ -20,7 +20,7 @@ use std::rc::Rc; #[tsify(into_wasm_abi, from_wasm_abi)] pub struct Workbench { pub name: String, - pub history: Vec, + pub history: Vec>>, // These are free-standing points in 3D space, not part of sketches pub points: BTreeMap>>, @@ -31,8 +31,8 @@ pub struct Workbench { pub sketches: BTreeMap>>, pub sketches_next_id: IDType, - pub solids: BTreeMap>>, - pub solids_next_id: IDType, + pub features: BTreeMap>>, + pub features_next_id: IDType, } impl Workbench { @@ -49,8 +49,8 @@ impl Workbench { sketches: BTreeMap::new(), sketches_next_id: 0, - solids: BTreeMap::new(), - solids_next_id: 0, + features: BTreeMap::new(), + features_next_id: 0, }; wb.points.insert(0, Rc::new(RefCell::new(Point3::new(0.0, 0.0, 0.0)))); @@ -83,7 +83,10 @@ impl Workbench { } pub fn add_message_step(&mut self, message: &Message) { - self.history.push(Step::new(self.history.len() as IDType, message.clone())); + self.history.push( + Rc::new( + RefCell::new( + Step::new(self.history.len() as IDType, message.clone())))); } } @@ -186,3 +189,28 @@ impl MessageHandler for WorkbenchRename { Ok(None) } } + +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] +#[tsify(from_wasm_abi, into_wasm_abi)] +pub struct SetSketchPlane { + pub sketch_id: IDType, + pub plane_description: PlaneDescription, +} + +impl MessageHandler for SetSketchPlane { + type Parent = Rc>; + fn handle_message(&self, workbench_ref: Self::Parent) -> anyhow::Result> { + let wb = workbench_ref.borrow(); + + let plane = match self.plane_description { + PlaneDescription::PlaneId(plane_id) => + wb.planes.get(&plane_id).ok_or(anyhow::anyhow!("Failed to find plane with id {}", plane_id))?, + PlaneDescription::SolidFace { solid_id: _, normal: _ } => todo!("Implement SolidFace"), + }.clone(); + + let sketch = wb.sketches.get(&self.sketch_id).ok_or(anyhow::anyhow!("Failed to find sketch with id {}", self.sketch_id))?; + sketch.borrow_mut().plane = plane; + + Ok(None) + } +} diff --git a/packages/shared/cadmium-api.ts b/packages/shared/cadmium-api.ts index 3a6d7c0e..aefab2b1 100644 --- a/packages/shared/cadmium-api.ts +++ b/packages/shared/cadmium-api.ts @@ -1,65 +1,234 @@ -import { Direction, IDType, MessageResult, Mode, Plane, PlaneDescription } from "cadmium"; -import { sendWasmMessage } from "./projectUtils"; +import {Direction, IDType, MessageResult, Mode, Plane, PlaneDescription} from "cadmium" +import {sendWasmMessage} from "./projectUtils" -interface ProjectRename { new_name: string }; +interface ProjectRename { + new_name: string +} export function projectRename(new_name: string): MessageResult { - const message: Message = { ProjectRename: { new_name } } - return sendWasmMessage(message) + const message: Message = {ProjectRename: {new_name}} + return sendWasmMessage(message) +} +interface WorkbenchRename { + workbench_id: IDType + new_name: string } -interface WorkbenchRename { workbench_id: IDType, new_name: string }; export function workbenchRename(workbench_id: IDType, new_name: string): MessageResult { - const message: Message = { WorkbenchRename: { workbench_id, new_name } } - return sendWasmMessage(message) + const message: Message = {WorkbenchRename: {workbench_id, new_name}} + return sendWasmMessage(message) +} +interface WorkbenchPointAdd { + workbench_id: IDType + x: number + y: number + z: number } -interface WorkbenchPointAdd { workbench_id: IDType, x: number, y: number, z: number }; export function workbenchPointAdd(workbench_id: IDType, x: number, y: number, z: number): MessageResult { - const message: Message = { WorkbenchPointAdd: { workbench_id, x, y, z } } - return sendWasmMessage(message) + const message: Message = {WorkbenchPointAdd: {workbench_id, x, y, z}} + return sendWasmMessage(message) +} +interface WorkbenchPlaneAdd { + workbench_id: IDType + plane: Plane + width: number + height: number } -interface WorkbenchPlaneAdd { workbench_id: IDType, plane: Plane, width: number, height: number }; export function workbenchPlaneAdd(workbench_id: IDType, plane: Plane, width: number, height: number): MessageResult { - const message: Message = { WorkbenchPlaneAdd: { workbench_id, plane, width, height } } - return sendWasmMessage(message) + const message: Message = {WorkbenchPlaneAdd: {workbench_id, plane, width, height}} + return sendWasmMessage(message) +} +interface WorkbenchSketchAdd { + workbench_id: IDType + plane_description: PlaneDescription } -interface WorkbenchSketchAdd { workbench_id: IDType, plane_description: PlaneDescription }; export function workbenchSketchAdd(workbench_id: IDType, plane_description: PlaneDescription): MessageResult { - const message: Message = { WorkbenchSketchAdd: { workbench_id, plane_description } } - return sendWasmMessage(message) + const message: Message = {WorkbenchSketchAdd: {workbench_id, plane_description}} + return sendWasmMessage(message) +} +interface WorkbenchSketchSetPlane { + workbench_id: IDType + sketch_id: IDType + plane_description: PlaneDescription +} +export function WorkbenchSketchSetPlane(workbench_id: IDType, sketch_id: IDType, plane_description: PlaneDescription): MessageResult { + const message: Message = {WorkbenchSketchSetPlane: {workbench_id, sketch_id, plane_description}} + return sendWasmMessage(message) +} +interface WorkbenchPointUpdate { + workbench_id: IDType + point_id: IDType + x: number + y: number + z: number } -interface WorkbenchPointUpdate { workbench_id: IDType, point_id: IDType, x: number, y: number, z: number }; export function workbenchPointUpdate(workbench_id: IDType, point_id: IDType, x: number, y: number, z: number): MessageResult { - const message: Message = { WorkbenchPointUpdate: { workbench_id, point_id, x, y, z } } - return sendWasmMessage(message) + const message: Message = {WorkbenchPointUpdate: {workbench_id, point_id, x, y, z}} + return sendWasmMessage(message) +} +interface SketchAddPoint { + workbench_id: IDType + sketch_id: IDType + x: number + y: number + z: number } -interface SketchAddPoint { workbench_id: IDType, sketch_id: IDType, x: number, y: number, z: number }; export function sketchAddPoint(workbench_id: IDType, sketch_id: IDType, x: number, y: number, z: number): MessageResult { - const message: Message = { SketchAddPoint: { workbench_id, sketch_id, x, y, z } } - return sendWasmMessage(message) + const message: Message = {SketchAddPoint: {workbench_id, sketch_id, x, y, z}} + return sendWasmMessage(message) +} +interface SketchAddArc { + workbench_id: IDType + sketch_id: IDType + center: IDType + radius: number + clockwise: boolean + start_angle: number + end_angle: number } -interface SketchAddArc { workbench_id: IDType, sketch_id: IDType, center: IDType, radius: number, clockwise: boolean, start_angle: number, end_angle: number }; -export function sketchAddArc(workbench_id: IDType, sketch_id: IDType, center: IDType, radius: number, clockwise: boolean, start_angle: number, end_angle: number): MessageResult { - const message: Message = { SketchAddArc: { workbench_id, sketch_id, center, radius, clockwise, start_angle, end_angle } } - return sendWasmMessage(message) +export function sketchAddArc( + workbench_id: IDType, + sketch_id: IDType, + center: IDType, + radius: number, + clockwise: boolean, + start_angle: number, + end_angle: number, +): MessageResult { + const message: Message = {SketchAddArc: {workbench_id, sketch_id, center, radius, clockwise, start_angle, end_angle}} + return sendWasmMessage(message) +} +interface SketchAddCircle { + workbench_id: IDType + sketch_id: IDType + center: IDType + radius: number } -interface SketchAddCircle { workbench_id: IDType, sketch_id: IDType, center: IDType, radius: number }; export function sketchAddCircle(workbench_id: IDType, sketch_id: IDType, center: IDType, radius: number): MessageResult { - const message: Message = { SketchAddCircle: { workbench_id, sketch_id, center, radius } } - return sendWasmMessage(message) + const message: Message = {SketchAddCircle: {workbench_id, sketch_id, center, radius}} + return sendWasmMessage(message) +} +interface SketchAddLine { + workbench_id: IDType + sketch_id: IDType + start: IDType + end: IDType } -interface SketchAddLine { workbench_id: IDType, sketch_id: IDType, start: IDType, end: IDType }; export function sketchAddLine(workbench_id: IDType, sketch_id: IDType, start: IDType, end: IDType): MessageResult { - const message: Message = { SketchAddLine: { workbench_id, sketch_id, start, end } } - return sendWasmMessage(message) + const message: Message = {SketchAddLine: {workbench_id, sketch_id, start, end}} + return sendWasmMessage(message) +} +interface SketchAddRectangle { + workbench_id: IDType + sketch_id: IDType + start: IDType + end: IDType +} +export function sketchAddRectangle(workbench_id: IDType, sketch_id: IDType, start: IDType, end: IDType): MessageResult { + const message: Message = {SketchAddRectangle: {workbench_id, sketch_id, start, end}} + return sendWasmMessage(message) +} +interface SketchDeleteCompound { + workbench_id: IDType + sketch_id: IDType + compound_id: IDType +} +export function sketchDeleteCompound(workbench_id: IDType, sketch_id: IDType, compound_id: IDType): MessageResult { + const message: Message = {SketchDeleteCompound: {workbench_id, sketch_id, compound_id}} + return sendWasmMessage(message) +} +interface SketchDeletePrimitive { + workbench_id: IDType + sketch_id: IDType + primitive_id: IDType } -interface SketchDeletePrimitive { workbench_id: IDType, sketch_id: IDType, primitive_id: IDType }; export function sketchDeletePrimitive(workbench_id: IDType, sketch_id: IDType, primitive_id: IDType): MessageResult { - const message: Message = { SketchDeletePrimitive: { workbench_id, sketch_id, primitive_id } } - return sendWasmMessage(message) + const message: Message = {SketchDeletePrimitive: {workbench_id, sketch_id, primitive_id}} + return sendWasmMessage(message) +} +interface FeatureExtrusionAdd { + workbench_id: IDType + sketch_id: IDType + faces: IDType[] + length: number + offset: number + direction: Direction + mode: Mode +} +export function featureExtrusionAdd( + workbench_id: IDType, + sketch_id: IDType, + faces: IDType[], + length: number, + offset: number, + direction: Direction, + mode: Mode, +): MessageResult { + const message: Message = {FeatureExtrusionAdd: {workbench_id, sketch_id, faces, length, offset, direction, mode}} + return sendWasmMessage(message) +} +interface FeatureExtrusionUpdateFaces { + workbench_id: IDType + extrusion_id: IDType + sketch_id: IDType + faces: IDType[] +} +export function featureExtrusionUpdateFaces(workbench_id: IDType, extrusion_id: IDType, sketch_id: IDType, faces: IDType[]): MessageResult { + const message: Message = {FeatureExtrusionUpdateFaces: {workbench_id, extrusion_id, sketch_id, faces}} + return sendWasmMessage(message) +} +interface FeatureExtrusionUpdateForm { + workbench_id: IDType + extrusion_id: IDType + length: number + offset: number + direction: Direction + mode: Mode +} +export function featureExtrusionUpdateForm( + workbench_id: IDType, + extrusion_id: IDType, + length: number, + offset: number, + direction: Direction, + mode: Mode, +): MessageResult { + const message: Message = {FeatureExtrusionUpdateForm: {workbench_id, extrusion_id, length, offset, direction, mode}} + return sendWasmMessage(message) +} +interface StepRename { + workbench_id: IDType + step_id: IDType + new_name: string +} +export function stepRename(workbench_id: IDType, step_id: IDType, new_name: string): MessageResult { + const message: Message = {StepRename: {workbench_id, step_id, new_name}} + return sendWasmMessage(message) +} +interface StepDelete { + workbench_id: IDType + step_id: IDType } -interface SolidExtrusionAdd { workbench_id: IDType, sketch_id: IDType, faces: Face[], length: number, offset: number, direction: Direction, mode: Mode }; -export function solidExtrusionAdd(workbench_id: IDType, sketch_id: IDType, faces: Face[], length: number, offset: number, direction: Direction, mode: Mode): MessageResult { - const message: Message = { SolidExtrusionAdd: { workbench_id, sketch_id, faces, length, offset, direction, mode } } - return sendWasmMessage(message) +export function stepDelete(workbench_id: IDType, step_id: IDType): MessageResult { + const message: Message = {StepDelete: {workbench_id, step_id}} + return sendWasmMessage(message) } -export type Message = { ProjectRename: ProjectRename } | { WorkbenchRename: WorkbenchRename } | { WorkbenchPointAdd: WorkbenchPointAdd } | { WorkbenchPlaneAdd: WorkbenchPlaneAdd } | { WorkbenchSketchAdd: WorkbenchSketchAdd } | { WorkbenchPointUpdate: WorkbenchPointUpdate } | { SketchAddPoint: SketchAddPoint } | { SketchAddArc: SketchAddArc } | { SketchAddCircle: SketchAddCircle } | { SketchAddLine: SketchAddLine } | { SketchDeletePrimitive: SketchDeletePrimitive } | { SolidExtrusionAdd: SolidExtrusionAdd }; +export type Message = + | {ProjectRename: ProjectRename} + | {WorkbenchRename: WorkbenchRename} + | {WorkbenchPointAdd: WorkbenchPointAdd} + | {WorkbenchPlaneAdd: WorkbenchPlaneAdd} + | {WorkbenchSketchAdd: WorkbenchSketchAdd} + | {WorkbenchSketchSetPlane: WorkbenchSketchSetPlane} + | {WorkbenchPointUpdate: WorkbenchPointUpdate} + | {SketchAddPoint: SketchAddPoint} + | {SketchAddArc: SketchAddArc} + | {SketchAddCircle: SketchAddCircle} + | {SketchAddLine: SketchAddLine} + | {SketchAddRectangle: SketchAddRectangle} + | {SketchDeleteCompound: SketchDeleteCompound} + | {SketchDeletePrimitive: SketchDeletePrimitive} + | {FeatureExtrusionAdd: FeatureExtrusionAdd} + | {FeatureExtrusionUpdateFaces: FeatureExtrusionUpdateFaces} + | {FeatureExtrusionUpdateForm: FeatureExtrusionUpdateForm} + | {StepRename: StepRename} + | {StepDelete: StepDelete} diff --git a/packages/shared/projectUtils.ts b/packages/shared/projectUtils.ts index bbb02795..fd24d6ba 100644 --- a/packages/shared/projectUtils.ts +++ b/packages/shared/projectUtils.ts @@ -1,35 +1,35 @@ import * as cadFunctions from "./cadmium-api" -(window as any).cad = cadFunctions +;(window as any).cad = cadFunctions import { - workbenchIsStale, - workbenchIndex, - workbench, - project, - featureIndex, - wasmProject, - projectIsStale, - realizationIsStale, - wasmRealization, - realization, - messageHistory, + workbenchIsStale, + workbenchIndex, + workbench, + project, + featureIndex, + wasmProject, + projectIsStale, + realizationIsStale, + wasmRealization, + realization, + messageHistory, } from "./stores" import {get} from "svelte/store" import {Vector2, Vector3, type Vector2Like} from "three" import type { - Entity, - ExtrusionHistoryStep, - HistoryStep, - MessageHistory, - PlaneHistoryStep, - PointHistoryStep, - SketchHistoryStep, - WithTarget, - WorkBench + Entity, + ExtrusionHistoryStep, + HistoryStep, + MessageHistory, + PlaneHistoryStep, + PointHistoryStep, + SketchHistoryStep, + WithTarget, + WorkBench, } from "./types" -import type { Realization as WasmRealization, Primitive, StepData, Workbench, MessageResult } from "cadmium" -import type { Message } from "./cadmium-api" -import { isMessage } from "./typeGuards" +import type {Realization as WasmRealization, Primitive, StepData, Workbench, MessageResult} from "cadmium" +import type {Message} from "./cadmium-api" +import {isMessage} from "./typeGuards" // import { isDevelopment } from "../+layout" // prettier-ignore @@ -38,458 +38,457 @@ const log = (function () { const context = "[projectUtils.ts]"; const color = "a export const CIRCLE_TOLERANCE = 0.05 export function isPoint(feature: HistoryStep): feature is PointHistoryStep { - return feature.data.type === "Point" + return feature.data.type === "Point" } export function isPlane(feature: HistoryStep): feature is PlaneHistoryStep { - return feature.data.type === "Plane" + return feature.data.type === "Plane" } export function isExtrusion(feature: HistoryStep): feature is ExtrusionHistoryStep { - return feature.data.type === "Extrusion" + return feature.data.type === "Extrusion" } export function isSketch(feature: HistoryStep): feature is SketchHistoryStep { - return feature.data.type === "Sketch" + return feature.data.type === "Sketch" } export function arraysEqual(a: any[], b: any[]) { - if (a.length !== b.length) return false - for (let i = 0; i < a.length; i++) { - if (a[i] !== b[i]) return false - } - return true + if (a.length !== b.length) return false + for (let i = 0; i < a.length; i++) { + if (a[i] !== b[i]) return false + } + return true } export function sendWasmMessage(message: Message): MessageResult { - let wp = get(wasmProject) - log("[sendWasmMessage] sending message:", message) - let result = wp.send_message(message) - log("[sendWasmMessage] reply:", result) - - messageHistory.update((history: MessageHistory[]) => { - log("[sendWasmMessage] [messageHistory.update] update:", {message, result}) - return [...history, {message, result}] - }) - return result + let wp = get(wasmProject) + log("[sendWasmMessage] sending message:", message) + let result = wp.send_message(message) + log("[sendWasmMessage] reply:", result) + + messageHistory.update((history: MessageHistory[]) => { + log("[sendWasmMessage] [messageHistory.update] update:", {message, result}) + return [...history, {message, result}] + }) + return result } export function updateExtrusion(extrusionId: number, sketchId: number, length: number, faceIds: string[]) { - const message: Message = { - UpdateExtrusion: { - workbench_id: get(workbenchIndex), - sketch_id: sketchId, - face_ids: faceIds.map(id => +id), // on browser side ids are strings - coerce face ids to numbers here to suit rust - length, - offset: 0.0, - extrusion_name: "Extra", - direction: "Normal", - extrusion_id: extrusionId, - }, - } - const isValid = checkWasmMessage(message) - const hasFaceIds = notEmpty(message.UpdateExtrusion.face_ids) - if (isValid) { - sendWasmMessage(message) - workbenchIsStale.set(true) - if (hasFaceIds) { - log("[updateExtrusion]", "[checkWasmMessage]", "is valid,", "sending message...", message) - // sendWasmMessage(message) - } else log("[updateExtrusion]", "[checkWasmMessage]", "is valid,", "but face_ids is empty,", "NOT sending message:", message) - } else log("[updateExtrusion]", "[checkWasmMessage]", "is bogus,", "abort message send!", message) - - // sendWasmMessage(message) - - // should this be set stale when not sending the wasm message? todo - // workbenchIsStale.set(true) + const message: Message = { + UpdateExtrusion: { + workbench_id: get(workbenchIndex), + sketch_id: sketchId, + face_ids: faceIds.map(id => +id), // on browser side ids are strings - coerce face ids to numbers here to suit rust + length, + offset: 0.0, + extrusion_name: "Extra", + direction: "Normal", + extrusion_id: extrusionId, + }, + } + const isValid = checkWasmMessage(message) + const hasFaceIds = notEmpty(message.UpdateExtrusion.face_ids) + if (isValid) { + sendWasmMessage(message) + workbenchIsStale.set(true) + if (hasFaceIds) { + log("[updateExtrusion]", "[checkWasmMessage]", "is valid,", "sending message...", message) + // sendWasmMessage(message) + } else log("[updateExtrusion]", "[checkWasmMessage]", "is valid,", "but face_ids is empty,", "NOT sending message:", message) + } else log("[updateExtrusion]", "[checkWasmMessage]", "is bogus,", "abort message send!", message) + + // sendWasmMessage(message) + + // should this be set stale when not sending the wasm message? todo + // workbenchIsStale.set(true) } export function setSketchPlane(sketchId: number, planeId: number) { - const message: Message = { - SetSketchPlane: { - workbench_id: get(workbenchIndex), - sketch_id: sketchId, - plane_id: planeId - } - } - checkWasmMessage(message) - sendWasmMessage(message) + const message: Message = { + SetSketchPlane: { + workbench_id: get(workbenchIndex), + sketch_id: sketchId, + plane_id: planeId, + }, + } + checkWasmMessage(message) + sendWasmMessage(message) } export function newSketchOnPlane() { - const message: Message = { - StepAction: { - name: "", - data: { - workbench_id: get(workbenchIndex), - plane_id: "", // leave it floating at first - } - } - } - checkWasmMessage(message) - sendWasmMessage(message) + const message: Message = { + StepAction: { + name: "", + data: { + workbench_id: get(workbenchIndex), + plane_id: "", // leave it floating at first + }, + }, + } + checkWasmMessage(message) + sendWasmMessage(message) } export function newExtrusion() { - const bench: Workbench = get(workbench) - // log("[newExtrusion] workbench:", workbench) - // log("[newExtrusion] bench:", bench) - - let sketchId = "" - for (let step of bench.history) { - if (step.data.type === "Sketch") { - sketchId = step.unique_id - } - } - if (sketchId === "") { - log("No sketch found in history") - return - } - - const message: Message = { - StepAction: { - data: { - workbench_id: get(workbenchIndex), - sketch_id: sketchId, - face_ids: [], - length: 25, - offset: 0.0, - extrusion_name: "", - direction: "Normal", - }, - } - } - - // we check for face_ids: [] to contain numbers but we send an empty array - // todo: maybe change isNewExtrusion? although with the rust api it is possible to send an array of faceids so we ought to check them... - // probably best to alter isNewExtrusion to allow an empty array or a number[] - checkWasmMessage(message) - sendWasmMessage(message) + const bench: Workbench = get(workbench) + // log("[newExtrusion] workbench:", workbench) + // log("[newExtrusion] bench:", bench) + + let sketchId = "" + for (let step of bench.history) { + if (step.data.type === "Sketch") { + sketchId = step.unique_id + } + } + if (sketchId === "") { + log("No sketch found in history") + return + } + + const message: Message = { + StepAction: { + data: { + workbench_id: get(workbenchIndex), + sketch_id: sketchId, + face_ids: [], + length: 25, + offset: 0.0, + extrusion_name: "", + direction: "Normal", + }, + }, + } + + // we check for face_ids: [] to contain numbers but we send an empty array + // todo: maybe change isNewExtrusion? although with the rust api it is possible to send an array of faceids so we ought to check them... + // probably best to alter isNewExtrusion to allow an empty array or a number[] + checkWasmMessage(message) + sendWasmMessage(message) } export function deleteEntities(sketchIdx: string, selection: Entity[]) { - const workbenchIdx = get(workbenchIndex) - - // log("[deleteEntities]", "sketchIdx:", sketchIdx, "selection:", selection, "workbenchIdx:", workbenchIdx, "sketchIdx:", sketchIdx, "selection:", selection) - const lines = selection.filter(e => e.type === "line") - const arcs = selection.filter(e => e.type === "arc") - const circles = selection.filter(e => e.type === "circle") - // const points = selection.filter((e) => e.type === 'point') - - const lineIds = reduceToInts( - lines.map(e => e.id), - (id: any) => console.error(`[deleteEntities] line id is not an int: ${id}`), - ) - const arcIds = reduceToInts( - arcs.map(e => e.id), - (id: any) => console.error(`[deleteEntities] arc id is not an int: ${id}`), - ) - const circleIds = reduceToInts( - circles.map(e => e.id), - (id: any) => console.error(`[deleteEntities] circle id is not an int: ${id}`), - ) - - if (notEmpty(lineIds)) deleteLines(workbenchIdx, sketchIdx, lineIds) - if (notEmpty(arcIds)) deleteArcs(workbenchIdx, sketchIdx, arcIds) - if (notEmpty(circleIds)) deleteCircles(workbenchIdx, sketchIdx, circleIds) - - // only refresh the workbench once, after all deletions are done - workbenchIsStale.set(true) + const workbenchIdx = get(workbenchIndex) + + // log("[deleteEntities]", "sketchIdx:", sketchIdx, "selection:", selection, "workbenchIdx:", workbenchIdx, "sketchIdx:", sketchIdx, "selection:", selection) + const lines = selection.filter(e => e.type === "line") + const arcs = selection.filter(e => e.type === "arc") + const circles = selection.filter(e => e.type === "circle") + // const points = selection.filter((e) => e.type === 'point') + + const lineIds = reduceToInts( + lines.map(e => e.id), + (id: any) => console.error(`[deleteEntities] line id is not an int: ${id}`), + ) + const arcIds = reduceToInts( + arcs.map(e => e.id), + (id: any) => console.error(`[deleteEntities] arc id is not an int: ${id}`), + ) + const circleIds = reduceToInts( + circles.map(e => e.id), + (id: any) => console.error(`[deleteEntities] circle id is not an int: ${id}`), + ) + + if (notEmpty(lineIds)) deleteLines(workbenchIdx, sketchIdx, lineIds) + if (notEmpty(arcIds)) deleteArcs(workbenchIdx, sketchIdx, arcIds) + if (notEmpty(circleIds)) deleteCircles(workbenchIdx, sketchIdx, circleIds) + + // only refresh the workbench once, after all deletions are done + workbenchIsStale.set(true) } export function addRectangleBetweenPoints(sketchIdx: string, point1: number, point2: number) { - log("[addRectangleBetweenPoints] sketchIdx, point1, point2", sketchIdx, point1, point2) - const message: Message = { - NewRectangleBetweenPoints: { - workbench_id: get(workbenchIndex), - sketch_id: sketchIdx, - start_id: point1, - end_id: point2 - } - } - checkWasmMessage(message) - sendWasmMessage(message) + log("[addRectangleBetweenPoints] sketchIdx, point1, point2", sketchIdx, point1, point2) + const message: Message = { + NewRectangleBetweenPoints: { + workbench_id: get(workbenchIndex), + sketch_id: sketchIdx, + start_id: point1, + end_id: point2, + }, + } + checkWasmMessage(message) + sendWasmMessage(message) } export function addCircleBetweenPoints(sketchIdx: string, point1: string, point2: string) { - log("[addCircleBetweenPoints]", "sketchIdx:", sketchIdx, "point1:", point1, "point2", point2) - - const p1Valid = isStringInt(point1, id => console.error("[projectUtils.ts] [addCircleBetweenPoints]", "id is not an int:", id)) - const p2Valid = isStringInt(point2, id => console.error("[projectUtils.ts] [addCircleBetweenPoints]", "id is not an int:", id)) - - if (!p1Valid || !p2Valid) return - - const message: Message = { - NewCircleBetweenPoints: { - workbench_id: get(workbenchIndex), - sketch_id: sketchIdx, - center_id: parseInt(point1, 10), - edge_id: parseInt(point2, 10) - } - } - checkWasmMessage(message) - sendWasmMessage(message) + log("[addCircleBetweenPoints]", "sketchIdx:", sketchIdx, "point1:", point1, "point2", point2) + + const p1Valid = isStringInt(point1, id => console.error("[projectUtils.ts] [addCircleBetweenPoints]", "id is not an int:", id)) + const p2Valid = isStringInt(point2, id => console.error("[projectUtils.ts] [addCircleBetweenPoints]", "id is not an int:", id)) + + if (!p1Valid || !p2Valid) return + + const message: Message = { + NewCircleBetweenPoints: { + workbench_id: get(workbenchIndex), + sketch_id: sketchIdx, + center_id: parseInt(point1, 10), + edge_id: parseInt(point2, 10), + }, + } + checkWasmMessage(message) + sendWasmMessage(message) } export function addLineToSketch(sketchIdx: string, point1: number, point2: number) { - const message: Message = { - NewLineOnSketch: { - workbench_id: get(workbenchIndex), - sketch_id: sketchIdx, - start_point_id: point1, - end_point_id: point2 - } - } - checkWasmMessage(message) - sendWasmMessage(message) + const message: Message = { + NewLineOnSketch: { + workbench_id: get(workbenchIndex), + sketch_id: sketchIdx, + start_point_id: point1, + end_point_id: point2, + }, + } + checkWasmMessage(message) + sendWasmMessage(message) } export function addPointToSketch(sketchIdx: string, point: Vector2Like, hidden: boolean) { - log("[addPointToSketch] sketchIdx, point, hidden", sketchIdx, point, hidden) - const message: Message = { - NewPointOnSketch2: { - workbench_id: get(workbenchIndex), - sketch_id: sketchIdx, - x: point.x, - y: point.y, - hidden: hidden, - }, - } - checkWasmMessage(message) - const reply = sendWasmMessage(message) - // log("[addPointToSketch sendWasmMessage]", "message:", message, "reply:", reply) - - if (!reply.success) console.error("ERROR [projectUtils.ts addPointToSketch sendWasmMessage]", "message:", message, "reply:", reply) - - workbenchIsStale.set(true) - return JSON.parse(reply.data).id + log("[addPointToSketch] sketchIdx, point, hidden", sketchIdx, point, hidden) + const message: Message = { + NewPointOnSketch2: { + workbench_id: get(workbenchIndex), + sketch_id: sketchIdx, + x: point.x, + y: point.y, + hidden: hidden, + }, + } + checkWasmMessage(message) + const reply = sendWasmMessage(message) + // log("[addPointToSketch sendWasmMessage]", "message:", message, "reply:", reply) + + if (!reply.success) console.error("ERROR [projectUtils.ts addPointToSketch sendWasmMessage]", "message:", message, "reply:", reply) + + workbenchIsStale.set(true) + return JSON.parse(reply.data).id } export function addPrimitiveToSketch(sketchIdx: string, primitive: Primitive): number { - const message: Message = { - AddSketchPrimitive: { - workbench_id: get(workbenchIndex), - sketch_id: sketchIdx, - primitive - } - } - checkWasmMessage(message) - const reply = sendWasmMessage(message) - - if (!reply.success) - console.error("ERROR [projectUtils.ts addPrimitiveToSketch sendWasmMessage]", "message:", message, "reply:", reply) - - return JSON.parse(reply.data).id + const message: Message = { + AddSketchPrimitive: { + workbench_id: get(workbenchIndex), + sketch_id: sketchIdx, + primitive, + }, + } + checkWasmMessage(message) + const reply = sendWasmMessage(message) + + if (!reply.success) console.error("ERROR [projectUtils.ts addPrimitiveToSketch sendWasmMessage]", "message:", message, "reply:", reply) + + return JSON.parse(reply.data).id } export function renameStep(stepIdx: number, newName: string): void { - log("[renameStep] stepIdx, newName", stepIdx, newName) - const message: Message = { - RenameStep: { - workbench_id: get(workbenchIndex), - step_id: stepIdx, - new_name: newName, - }, - } - checkWasmMessage(message) - sendWasmMessage(message) + log("[renameStep] stepIdx, newName", stepIdx, newName) + const message: Message = { + RenameStep: { + workbench_id: get(workbenchIndex), + step_id: stepIdx, + new_name: newName, + }, + } + checkWasmMessage(message) + sendWasmMessage(message) } export function renameWorkbench(newName: string): void { - log("[renameWorkbench] newName", newName) - const message: Message = { - RenameWorkbench: { - workbench_id: get(workbenchIndex), - new_name: newName, - }, - } - checkWasmMessage(message) - sendWasmMessage(message) + log("[renameWorkbench] newName", newName) + const message: Message = { + RenameWorkbench: { + workbench_id: get(workbenchIndex), + new_name: newName, + }, + } + checkWasmMessage(message) + sendWasmMessage(message) } export function renameProject(newName: string): void { - log("[renameProject] newName", newName) - const message: Message = { - RenameProject: { - new_name: newName, - }, - } - checkWasmMessage(message) - sendWasmMessage(message) + log("[renameProject] newName", newName) + const message: Message = { + RenameProject: { + new_name: newName, + }, + } + checkWasmMessage(message) + sendWasmMessage(message) } // If the project ever becomes stale, refresh it. This should be pretty rare. projectIsStale.subscribe(value => { - if (value) { - const wp = get(wasmProject) - project.set(JSON.parse(wp.to_json())) - - workbenchIndex.set(0) - workbenchIsStale.set(true) - projectIsStale.set(false) - // @ts-ignore - log("[projectIsStale] Refreshing project", "value:", value, "wasmProject:", wp, "project:", project) - } + if (value) { + const wp = get(wasmProject) + project.set(JSON.parse(wp.to_json())) + + workbenchIndex.set(0) + workbenchIsStale.set(true) + projectIsStale.set(false) + // @ts-ignore + log("[projectIsStale] Refreshing project", "value:", value, "wasmProject:", wp, "project:", project) + } }) // If the workbench ever becomes stale, refresh it. This should be very common. // Every time you edit any part of the feature history, for example workbenchIsStale.subscribe(value => { - if (value) { - log("[workbenchIsStale] Workbench:", get(workbench)) - const workbenchIdx = get(workbenchIndex) - const wasmProj = get(wasmProject) - const workbenchJson = wasmProj.get_workbench(workbenchIdx) - // TODO: reach inside of project and set its representation - // of the workbench to the new one that we just got - workbench.set(workbenchJson) - workbenchIsStale.set(false) - // log("Workbench:", get(workbench)) - realizationIsStale.set(true) - } + if (value) { + log("[workbenchIsStale] Workbench:", get(workbench)) + const workbenchIdx = get(workbenchIndex) + const wasmProj = get(wasmProject) + const workbenchJson = wasmProj.get_workbench(workbenchIdx) + // TODO: reach inside of project and set its representation + // of the workbench to the new one that we just got + workbench.set(workbenchJson) + workbenchIsStale.set(false) + // log("Workbench:", get(workbench)) + realizationIsStale.set(true) + } }) // If the realization ever becomes stale, refresh it. This should be very common. // Every time you edit any part of the feature history, for example realizationIsStale.subscribe(value => { - if (value) { - // log("[realizationIsStale] Refreshing realization") - - const wasmProj = get(wasmProject) - const workbenchIdx = get(workbenchIndex) - const wasmReal: WasmRealization = wasmProj.get_realization(workbenchIdx, get(featureIndex) + 1) - wasmRealization.set(wasmReal) - realization.set(JSON.parse(wasmReal.to_json())) - // log("[realizationIsStale] New realization:", get(realization)) - // log("[wasmProj]", wasmProj) - - realizationIsStale.set(false) - } + if (value) { + // log("[realizationIsStale] Refreshing realization") + + const wasmProj = get(wasmProject) + const workbenchIdx = get(workbenchIndex) + const wasmReal: WasmRealization = wasmProj.get_realization(workbenchIdx, get(featureIndex) + 1) + wasmRealization.set(wasmReal) + realization.set(JSON.parse(wasmReal.to_json())) + // log("[realizationIsStale] New realization:", get(realization)) + // log("[wasmProj]", wasmProj) + + realizationIsStale.set(false) + } }) export function getObjectString(solidId: string): string { - // log("[getObjectString] solidId:", solidId) - const wasmReal = get(wasmRealization) - const objString = wasmReal.solid_to_obj(solidId, 0.1) - return objString + // log("[getObjectString] solidId:", solidId) + const wasmReal = get(wasmRealization) + const objString = wasmReal.solid_to_obj(solidId, 0.1) + return objString } export function readFile(e: WithTarget): void { - const target = e.target as HTMLInputElement - const file = target.files![0] - const reader = new FileReader() - reader.onload = function (e) { - // log("[readFile] file contents", e.target?.result) - } - reader.readAsText(file) + const target = e.target as HTMLInputElement + const file = target.files![0] + const reader = new FileReader() + reader.onload = function (e) { + // log("[readFile] file contents", e.target?.result) + } + reader.readAsText(file) } export function arcToPoints(center: Vector2, start: Vector2, end: Vector2, clockwise: boolean = false): Vector2[] { - // log("[arcToPoints] center, start, end, clockwise", center, start, end, clockwise) - // see https://math.stackexchange.com/a/4132095/816177 - const tolerance = CIRCLE_TOLERANCE // in meters - const radius = start.distanceTo(center) - const k = tolerance / radius - // more precise but slower to calculate: - // const n = Math.ceil(Math.PI / Math.acos(1 - k)) - // faster to calculate, at most only overestimates by 1: - let n = Math.ceil(Math.PI / Math.sqrt(2 * k)) - const segmentAngle = (2 * Math.PI) / n - const segmentLength = radius * segmentAngle - if (clockwise) n = -n - - const startAngle = Math.atan2(start.y - center.y, start.x - center.x) - - const lineVertices: Vector2[] = [] - lineVertices.push(start.clone()) - for (let i = 1; i <= Math.abs(n); i++) { - const theta = ((2 * Math.PI) / n) * i + startAngle - const xComponent = radius * Math.cos(theta) - const yComponent = radius * Math.sin(theta) - const point = new Vector2(xComponent, yComponent).add(center) - lineVertices.push(point) - - const distanceToEnd = point.distanceTo(end) - if (distanceToEnd <= segmentLength) { - lineVertices.push(end.clone()) - break - } - } - return lineVertices + // log("[arcToPoints] center, start, end, clockwise", center, start, end, clockwise) + // see https://math.stackexchange.com/a/4132095/816177 + const tolerance = CIRCLE_TOLERANCE // in meters + const radius = start.distanceTo(center) + const k = tolerance / radius + // more precise but slower to calculate: + // const n = Math.ceil(Math.PI / Math.acos(1 - k)) + // faster to calculate, at most only overestimates by 1: + let n = Math.ceil(Math.PI / Math.sqrt(2 * k)) + const segmentAngle = (2 * Math.PI) / n + const segmentLength = radius * segmentAngle + if (clockwise) n = -n + + const startAngle = Math.atan2(start.y - center.y, start.x - center.x) + + const lineVertices: Vector2[] = [] + lineVertices.push(start.clone()) + for (let i = 1; i <= Math.abs(n); i++) { + const theta = ((2 * Math.PI) / n) * i + startAngle + const xComponent = radius * Math.cos(theta) + const yComponent = radius * Math.sin(theta) + const point = new Vector2(xComponent, yComponent).add(center) + lineVertices.push(point) + + const distanceToEnd = point.distanceTo(end) + if (distanceToEnd <= segmentLength) { + lineVertices.push(end.clone()) + break + } + } + return lineVertices } export function circleToPoints(centerPoint: Vector2Like, radius: number): Vector2[] { - // this is 2D function - - // see https://math.stackexchange.com/a/4132095/816177 - const tolerance = CIRCLE_TOLERANCE // in meters - const k = tolerance / radius - // more precise but slower to calculate: - // const n = Math.ceil(Math.PI / Math.acos(1 - k)) - // faster to calculate, at most only overestimates by 1: - const n = Math.ceil(Math.PI / Math.sqrt(2 * k)) - - const lineVertices: Vector2[] = [] - for (let i = 0; i <= n; i++) { - const theta = ((2 * Math.PI) / n) * i - const xComponent = radius * Math.cos(theta) - const yComponent = radius * Math.sin(theta) - const point = new Vector2(xComponent, yComponent).add(centerPoint) - lineVertices.push(point) - } - return lineVertices + // this is 2D function + + // see https://math.stackexchange.com/a/4132095/816177 + const tolerance = CIRCLE_TOLERANCE // in meters + const k = tolerance / radius + // more precise but slower to calculate: + // const n = Math.ceil(Math.PI / Math.acos(1 - k)) + // faster to calculate, at most only overestimates by 1: + const n = Math.ceil(Math.PI / Math.sqrt(2 * k)) + + const lineVertices: Vector2[] = [] + for (let i = 0; i <= n; i++) { + const theta = ((2 * Math.PI) / n) * i + const xComponent = radius * Math.cos(theta) + const yComponent = radius * Math.sin(theta) + const point = new Vector2(xComponent, yComponent).add(centerPoint) + lineVertices.push(point) + } + return lineVertices } export function promoteTo3(points: Vector2[]): Vector3[] { - const points3: Vector3[] = [] - for (const point of points) { - points3.push(new Vector3(point.x, point.y, 0)) - } - return points3 + const points3: Vector3[] = [] + for (const point of points) { + points3.push(new Vector3(point.x, point.y, 0)) + } + return points3 } export function flatten(points: Vector3[]): number[] { - const pointsFlat: number[] = [] - for (const point of points) { - pointsFlat.push(point.x, point.y, point.z) - } - return pointsFlat + const pointsFlat: number[] = [] + for (const point of points) { + pointsFlat.push(point.x, point.y, point.z) + } + return pointsFlat } function isStringInt(s: string, errorCallback: {(id: any): void; (arg0: string): void}): boolean { - if (typeof s !== "string") console.error("[proectUtils.ts] [isStringInt]", s, "is not a string:", typeof s) - const isInt = !Number.isNaN(parseInt(s, 10)) - if (!isInt) errorCallback(s) - return isInt + if (typeof s !== "string") console.error("[proectUtils.ts] [isStringInt]", s, "is not a string:", typeof s) + const isInt = !Number.isNaN(parseInt(s, 10)) + if (!isInt) errorCallback(s) + return isInt } function reduceToInts(data: string[], errorCallback: (id: any) => void): number[] { - function reducer(acc: number[], id: string): number[] { - return isStringInt(id, errorCallback) ? [...acc, parseInt(id, 10)] : acc - } - return data.reduce(reducer, []) + function reducer(acc: number[], id: string): number[] { + return isStringInt(id, errorCallback) ? [...acc, parseInt(id, 10)] : acc + } + return data.reduce(reducer, []) } function notEmpty(array: unknown[]): boolean { - return array && Array.isArray(array) && array.length > 0 + return array && Array.isArray(array) && array.length > 0 } export function checkWasmMessage(message: Message, abort = true, logError = true): boolean { - const key = Object.keys(message)[0] - const command = message[key as keyof Message] - if (!command) { - console.error("[projectUtils.ts] [checkWasmMessage]", "messageType not found:", key, message) - return false - } - log("[checkWasmMessage]", "checking...", key, message) - - function logOrAbort() { - const error = `[${key}] message failed typecheck:` - if (logError) console.error("[projectUtils.ts]", error, message) - // if (abort && isDevelopment()) throw new Error(`"[projectUtils.ts]" ${error}`) - return false - } - - if (!isMessage(command)) { - logOrAbort() - return false - } - return true + const key = Object.keys(message)[0] + const command = message[key as keyof Message] + if (!command) { + console.error("[projectUtils.ts] [checkWasmMessage]", "messageType not found:", key, message) + return false + } + log("[checkWasmMessage]", "checking...", key, message) + + function logOrAbort() { + const error = `[${key}] message failed typecheck:` + if (logError) console.error("[projectUtils.ts]", error, message) + // if (abort && isDevelopment()) throw new Error(`"[projectUtils.ts]" ${error}`) + return false + } + + if (!isMessage(command)) { + logOrAbort() + return false + } + return true } diff --git a/packages/shared/sketch.ts b/packages/shared/sketch.ts deleted file mode 100644 index 6c21901f..00000000 --- a/packages/shared/sketch.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Message, Primitive } from "cadmium"; -import { get } from "svelte/store"; -import { workbenchIndex } from "./stores"; -import { sendWasmMessage } from "./projectUtils"; - -export class ISketch { - id: string; - - constructor(id: string) { - this.id = id - } - - addPrimitive(primitive: Primitive): number { - const message: Message = { - AddSketchPrimitive: { - workbench_id: get(workbenchIndex), - sketch_id: this.id, - primitive - } - } - - const reply = sendWasmMessage(message) - - if (!reply.success) - console.error("ERROR [projectUtils.ts addPrimitiveToSketch sendWasmMessage]", "message:", message, "reply:", reply) - - return JSON.parse(reply.data).id - } - - deletePrimitives(ids: number[]) { - const message: Message = { - DeleteSketchPrimitives: { - workbench_id: get(workbenchIndex), - sketch_id: this.id, - ids - } - } - - sendWasmMessage(message) - } - - setPlane(plane_id: number) { - const message: Message = { - SetSketchPlane: { - workbench_id: get(workbenchIndex), - sketch_id: this.id, - plane_id: `${plane_id}` - } - } - - sendWasmMessage(message) - } - - addCircle(center: number, external: number): number { - return this.addPrimitive({ - Circle.new() - }) - } -}