Fix clippy lints (#1327)

* Fix clippy lints

* Update formatting

* Remove unsafe send impls

* New type for Rc<NodeContainer>
This commit is contained in:
0HyperCube 2023-07-19 16:38:23 +01:00 committed by Keavon Chambers
parent 743803ce04
commit 80cc5bee73
80 changed files with 549 additions and 445 deletions

345
Cargo.lock generated
View file

@ -62,15 +62,6 @@ dependencies = [
"version_check",
]
[[package]]
name = "aho-corasick"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
[[package]]
name = "aho-corasick"
version = "1.0.2"
@ -136,9 +127,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.71"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854"
[[package]]
name = "approx"
@ -221,9 +212,9 @@ dependencies = [
[[package]]
name = "async-channel"
version = "1.8.0"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833"
checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35"
dependencies = [
"concurrent-queue",
"event-listener",
@ -311,7 +302,7 @@ checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -322,13 +313,13 @@ checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae"
[[package]]
name = "async-trait"
version = "0.1.69"
version = "0.1.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b2d0f03b3640e3a630367e40c468cb7f309529c708ed1d88597047b0e7c6ef7"
checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -527,6 +518,9 @@ name = "bitflags"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
dependencies = [
"serde",
]
[[package]]
name = "block"
@ -600,9 +594,9 @@ dependencies = [
[[package]]
name = "bstr"
version = "1.5.0"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a246e68bb43f6cd9db24bea052a53e40405417c5fb372e3d1a8a7f770a564ef5"
checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05"
dependencies = [
"memchr",
"serde",
@ -631,7 +625,7 @@ checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -694,7 +688,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "599aa35200ffff8f04c1925aa1acc92fa2e08874379ef42e210a80e527e60838"
dependencies = [
"serde",
"toml 0.7.5",
"toml 0.7.6",
]
[[package]]
@ -942,9 +936,9 @@ dependencies = [
[[package]]
name = "cpufeatures"
version = "0.2.8"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c"
checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"
dependencies = [
"libc",
]
@ -1051,7 +1045,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
dependencies = [
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -1077,9 +1071,9 @@ dependencies = [
[[package]]
name = "darling"
version = "0.20.1"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944"
checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
dependencies = [
"darling_core",
"darling_macro",
@ -1087,27 +1081,27 @@ dependencies = [
[[package]]
name = "darling_core"
version = "0.20.1"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb"
checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
name = "darling_macro"
version = "0.20.1"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a"
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
dependencies = [
"darling_core",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -1255,7 +1249,7 @@ checksum = "f7f1e82a60222fc67bfd50d752a9c89da5cce4c39ed39decc84a443b07bbd69a"
dependencies = [
"cc",
"rustc_version",
"toml 0.7.5",
"toml 0.7.6",
"vswhom",
"winreg 0.11.0",
]
@ -1293,7 +1287,7 @@ checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -1311,9 +1305,9 @@ dependencies = [
[[package]]
name = "equivalent"
version = "1.0.0"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
@ -1540,7 +1534,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -1751,12 +1745,12 @@ dependencies = [
[[package]]
name = "glam"
version = "0.22.0"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12f597d56c1bd55a811a1be189459e8fad2bbc272616375602443bdfb37fa774"
checksum = "42218cb640844e3872cc3c153dc975229e080a6c4733b34709ef445610550226"
dependencies = [
"bytemuck",
"num-traits",
"libm",
"serde",
]
@ -1813,11 +1807,11 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "globset"
version = "0.4.10"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc"
checksum = "1391ab1f92ffcc08911957149833e682aa3fe252b9f45f966d2ef972274c97df"
dependencies = [
"aho-corasick 0.7.20",
"aho-corasick",
"bstr",
"fnv",
"log",
@ -1916,7 +1910,7 @@ name = "gpu-executor"
version = "0.1.0"
dependencies = [
"anyhow",
"base64 0.13.1",
"base64 0.21.2",
"bytemuck",
"dyn-any",
"futures",
@ -1937,7 +1931,7 @@ name = "graph-craft"
version = "0.1.0"
dependencies = [
"anyhow",
"base64 0.13.1",
"base64 0.21.2",
"bezier-rs",
"bytemuck",
"dyn-any",
@ -1986,7 +1980,7 @@ name = "graphene-core"
version = "0.1.0"
dependencies = [
"async-trait",
"base64 0.13.1",
"base64 0.21.2",
"bezier-rs",
"bytemuck",
"dyn-any",
@ -2069,7 +2063,7 @@ dependencies = [
name = "graphite-document-legacy"
version = "0.0.0"
dependencies = [
"base64 0.13.1",
"base64 0.21.2",
"bezier-rs",
"glam",
"graph-craft",
@ -2088,7 +2082,7 @@ name = "graphite-editor"
version = "0.0.0"
dependencies = [
"bezier-rs",
"bitflags 1.3.2",
"bitflags 2.3.3",
"derivative",
"dyn-any",
"env_logger",
@ -2396,10 +2390,11 @@ dependencies = [
[[package]]
name = "hyper-rustls"
version = "0.24.0"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7"
checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97"
dependencies = [
"futures-util",
"http",
"hyper",
"rustls",
@ -2522,6 +2517,12 @@ dependencies = [
"hashbrown 0.14.0",
]
[[package]]
name = "indoc"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "761cde40c27e2a9877f8c928fd248b7eec9dd48623dd514b256858ca593fbba7"
[[package]]
name = "infer"
version = "0.12.0"
@ -2580,6 +2581,15 @@ version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "0.4.8"
@ -2697,7 +2707,7 @@ dependencies = [
[[package]]
name = "kurbo"
version = "0.9.5"
source = "git+https://github.com/linebender/kurbo.git#68a8ff6ee387f5a38ab06be7184675317a95a961"
source = "git+https://github.com/linebender/kurbo.git#b22ba21c63cf455dbe22a75df7151caefbe7b501"
dependencies = [
"arrayvec",
"serde",
@ -2810,7 +2820,7 @@ dependencies = [
"dirs-next",
"objc-foundation",
"objc_id",
"time 0.3.22",
"time 0.3.23",
]
[[package]]
@ -2842,7 +2852,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
dependencies = [
"regex-automata",
"regex-automata 0.1.10",
]
[[package]]
@ -2959,9 +2969,9 @@ dependencies = [
[[package]]
name = "naga"
version = "0.12.2"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80cd00bd6180a8790f1c020ed258a46b8d73dd5bd6af104a238c9d71f806938e"
checksum = "bbcc2e0513220fd2b598e6068608d4462db20322c0e77e47f6f488dfcfc279cb"
dependencies = [
"bit-set",
"bitflags 1.3.2",
@ -3185,9 +3195,9 @@ dependencies = [
[[package]]
name = "num"
version = "0.4.0"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606"
checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
dependencies = [
"num-bigint",
"num-complex",
@ -3321,7 +3331,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -3455,7 +3465,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -3528,7 +3538,7 @@ version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "706de7e2214113d63a8238d1910463cfce781129a6f263d13fdb09ff64355ba4"
dependencies = [
"ttf-parser 0.19.1",
"ttf-parser",
]
[[package]]
@ -3728,7 +3738,7 @@ checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -3751,16 +3761,16 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "plist"
version = "1.4.3"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bd9647b268a3d3e14ff09c23201133a62589c658db02bb7388c7246aafe0590"
checksum = "bdc0001cfea3db57a2e24bc0d818e9e20e554b5f97fabb9bc231dc240269ae06"
dependencies = [
"base64 0.21.2",
"indexmap 1.9.3",
"line-wrap",
"quick-xml 0.28.2",
"quick-xml 0.29.0",
"serde",
"time 0.3.22",
"time 0.3.23",
]
[[package]]
@ -3846,9 +3856,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]]
name = "proc-macro2"
version = "1.0.63"
version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da"
dependencies = [
"unicode-ident",
]
@ -3870,9 +3880,9 @@ dependencies = [
[[package]]
name = "quick-xml"
version = "0.28.2"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce5e73202a820a31f8a0ee32ada5e21029c81fd9e3ebf668a40832e4219d9d1"
checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51"
dependencies = [
"memchr",
]
@ -4050,13 +4060,14 @@ dependencies = [
[[package]]
name = "regex"
version = "1.8.4"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
dependencies = [
"aho-corasick 1.0.2",
"aho-corasick",
"memchr",
"regex-syntax 0.7.2",
"regex-automata 0.3.3",
"regex-syntax 0.7.4",
]
[[package]]
@ -4068,6 +4079,17 @@ dependencies = [
"regex-syntax 0.6.29",
]
[[package]]
name = "regex-automata"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.7.4",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
@ -4076,19 +4098,19 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.7.2"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
[[package]]
name = "remain"
version = "0.2.9"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a7353bbc5701e3ea03298c88c3d087c23798589a351e3b42819d5e5fadc91bf"
checksum = "0a1f84d591f6fbf50b971a9d139407b21042e694de27acf741d21b85dc986142"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -4214,9 +4236,9 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.37.22"
version = "0.37.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c"
checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06"
dependencies = [
"bitflags 1.3.2",
"errno",
@ -4228,9 +4250,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.21.2"
version = "0.21.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f"
checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36"
dependencies = [
"log",
"ring",
@ -4249,9 +4271,9 @@ dependencies = [
[[package]]
name = "rustls-webpki"
version = "0.100.1"
version = "0.101.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b"
checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e"
dependencies = [
"ring",
"untrusted",
@ -4265,14 +4287,14 @@ checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f"
[[package]]
name = "rustybuzz"
version = "0.6.0"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab9e34ecf6900625412355a61bda0bd68099fe674de707c67e5e4aed2c05e489"
checksum = "82eea22c8f56965eeaf3a209b3d24508256c7b920fb3b6211b8ba0f7c0583250"
dependencies = [
"bitflags 1.3.2",
"bytemuck",
"smallvec",
"ttf-parser 0.17.1",
"ttf-parser",
"unicode-bidi-mirroring",
"unicode-ccc",
"unicode-general-category",
@ -4407,9 +4429,9 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.166"
version = "1.0.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8"
checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9"
dependencies = [
"serde_derive",
]
@ -4438,20 +4460,20 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.166"
version = "1.0.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6"
checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
name = "serde_json"
version = "1.0.99"
version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
checksum = "b5062a995d481b2308b6064e9af76011f2921c35f97b0468811ed9f6cd91dfed"
dependencies = [
"itoa 1.0.8",
"ryu",
@ -4460,9 +4482,9 @@ dependencies = [
[[package]]
name = "serde_path_to_error"
version = "0.1.12"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b1b6471d7496b051e03f1958802a73f88b947866f5146f329e47e36554f4e55"
checksum = "8acc4422959dd87a76cb117c191dcbffc20467f06c9100b76721dab370f24d3a"
dependencies = [
"itoa 1.0.8",
"serde",
@ -4470,13 +4492,13 @@ dependencies = [
[[package]]
name = "serde_repr"
version = "0.1.13"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f0a21fba416426ac927b1691996e82079f8b6156e920c85345f135b2e9ba2de"
checksum = "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -4513,7 +4535,7 @@ dependencies = [
"serde",
"serde_json",
"serde_with_macros",
"time 0.3.22",
"time 0.3.23",
]
[[package]]
@ -4525,7 +4547,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -4603,9 +4625,9 @@ dependencies = [
[[package]]
name = "signal-hook"
version = "0.3.15"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9"
checksum = "b824b6e687aff278cdbf3b36f07aa52d4bd4099699324d5da86a2ebce3aa00b3"
dependencies = [
"libc",
"signal-hook-registry",
@ -4681,7 +4703,7 @@ dependencies = [
"serde",
"serde_json",
"slog",
"time 0.3.22",
"time 0.3.23",
]
[[package]]
@ -4694,7 +4716,7 @@ dependencies = [
"slog",
"term",
"thread_local",
"time 0.3.22",
"time 0.3.23",
]
[[package]]
@ -4708,9 +4730,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.10.0"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]]
name = "smithay-client-toolkit"
@ -4771,24 +4793,27 @@ dependencies = [
[[package]]
name = "specta"
version = "0.0.6"
source = "git+https://github.com/oscartbeaumont/rspc?rev=9725ddbfe40183debc055b88c37910eb6f818eae#9725ddbfe40183debc055b88c37910eb6f818eae"
version = "1.0.4"
source = "git+https://github.com/0HyperCube/specta.git?rev=d28cd72ea4ea2f6eaa85e0622d3a98340dbb43d3#d28cd72ea4ea2f6eaa85e0622d3a98340dbb43d3"
dependencies = [
"document-features",
"glam",
"indoc",
"once_cell",
"paste",
"serde",
"serde_json",
"specta-macros",
"thiserror",
]
[[package]]
name = "specta-macros"
version = "0.0.6"
source = "git+https://github.com/oscartbeaumont/rspc?rev=9725ddbfe40183debc055b88c37910eb6f818eae#9725ddbfe40183debc055b88c37910eb6f818eae"
version = "1.0.4"
source = "git+https://github.com/0HyperCube/specta.git?rev=d28cd72ea4ea2f6eaa85e0622d3a98340dbb43d3#d28cd72ea4ea2f6eaa85e0622d3a98340dbb43d3"
dependencies = [
"Inflector",
"itertools",
"proc-macro2",
"quote",
"syn 1.0.109",
@ -4822,9 +4847,9 @@ dependencies = [
[[package]]
name = "spirv-std"
version = "0.7.0"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3197bd4c021c2dfc0f9dfb356312c8f7842d972d5545c308ad86422c2e2d3e66"
checksum = "53ad6bf0206aea3e6ac6283cb88ef397239cd2d9276b8f71854d60ac2cf94e0b"
dependencies = [
"bitflags 1.3.2",
"glam",
@ -4835,9 +4860,9 @@ dependencies = [
[[package]]
name = "spirv-std-macros"
version = "0.7.0"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaffad626ab9d3ac61c4b74b5d51cb52f1939a8041d7ac09ec828eb4ad44d72"
checksum = "2058ef7585e7ef31ee7b00bdfee2e6726649d827c71070a50087598405e8b2cf"
dependencies = [
"proc-macro2",
"quote",
@ -4847,9 +4872,9 @@ dependencies = [
[[package]]
name = "spirv-std-types"
version = "0.7.0"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab83875e851bc803c687024d2d950730f350c0073714b95b3a6b1d22e9eac42a"
checksum = "5cce2183deb9e7ada727867823fb8bbbc8b56e503801a332d155dde613130e1b"
[[package]]
name = "stable_deref_trait"
@ -4923,9 +4948,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.23"
version = "2.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737"
checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970"
dependencies = [
"proc-macro2",
"quote",
@ -4973,7 +4998,7 @@ dependencies = [
"cfg-expr 0.15.3",
"heck 0.4.1",
"pkg-config",
"toml 0.7.5",
"toml 0.7.6",
"version-compare 0.1.1",
]
@ -5043,9 +5068,9 @@ dependencies = [
[[package]]
name = "tar"
version = "0.4.38"
version = "0.4.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6"
checksum = "ec96d2ffad078296368d46ff1cb309be1c23c513b4ab0e22a45de0185275ac96"
dependencies = [
"filetime",
"libc",
@ -5054,9 +5079,9 @@ dependencies = [
[[package]]
name = "target-lexicon"
version = "0.12.8"
version = "0.12.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1c7f239eb94671427157bd93b3694320f3668d4e1eff08c7285366fd777fac"
checksum = "df8e77cb757a61f51b947ec4a7e3646efd825b73561db1c232a8ccb639e611a0"
[[package]]
name = "tauri"
@ -5151,7 +5176,7 @@ dependencies = [
"sha2",
"tauri-utils",
"thiserror",
"time 0.3.22",
"time 0.3.23",
"uuid",
"walkdir",
]
@ -5247,7 +5272,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5993dc129e544393574288923d1ec447c857f3f644187f4fbf7d9a875fbfc4fb"
dependencies = [
"embed-resource",
"toml 0.7.5",
"toml 0.7.6",
]
[[package]]
@ -5335,22 +5360,22 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
[[package]]
name = "thiserror"
version = "1.0.40"
version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.40"
version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -5376,9 +5401,9 @@ dependencies = [
[[package]]
name = "time"
version = "0.3.22"
version = "0.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd"
checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446"
dependencies = [
"itoa 1.0.8",
"libc",
@ -5396,9 +5421,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
[[package]]
name = "time-macros"
version = "0.2.9"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b"
checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4"
dependencies = [
"time-core",
]
@ -5471,7 +5496,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -5519,9 +5544,9 @@ dependencies = [
[[package]]
name = "toml"
version = "0.7.5"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240"
checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542"
dependencies = [
"serde",
"serde_spanned",
@ -5540,9 +5565,9 @@ dependencies = [
[[package]]
name = "toml_edit"
version = "0.19.11"
version = "0.19.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7"
checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
dependencies = [
"indexmap 2.0.0",
"serde",
@ -5618,7 +5643,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
]
[[package]]
@ -5675,12 +5700,6 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
[[package]]
name = "ttf-parser"
version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "375812fa44dab6df41c195cd2f7fecb488f6c09fbaafb62807488cefab642bff"
[[package]]
name = "ttf-parser"
version = "0.19.1"
@ -5735,9 +5754,9 @@ checksum = "2281c8c1d221438e373249e065ca4989c4c36952c211ff21a0ee91c44a3869e7"
[[package]]
name = "unicode-ident"
version = "1.0.10"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "unicode-normalization"
@ -5875,7 +5894,7 @@ name = "vulkan-executor"
version = "0.1.0"
dependencies = [
"anyhow",
"base64 0.13.1",
"base64 0.21.2",
"bytemuck",
"dyn-any",
"glam",
@ -5977,7 +5996,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
"wasm-bindgen-shared",
]
@ -6011,7 +6030,7 @@ checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.26",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -6261,9 +6280,9 @@ dependencies = [
[[package]]
name = "wgpu"
version = "0.16.1"
version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3059ea4ddec41ca14f356833e2af65e7e38c0a8f91273867ed526fb9bafcca95"
checksum = "8aa4361a426ff9f028520da01e8fda28ab9bdb029e2a76901f1f88317e2796e9"
dependencies = [
"arrayvec",
"cfg-if",
@ -6311,7 +6330,7 @@ name = "wgpu-executor"
version = "0.1.0"
dependencies = [
"anyhow",
"base64 0.13.1",
"base64 0.21.2",
"bytemuck",
"dyn-any",
"future-executor",
@ -6333,9 +6352,9 @@ dependencies = [
[[package]]
name = "wgpu-hal"
version = "0.16.1"
version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74851c2c8e5d97652e74c241d41b0656b31c924a45dcdecde83975717362cfa4"
checksum = "1ecb3258078e936deee14fd4e0febe1cfe9bbb5ffef165cb60218d2ee5eb4448"
dependencies = [
"android_system_properties",
"arrayvec",
@ -6375,9 +6394,9 @@ dependencies = [
[[package]]
name = "wgpu-types"
version = "0.16.0"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bd33a976130f03dcdcd39b3810c0c3fc05daf86f0aaf867db14bfb7c4a9a32b"
checksum = "d0c153280bb108c2979eb5c7391cb18c56642dd3c072e55f52065e13e2a1252a"
dependencies = [
"bitflags 2.3.3",
"js-sys",
@ -6386,9 +6405,9 @@ dependencies = [
[[package]]
name = "wide"
version = "0.7.10"
version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40018623e2dba2602a9790faba8d33f2ebdebf4b86561b83928db735f8784728"
checksum = "aa469ffa65ef7e0ba0f164183697b89b854253fd31aeb92358b7b6155177d62f"
dependencies = [
"bytemuck",
"safe_arch",
@ -6752,9 +6771,9 @@ dependencies = [
[[package]]
name = "winnow"
version = "0.4.7"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448"
checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7"
dependencies = [
"memchr",
]

View file

@ -28,10 +28,10 @@ resolver = "2"
exclude = ["node-graph/gpu-compiler"]
[workspace.dependencies]
specta = { git = "https://github.com/oscartbeaumont/rspc", rev = "9725ddbfe40183debc055b88c37910eb6f818eae", features = [
specta = { git = "https://github.com/0HyperCube/specta.git", rev = "d28cd72ea4ea2f6eaa85e0622d3a98340dbb43d3", features = [
"glam",
] }
xxhash-rust = { version = "0.8.4", features = ["xxh3"] }
xxhash-rust = { version = "0.8", features = ["xxh3"] }
[profile.dev.package.graphite-editor]
opt-level = 1

View file

@ -24,6 +24,6 @@ kurbo = { git = "https://github.com/linebender/kurbo.git", features = [
] }
specta.workspace = true
serde = { version = "1.0", features = ["derive"] }
base64 = "0.13"
glam = { version = "0.22", features = ["serde"] }
rustybuzz = "0.6.0"
base64 = "0.21"
glam = { version = "0.24", features = ["serde"] }
rustybuzz = "0.8"

View file

@ -403,7 +403,7 @@ impl Document {
}
pub fn mark_downstream_as_dirty(&mut self, path: &[LayerId]) -> Result<(), DocumentError> {
let mut layer = self.layer_mut(path)?;
let layer = self.layer_mut(path)?;
layer.cache_dirty = true;
let mut path = path.to_vec();
@ -739,7 +739,9 @@ impl Document {
let mut old_to_new_layer_id: HashMap<LayerId, LayerId> = HashMap::new();
for (i, duplicate_layer) in duplicated_layers.into_iter().enumerate() {
let Some(old_layer_id) = duplicate_layer.last().cloned() else { continue; };
let Some(old_layer_id) = duplicate_layer.last().cloned() else {
continue;
};
// Iterate through each ID of the current duplicate layer
// If the dictionary contains the ID, we know the duplicate folder has been created already. Use the existing layer ID instead of creating a new one
@ -922,7 +924,7 @@ impl Document {
}
Operation::SetLayerName { path, name } => {
self.mark_as_dirty(&path)?;
let mut layer = self.layer_mut(&path)?;
let layer = self.layer_mut(&path)?;
layer.name = if name.as_str() == "" { None } else { Some(name) };
Some(vec![LayerChanged { path }])

View file

@ -1,12 +1,13 @@
//! Basic wrapper for [`serde`] for [`base64`] encoding
use base64::Engine;
use serde::{Deserialize, Deserializer, Serializer};
pub fn as_base64<S>(key: &std::sync::Arc<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&base64::encode(key.as_slice()))
serializer.serialize_str(&base64::engine::general_purpose::STANDARD.encode(key.as_slice()))
}
pub fn from_base64<'a, D>(deserializer: D) -> Result<std::sync::Arc<Vec<u8>>, D::Error>
@ -16,7 +17,7 @@ where
use serde::de::Error;
String::deserialize(deserializer)
.and_then(|string| base64::decode(string).map_err(|err| Error::custom(err.to_string())))
.and_then(|string| base64::engine::general_purpose::STANDARD.decode(string).map_err(|err| Error::custom(err.to_string())))
.map(std::sync::Arc::new)
.map_err(serde::de::Error::custom)
}

View file

@ -21,13 +21,13 @@ wasm = ["wasm-bindgen", "future-executor", "graphene-std/wasm"]
[dependencies]
log = "0.4"
bitflags = "1.2.1"
thiserror = "1.0.24"
bitflags = { version = "2.3", features = ["serde"] }
thiserror = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0" }
graphite-proc-macros = { path = "../proc-macros" }
bezier-rs = { path = "../libraries/bezier-rs" }
glam = { version = "0.22", features = ["serde"] }
glam = { version = "0.24", features = ["serde"] }
kurbo = { git = "https://github.com/linebender/kurbo.git", features = [
"serde",
] }

View file

@ -534,15 +534,15 @@ mod test {
editor.handle_message(DocumentMessage::SelectedLayersRaise);
let (all, non_selected, selected) = verify_order(editor.dispatcher.message_handlers.portfolio_message_handler.active_document_mut().unwrap());
assert_eq!(all, non_selected.into_iter().chain(selected.into_iter()).collect::<Vec<_>>());
assert_eq!(all, non_selected.into_iter().chain(selected).collect::<Vec<_>>());
editor.handle_message(DocumentMessage::SelectedLayersLower);
let (all, non_selected, selected) = verify_order(editor.dispatcher.message_handlers.portfolio_message_handler.active_document_mut().unwrap());
assert_eq!(all, selected.into_iter().chain(non_selected.into_iter()).collect::<Vec<_>>());
assert_eq!(all, selected.into_iter().chain(non_selected).collect::<Vec<_>>());
editor.handle_message(DocumentMessage::SelectedLayersRaiseToFront);
let (all, non_selected, selected) = verify_order(editor.dispatcher.message_handlers.portfolio_message_handler.active_document_mut().unwrap());
assert_eq!(all, non_selected.into_iter().chain(selected.into_iter()).collect::<Vec<_>>());
assert_eq!(all, non_selected.into_iter().chain(selected).collect::<Vec<_>>());
}
#[test]

View file

@ -7,28 +7,29 @@ fn generate_ts_types() {
use crate::messages::prelude::FrontendMessage;
use specta::{
ts::{export_datatype, BigIntExportBehavior, ExportConfiguration},
DefOpts, Type, TypeDefs,
DefOpts, NamedType, Type, TypeDefs,
};
use std::fs::File;
use std::io::Write;
let config = ExportConfiguration {
bigint: BigIntExportBehavior::Number,
..Default::default()
};
let config = ExportConfiguration::new().bigint(BigIntExportBehavior::Number);
let mut type_map = TypeDefs::new();
let datatype = FrontendMessage::definition(DefOpts {
parent_inline: false,
type_map: &mut type_map,
});
let datatype = FrontendMessage::named_data_type(
DefOpts {
parent_inline: false,
type_map: &mut type_map,
},
&FrontendMessage::definition_generics().into_iter().map(Into::into).collect::<Vec<_>>(),
)
.unwrap();
let mut export = String::new();
export += &export_datatype(&config, &datatype).unwrap();
type_map.values().flat_map(|v| export_datatype(&config, v)).for_each(|e| export += &format!("\n\n{e}"));
type_map.values().flatten().flat_map(|v| export_datatype(&config, v)).for_each(|e| export += &format!("\n\n{e}"));
let mut file = File::create("../types.ts").unwrap();

View file

@ -33,8 +33,9 @@ pub enum KeyPosition {
}
bitflags! {
#[derive(Default, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, Serialize, Deserialize)]
#[repr(transparent)]
#[serde(transparent)]
pub struct ModifierKeys: u8 {
const SHIFT = 0b_0000_0001;
const ALT = 0b_0000_0010;

View file

@ -138,12 +138,11 @@ impl EditorMouseState {
}
bitflags! {
#[derive(Default, Serialize, Deserialize)]
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[repr(transparent)]
pub struct MouseKeys: u8 {
const LEFT = 0b0000_0001;
const RIGHT = 0b0000_0010;
const MIDDLE = 0b0000_0100;
const NONE = 0b0000_0000;
}
}

View file

@ -116,7 +116,7 @@ impl InputPreprocessorMessageHandler {
let old_down = self.mouse.mouse_keys & bit_flag == bit_flag;
let new_down = new_state.mouse_keys & bit_flag == bit_flag;
if !old_down && new_down {
if allow_first_button_down || self.mouse.mouse_keys != MouseKeys::NONE {
if allow_first_button_down || self.mouse.mouse_keys != MouseKeys::empty() {
responses.add(InputMapperMessage::KeyDown(key));
} else {
// Required to stop a keyup being emitted for a keydown outside canvas

View file

@ -221,7 +221,7 @@ impl WidgetLayout {
return;
}
// Diff all of the children
for (index, (current_child, new_child)) in self.layout.iter_mut().zip(new.layout.into_iter()).enumerate() {
for (index, (current_child, new_child)) in self.layout.iter_mut().zip(new.layout).enumerate() {
widget_path.push(index);
current_child.diff(new_child, widget_path, widget_diffs);
widget_path.pop();
@ -394,7 +394,7 @@ impl LayoutGroup {
return;
}
// Diff all of the children
for (index, (current_child, new_child)) in current_widgets.iter_mut().zip(new_widgets.into_iter()).enumerate() {
for (index, (current_child, new_child)) in current_widgets.iter_mut().zip(new_widgets).enumerate() {
widget_path.push(index);
current_child.diff(new_child, widget_path, widget_diffs);
widget_path.pop();
@ -421,7 +421,7 @@ impl LayoutGroup {
return;
}
// Diff all of the children
for (index, (current_child, new_child)) in current_layout.iter_mut().zip(new_layout.into_iter()).enumerate() {
for (index, (current_child, new_child)) in current_layout.iter_mut().zip(new_layout).enumerate() {
widget_path.push(index);
current_child.diff(new_child, widget_path, widget_diffs);
widget_path.pop();

View file

@ -58,7 +58,7 @@ pub struct PopoverButton {
#[derive(Clone, Serialize, Deserialize, Derivative, Default, WidgetBuilder, specta::Type)]
#[derivative(Debug, PartialEq)]
#[serde(rename_all(serialize = "camelCase", deserialize = "camelCase"))]
#[serde(rename_all = "camelCase")]
pub struct ParameterExposeButton {
pub exposed: bool,
@ -78,7 +78,7 @@ pub struct ParameterExposeButton {
#[derive(Clone, Serialize, Deserialize, Derivative, Default, WidgetBuilder, specta::Type)]
#[derivative(Debug, PartialEq)]
#[serde(rename_all(serialize = "camelCase", deserialize = "camelCase"))]
#[serde(rename_all = "camelCase")]
pub struct TextButton {
#[widget_builder(constructor)]
pub label: String,
@ -105,7 +105,7 @@ pub struct TextButton {
#[derive(Clone, Serialize, Deserialize, Derivative, Default, WidgetBuilder, specta::Type)]
#[derivative(Debug, PartialEq)]
#[serde(rename_all(serialize = "camelCase", deserialize = "camelCase"))]
#[serde(rename_all = "camelCase")]
pub struct BreadcrumbTrailButtons {
#[widget_builder(constructor)]
pub labels: Vec<String>,

View file

@ -202,13 +202,15 @@ impl<'a> ModifyInputsContext<'a> {
let NodeInput::Value {
tagged_value: TaggedValue::Subpaths(subpaths),
..
} = subpaths else {
} = subpaths
else {
return;
};
let NodeInput::Value {
tagged_value: TaggedValue::ManipulatorGroupIds(mirror_angle_groups),
..
} = mirror_angle_groups else {
} = mirror_angle_groups
else {
return;
};

View file

@ -375,7 +375,7 @@ impl NodeGraphMessageHandler {
continue;
}
for (input_index, input) in node.inputs.iter_mut().enumerate() {
let NodeInput::Node{ node_id, .. } = input else {
let NodeInput::Node { node_id, .. } = input else {
continue;
};
if *node_id != deleting_node_id {
@ -383,9 +383,9 @@ impl NodeGraphMessageHandler {
}
let Some(node_type) = document_node_types::resolve_document_node_type(&node.name) else {
warn!("Removing input of invalid node type '{}'", node.name);
return false;
};
warn!("Removing input of invalid node type '{}'", node.name);
return false;
};
if let NodeInput::Value { tagged_value, .. } = &node_type.inputs[input_index].default {
*input = NodeInput::value(tagged_value.clone(), true);
}
@ -444,12 +444,12 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &NodeGraphExecutor, u64)>
let Some(network) = self.get_active_network(document) else {
error!("No network");
return;
};
};
let Some(input_node) = network.nodes.get(&input_node) else {
error!("No to");
return;
};
let Some((input_index, _)) = input_node.inputs.iter().enumerate().filter(|input|input.1.is_exposed()).nth(input_node_connector_index) else {
let Some((input_index, _)) = input_node.inputs.iter().enumerate().filter(|input| input.1.is_exposed()).nth(input_node_connector_index) else {
error!("Failed to find actual index of connector index {input_node_connector_index} on node {input_node:#?}");
return;
};
@ -482,7 +482,10 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &NodeGraphExecutor, u64)>
let node_id = node_id.unwrap_or_else(crate::application::generate_uuid);
let Some(document_node_type) = document_node_types::resolve_document_node_type(&node_type) else {
responses.add(DialogMessage::DisplayDialogError { title: "Cannot insert node".to_string(), description: format!("The document node '{node_type}' does not exist in the document node list") });
responses.add(DialogMessage::DisplayDialogError {
title: "Cannot insert node".to_string(),
description: format!("The document node '{node_type}' does not exist in the document node list"),
});
return;
};

View file

@ -1051,7 +1051,11 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
LayoutGroup::Row { widgets }.with_tooltip("Connection status to the server that computes generated images")
};
let &NodeInput::Value {tagged_value: TaggedValue::ImaginateController(ref controller),..} = controller else {
let &NodeInput::Value {
tagged_value: TaggedValue::ImaginateController(ref controller),
..
} = controller
else {
panic!("Invalid output status input")
};
let imaginate_status = controller.get_status();
@ -1085,7 +1089,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
})
};
let image_controls: _ = {
let image_controls = {
let mut widgets = vec![WidgetHolder::text_widget("Image"), WidgetHolder::unrelated_separator()];
let assist_separators = [
WidgetHolder::unrelated_separator(), // TODO: These three separators add up to 24px,

View file

@ -98,12 +98,8 @@ pub fn register_artboard_layer_properties(layer: &Layer, responses: &mut VecDequ
}];
let properties_body = {
let LayerDataType::Shape(shape) = &layer.data else {
panic!("Artboards can only be shapes")
};
let Fill::Solid(color) = shape.style.fill() else {
panic!("Artboard must have a solid fill")
};
let LayerDataType::Shape(shape) = &layer.data else { panic!("Artboards can only be shapes") };
let Fill::Solid(color) = shape.style.fill() else { panic!("Artboard must have a solid fill") };
let render_data = RenderData::new(&persistent_data.font_cache, ViewMode::default(), None);
let pivot = layer.transform.transform_vector2(layer.layerspace_pivot(&render_data));

View file

@ -21,5 +21,5 @@ where
V: Deserialize<'de>,
{
let container: Vec<_> = serde::Deserialize::deserialize(deserializer)?;
Ok(T::from_iter(container.into_iter()))
Ok(T::from_iter(container))
}

View file

@ -644,7 +644,11 @@ impl PortfolioMessageHandler {
}))),
LayerDataType::Layer(layer) => {
let input_is_font = |input: &NodeInput| {
let NodeInput::Value { tagged_value: TaggedValue::Font(font), .. } = input else {
let NodeInput::Value {
tagged_value: TaggedValue::Font(font),
..
} = input
else {
return false;
};
font == target_font

View file

@ -152,7 +152,7 @@ impl OverlayRenderer {
let Some(manipulator_groups) = self.manipulator_group_overlay_cache.get(layer_id) else { return };
if visibility {
let Ok(layer) = document.layer(&layer_path) else { return };
let Some(vector_data) = layer.as_vector_data() else { return };
let Some(vector_data) = layer.as_vector_data() else { return };
for manipulator_group in vector_data.manipulator_groups() {
let id = manipulator_group.id;
if let Some(manipulator_group_overlays) = manipulator_groups.get(&id) {

View file

@ -194,7 +194,9 @@ impl ShapeState {
}
if mirror {
let Some(mut original_handle_position) = point.manipulator_type.get_position(group) else { continue };
let Some(mut original_handle_position) = point.manipulator_type.get_position(group) else {
continue;
};
original_handle_position += delta;
let point = ManipulatorPointId::new(point.group, point.manipulator_type.opposite());
@ -318,7 +320,9 @@ impl ShapeState {
continue;
}
let Some(opposing_handle_length) = opposing_handle_lengths.get(&manipulator_group.id) else { continue };
let Some(opposing_handle_length) = opposing_handle_lengths.get(&manipulator_group.id) else {
continue;
};
let in_handle_selected = state.is_selected(ManipulatorPointId::new(manipulator_group.id, SelectedType::InHandle));
let out_handle_selected = state.is_selected(ManipulatorPointId::new(manipulator_group.id, SelectedType::OutHandle));
@ -344,7 +348,9 @@ impl ShapeState {
continue;
};
let Some(opposing_handle) = single_selected_handle.opposite().get_position(manipulator_group) else { continue };
let Some(opposing_handle) = single_selected_handle.opposite().get_position(manipulator_group) else {
continue;
};
let Some(offset) = (opposing_handle - manipulator_group.anchor).try_normalize() else { continue };
@ -627,14 +633,14 @@ impl ShapeState {
state.clear_points()
}
let Ok(layer) = document.layer(&layer_path) else {continue};
let Some(vector_data) = layer.as_vector_data() else {continue};
let Ok(layer) = document.layer(layer_path) else { continue };
let Some(vector_data) = layer.as_vector_data() else { continue };
let transform = document.multiply_transforms(layer_path).unwrap_or_default();
for manipulator_group in vector_data.manipulator_groups() {
for selected_type in [SelectedType::Anchor, SelectedType::InHandle, SelectedType::OutHandle] {
let Some(position) = selected_type.get_position(manipulator_group) else {continue};
let Some(position) = selected_type.get_position(manipulator_group) else { continue };
let transformed_position = transform.transform_point2(position);
if quad[0].min(quad[1]).cmple(transformed_position).all() && quad[0].max(quad[1]).cmpge(transformed_position).all() {

View file

@ -315,7 +315,11 @@ impl BrushToolData {
for (node, _node_id) in network.primary_flow() {
if node.name == "Brush" {
let points_input = node.inputs.get(2)?;
let NodeInput::Value { tagged_value: TaggedValue::BrushStrokes(strokes), .. } = points_input else {
let NodeInput::Value {
tagged_value: TaggedValue::BrushStrokes(strokes),
..
} = points_input
else {
continue;
};
self.strokes = strokes.clone();

View file

@ -210,7 +210,7 @@ impl Fsm for EllipseToolFsmState {
use EllipseToolFsmState::*;
use EllipseToolMessage::*;
let mut shape_data = &mut tool_data.data;
let shape_data = &mut tool_data.data;
if let ToolMessage::Ellipse(event) = event {
match (self, event) {

View file

@ -114,7 +114,7 @@ impl Fsm for NodeGraphToolFsmState {
use FrameToolMessage::*;
use NodeGraphToolFsmState::*;
let mut shape_data = &mut tool_data.data;
let shape_data = &mut tool_data.data;
if let ToolMessage::Frame(event) = event {
match (self, event) {

View file

@ -289,7 +289,7 @@ impl SelectedGradient {
inner_gradient.transform = gradient_space_transform(&inner_gradient.path, layer, document, render_data);
// Clear if no longer a gradient
let Some(gradient) = layer.style().ok().and_then(|style|style.fill().as_gradient()) else {
let Some(gradient) = layer.style().ok().and_then(|style| style.fill().as_gradient()) else {
responses.add(ToolMessage::RefreshToolOptions);
*gradient = None;
return;

View file

@ -114,7 +114,7 @@ impl Fsm for ImaginateToolFsmState {
use ImaginateToolFsmState::*;
use ImaginateToolMessage::*;
let mut shape_data = &mut tool_data.data;
let shape_data = &mut tool_data.data;
if let ToolMessage::Imaginate(event) = event {
match (self, event) {

View file

@ -351,7 +351,7 @@ impl Fsm for PathToolFsmState {
}
.into(),
));
return PathToolFsmState::Ready;
PathToolFsmState::Ready
}
(_, PathToolMessage::DragStop { shift_mirror_distance }) => {
let shift_pressed = input.keyboard.get(shift_mirror_distance as usize);

View file

@ -232,7 +232,9 @@ impl PenToolData {
// Stop the handles on the first point from mirroring
let Some(subpaths) = get_subpaths(layer, document) else { return };
let manipulator_groups = subpaths[subpath_index].manipulator_groups();
let Some(last_handle) = (if from_start { manipulator_groups.first() } else { manipulator_groups.last() }) else { return };
let Some(last_handle) = (if from_start { manipulator_groups.first() } else { manipulator_groups.last() }) else {
return;
};
responses.add(GraphOperationMessage::Vector {
layer: layer.to_vec(),
@ -765,7 +767,9 @@ fn should_extend(document: &DocumentMessageHandler, pos: DVec2, tolerance: f64)
let mut best_distance_squared = tolerance * tolerance;
for layer_path in document.selected_layers() {
let Ok(viewspace) = document.document_legacy.generate_transform_relative_to_viewport(layer_path) else { continue };
let Ok(viewspace) = document.document_legacy.generate_transform_relative_to_viewport(layer_path) else {
continue;
};
let subpaths = get_subpaths(layer_path, document)?;
for (subpath_index, subpath) in subpaths.iter().enumerate() {
@ -795,7 +799,11 @@ fn get_subpaths<'a>(layer_path: &[LayerId], document: &'a DocumentMessageHandler
for (node, _node_id) in network.primary_flow() {
if node.name == "Path Generator" {
let subpaths_input = node.inputs.get(0)?;
let NodeInput::Value { tagged_value: TaggedValue::Subpaths(subpaths), .. } = subpaths_input else {
let NodeInput::Value {
tagged_value: TaggedValue::Subpaths(subpaths),
..
} = subpaths_input
else {
continue;
};

View file

@ -209,7 +209,7 @@ impl Fsm for RectangleToolFsmState {
use RectangleToolFsmState::*;
use RectangleToolMessage::*;
let mut shape_data = &mut tool_data.data;
let shape_data = &mut tool_data.data;
if let ToolMessage::Rectangle(event) = event {
match (self, event) {

View file

@ -503,7 +503,7 @@ impl Fsm for SelectToolFsmState {
tool_data.drag_start = input.mouse.position;
tool_data.drag_current = input.mouse.position;
let dragging_bounds = tool_data.bounding_box_overlays.as_mut().and_then(|mut bounding_box| {
let dragging_bounds = tool_data.bounding_box_overlays.as_mut().and_then(|bounding_box| {
let edges = bounding_box.check_selected_edges(input.mouse.position);
bounding_box.selected_edges = edges.map(|(top, bottom, left, right)| {

View file

@ -250,7 +250,7 @@ impl Fsm for ShapeToolFsmState {
use ShapeToolFsmState::*;
use ShapeToolMessage::*;
let mut shape_data = &mut tool_data.data;
let shape_data = &mut tool_data.data;
if let ToolMessage::Shape(event) = event {
match (self, event) {

View file

@ -299,9 +299,27 @@ impl TextToolData {
}
fn extract_text_node_inputs(node: &DocumentNode) -> Option<(&String, &Font, f64)> {
let NodeInput::Value { tagged_value: TaggedValue::String(text), .. } = &node.inputs[1] else { return None; };
let NodeInput::Value { tagged_value: TaggedValue::Font(font), .. } = &node.inputs[2] else { return None; };
let NodeInput::Value { tagged_value: TaggedValue::F64(font_size), .. } = &node.inputs[3] else { return None; };
let NodeInput::Value {
tagged_value: TaggedValue::String(text),
..
} = &node.inputs[1]
else {
return None;
};
let NodeInput::Value {
tagged_value: TaggedValue::Font(font),
..
} = &node.inputs[2]
else {
return None;
};
let NodeInput::Value {
tagged_value: TaggedValue::F64(font_size),
..
} = &node.inputs[3]
else {
return None;
};
Some((text, font, *font_size))
}
@ -456,7 +474,9 @@ fn get_text_node_id(network: &NodeNetwork) -> Option<NodeId> {
}
fn is_text_layer(document: &DocumentMessageHandler, layer_path: &[LayerId]) -> bool {
let Some(network) = get_network(layer_path, document) else { return false; };
let Some(network) = get_network(layer_path, document) else {
return false;
};
get_text_node_id(network).is_some()
}

View file

@ -157,7 +157,7 @@ impl NodeRuntime {
let editor_api = WasmEditorApi {
font_cache: &self.font_cache,
image_frame,
application_io: &self.wasm_io.as_ref().unwrap(),
application_io: self.wasm_io.as_ref().unwrap(),
node_graph_message_sender: &self.sender,
imaginate_preferences: &self.imaginate_preferences,
};
@ -185,7 +185,9 @@ impl NodeRuntime {
let old_id = self.canvas_cache.insert(path.to_vec(), surface_id);
if let Some(old_id) = old_id {
if old_id != surface_id {
self.wasm_io.as_ref().map(|io| io.destroy_surface(old_id));
if let Some(io) = self.wasm_io.as_ref() {
io.destroy_surface(old_id)
}
}
}
}
@ -338,8 +340,10 @@ impl NodeGraphExecutor {
extract_data: F2,
) -> Option<U> {
let wrapping_document_node = network.nodes.get(node_path.last()?)?;
let DocumentNodeImplementation::Network(wrapped_network) = &wrapping_document_node.implementation else { return None; };
let introspection_node = find_node(&wrapped_network)?;
let DocumentNodeImplementation::Network(wrapped_network) = &wrapping_document_node.implementation else {
return None;
};
let introspection_node = find_node(wrapped_network)?;
let introspection = self.introspect_node(&[node_path, &[introspection_node]].concat())?;
let downcasted: &T = <dyn std::any::Any>::downcast_ref(introspection.as_ref())?;
Some(extract_data(downcasted))

View file

@ -354,7 +354,7 @@
draggingNodes = { startX: e.x, startY: e.y, roundX: 0, roundY: 0 };
}
if (modifiedSelected) editor.instance.selectNodes(new BigUint64Array(selected));
if (modifiedSelected) editor.instance.selectNodes(selected.length > 0 ? new BigUint64Array(selected): null);
return;
}
@ -362,7 +362,7 @@
// Clicked on the graph background
if (lmb && selected.length !== 0) {
selected = [];
editor.instance.selectNodes(new BigUint64Array([]));
editor.instance.selectNodes(null);
}
// LMB clicked on the graph background or MMB clicked anywhere

View file

@ -645,7 +645,8 @@ impl JsEditorHandle {
/// Notifies the backend that the user selected a node in the node graph
#[wasm_bindgen(js_name = selectNodes)]
pub fn select_nodes(&self, nodes: Vec<u64>) {
pub fn select_nodes(&self, nodes: Option<Vec<u64>>) {
let nodes = nodes.unwrap_or_default();
let message = NodeGraphMessage::SelectNodes { nodes };
self.dispatch(message);
}

View file

@ -14,7 +14,7 @@ repository = "https://github.com/GraphiteEditor/Graphite/tree/master/libraries/b
documentation = "https://graphite.rs/libraries/bezier-rs/"
[dependencies]
glam = { version = "0.22", features = ["serde"] }
glam = { version = "0.24", features = ["serde"] }
dyn-any = { version = "0.3.0", path = "../dyn-any", optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }

View file

@ -209,7 +209,7 @@ impl Bezier {
let self_points = self.get_points().collect::<Vec<DVec2>>();
let other_points = other.get_points().collect::<Vec<DVec2>>();
self_points.len() == other_points.len() && self_points.into_iter().zip(other_points.into_iter()).all(|(a, b)| a.abs_diff_eq(b, max_abs_diff))
self_points.len() == other_points.len() && self_points.into_iter().zip(other_points).all(|(a, b)| a.abs_diff_eq(b, max_abs_diff))
}
/// Returns true if the start, end and handles of the Bezier are all at the same location

View file

@ -1010,7 +1010,7 @@ mod tests {
fn test_arcs_cubic() {
let bezier = Bezier::from_cubic_coordinates(30., 30., 30., 80., 60., 80., 60., 140.);
let actual_arcs = bezier.arcs(ArcsOptions::default());
let expected_arcs = vec![
let expected_arcs = [
CircleArc {
center: DVec2::new(122.394877, 30.7777189),
radius: 92.39815,

View file

@ -22,7 +22,7 @@ pub fn compare_points(p1: DVec2, p2: DVec2) -> bool {
/// Compare vectors of points by allowing some maximum absolute difference to account for floating point errors
#[cfg(test)]
pub fn compare_vec_of_points(a: Vec<DVec2>, b: Vec<DVec2>, max_absolute_difference: f64) -> bool {
a.len() == b.len() && a.into_iter().zip(b.into_iter()).all(|(p1, p2)| p1.abs_diff_eq(p2, max_absolute_difference))
a.len() == b.len() && a.into_iter().zip(b).all(|(p1, p2)| p1.abs_diff_eq(p2, max_absolute_difference))
}
/// Compare circle arcs by allowing some maximum absolute difference between values to account for floating point errors

View file

@ -324,7 +324,7 @@ mod tests {
/// Compare vectors of `f64`s with a provided max absolute value difference.
fn f64_compare_vector(vec1: Vec<f64>, vec2: Vec<f64>, max_abs_diff: f64) -> bool {
vec1.len() == vec2.len() && vec1.into_iter().zip(vec2.into_iter()).all(|(a, b)| f64_compare(a, b, max_abs_diff))
vec1.len() == vec2.len() && vec1.into_iter().zip(vec2).all(|(a, b)| f64_compare(a, b, max_abs_diff))
}
#[test]

View file

@ -14,7 +14,7 @@ documentation = "https://docs.rs/dyn-any"
[dependencies]
dyn-any-derive = { path = "derive", version = "0.3.0", optional = true }
log = { version = "0.4", optional = true }
glam = { version = "0.22", optional = true, default-features = false }
glam = { version = "0.24", optional = true, default-features = false }
[features]
derive = ["dyn-any-derive"]

View file

@ -86,7 +86,7 @@ pub fn downcast<'a, V: StaticType + 'a>(i: Box<dyn DynAny<'a> + 'a>) -> Result<B
let type_id = DynAny::type_id(i.as_ref());
if type_id == core::any::TypeId::of::<<V as StaticType>::Static>() {
// SAFETY: caller guarantees that T is the correct type
let ptr = Box::into_raw(i) as *mut dyn DynAny<'a> as *mut V;
let ptr = Box::into_raw(i) as *mut V;
Ok(unsafe { Box::from_raw(ptr) })
} else {
if type_id == core::any::TypeId::of::<&dyn DynAny<'static>>() {

View file

@ -7,13 +7,13 @@ license = "MIT OR Apache-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio = { version = "1.0", features = ["full"] }
axum = "0.6.1"
tokio = { version = "1.29", features = ["full"] }
axum = "0.6.18"
serde_json = "1.0"
graph-craft = { version = "0.1.0", path = "../graph-craft", features = ["serde"] }
gpu-compiler-bin-wrapper = { version = "0.1.0", path = "../gpu-compiler/gpu-compiler-bin-wrapper" }
serde = { version = "1.0", features = ["derive"] }
tempfile = "3.3.0"
anyhow = "1.0.68"
tempfile = "3.6.0"
anyhow = "1.0.72"
futures = "0.3"
tower-http = { version = "0.4.0", features = ["cors"] }
tower-http = { version = "0.4.1", features = ["cors"] }

View file

@ -26,7 +26,7 @@ dyn-any = { path = "../../libraries/dyn-any", features = [
"glam",
], optional = true, default-features = false }
spirv-std = { version = "0.7", optional = true }
spirv-std = { version = "0.8", optional = true }
bytemuck = { version = "1.8", features = ["derive"] }
async-trait = { version = "0.1", optional = true }
serde = { version = "1.0", features = [
@ -40,16 +40,16 @@ kurbo = { git = "https://github.com/linebender/kurbo.git", features = [
"serde",
], optional = true }
spin = "0.9.2"
glam = { version = "^0.22", default-features = false, features = [
glam = { version = "0.24", default-features = false, features = [
"scalar-math",
] }
node-macro = { path = "../node-macro" }
base64 = { version = "0.13", optional = true }
base64 = { version = "0.21", optional = true }
specta.workspace = true
specta.optional = true
once_cell = { version = "1.17.0", default-features = false, optional = true }
rustybuzz = { version = "0.6.0", optional = true }
rustybuzz = { version = "0.8.0", optional = true }
num-derive = { version = "0.3.3" }
num-traits = { version = "0.2.15", default-features = false, features = [

View file

@ -8,7 +8,6 @@ use dyn_any::StaticType;
use dyn_any::StaticTypeSized;
use glam::DAffine2;
use core::any::Any;
use core::future::Future;
use core::hash::{Hash, Hasher};
use core::pin::Pin;
@ -88,6 +87,8 @@ impl<'a, Surface> Drop for SurfaceHandle<'a, Surface> {
}
}*/
pub type ResourceFuture = Pin<Box<dyn Future<Output = Result<Arc<[u8]>, ApplicationError>>>>;
pub trait ApplicationIo {
type Surface;
type Executor;
@ -96,7 +97,7 @@ pub trait ApplicationIo {
fn gpu_executor(&self) -> Option<&Self::Executor> {
None
}
fn load_resource<'a>(&self, url: impl AsRef<str>) -> Result<Pin<Box<dyn Future<Output = Result<Arc<[u8]>, ApplicationError>>>>, ApplicationError>;
fn load_resource(&self, url: impl AsRef<str>) -> Result<ResourceFuture, ApplicationError>;
}
impl<T: ApplicationIo> ApplicationIo for &T {
@ -115,7 +116,7 @@ impl<T: ApplicationIo> ApplicationIo for &T {
(**self).gpu_executor()
}
fn load_resource<'a>(&self, url: impl AsRef<str>) -> Result<Pin<Box<dyn Future<Output = Result<Arc<[u8]>, ApplicationError>>>>, ApplicationError> {
fn load_resource<'a>(&self, url: impl AsRef<str>) -> Result<ResourceFuture, ApplicationError> {
(**self).load_resource(url)
}
}

View file

@ -3,7 +3,6 @@ use crate::Node;
use bytemuck::{Pod, Zeroable};
use dyn_any::{DynAny, StaticType};
use num_traits::CheckedShr;
#[cfg(target_arch = "spirv")]
use spirv_std::num_traits::Float;
@ -85,9 +84,8 @@ fn quantize(value: f32, offset: u32, quantization: Quantization) -> u32 {
let rounded_value = scaled_value.clamp(0., (1 << bits) as f32 - 1.) as u32;
// Shift the quantized value to the appropriate position based on the offset
let shifted_value = rounded_value.checked_shl(32 - bits - offset).unwrap();
shifted_value as u32
rounded_value.checked_shl(32 - bits - offset).unwrap()
}
/*
#[inline(always)]
@ -113,9 +111,8 @@ fn decode(value: u32, offset: u32, quantization: Quantization) -> f32 {
let unpacked_value = shifted_value & ((1 << bits) - 1); // Mask out the unnecessary bits
let normalized_value = unpacked_value as f32 / ((1 << bits) - 1) as f32; // Normalize the value based on the quantization range
let decoded_value = normalized_value - b;
let original_value = decoded_value / a;
original_value
decoded_value / a
}
pub struct QuantizeNode<Quantization> {
@ -174,7 +171,7 @@ mod test {
let color = Color::from_rgbaf32_unchecked(0.5, 0.5, 0.5, 0.5);
let quantized = quantize_color(color, [quant; 4]);
assert_eq!(quantized.0, 0x7f7f7f7f);
let dequantized = dequantize_color(quantized, [quant; 4]);
let _dequantized = dequantize_color(quantized, [quant; 4]);
//assert_eq!(color, dequantized);
}

View file

@ -233,9 +233,9 @@ fn levels_node(color: Color, input_start: f32, input_mid: f32, input_end: f32, o
let color = color.to_gamma_srgb();
// Input Range (Range: 0-1)
let input_shadows = (input_start / 100.) as f32;
let input_midtones = (input_mid / 100.) as f32;
let input_highlights = (input_end / 100.) as f32;
let input_shadows = input_start / 100.;
let input_midtones = input_mid / 100.;
let input_highlights = input_end / 100.;
// Output Range (Range: 0-1)
let output_minimums = output_start / 100.;
@ -289,12 +289,12 @@ pub struct GrayscaleNode<Tint, Reds, Yellows, Greens, Cyans, Blues, Magentas> {
fn grayscale_color_node(color: Color, tint: Color, reds: f32, yellows: f32, greens: f32, cyans: f32, blues: f32, magentas: f32) -> Color {
let color = color.to_gamma_srgb();
let reds = reds as f32 / 100.;
let yellows = yellows as f32 / 100.;
let greens = greens as f32 / 100.;
let cyans = cyans as f32 / 100.;
let blues = blues as f32 / 100.;
let magentas = magentas as f32 / 100.;
let reds = reds / 100.;
let yellows = yellows / 100.;
let greens = greens / 100.;
let cyans = cyans / 100.;
let blues = blues / 100.;
let magentas = magentas / 100.;
let gray_base = color.r().min(color.g()).min(color.b());
@ -406,7 +406,7 @@ pub struct BlendNode<BlendMode, Opacity> {
#[node_macro::node_fn(BlendNode)]
fn blend_node(input: (Color, Color), blend_mode: BlendMode, opacity: f32) -> Color {
blend_colors(input.0, input.1, blend_mode, opacity as f32 / 100.)
blend_colors(input.0, input.1, blend_mode, opacity / 100.)
}
#[inline(always)]
@ -575,15 +575,15 @@ fn channel_mixer_node(
let (r, g, b, a) = color.components();
let color = if monochrome {
let (monochrome_r, monochrome_g, monochrome_b, monochrome_c) = (monochrome_r as f32 / 100., monochrome_g as f32 / 100., monochrome_b as f32 / 100., monochrome_c as f32 / 100.);
let (monochrome_r, monochrome_g, monochrome_b, monochrome_c) = (monochrome_r / 100., monochrome_g / 100., monochrome_b / 100., monochrome_c / 100.);
let gray = (r * monochrome_r + g * monochrome_g + b * monochrome_b + monochrome_c).clamp(0., 1.);
Color::from_rgbaf32_unchecked(gray, gray, gray, a)
} else {
let (red_r, red_g, red_b, red_c) = (red_r as f32 / 100., red_g as f32 / 100., red_b as f32 / 100., red_c as f32 / 100.);
let (green_r, green_g, green_b, green_c) = (green_r as f32 / 100., green_g as f32 / 100., green_b as f32 / 100., green_c as f32 / 100.);
let (blue_r, blue_g, blue_b, blue_c) = (blue_r as f32 / 100., blue_g as f32 / 100., blue_b as f32 / 100., blue_c as f32 / 100.);
let (red_r, red_g, red_b, red_c) = (red_r / 100., red_g / 100., red_b / 100., red_c / 100.);
let (green_r, green_g, green_b, green_c) = (green_r / 100., green_g / 100., green_b / 100., green_c / 100.);
let (blue_r, blue_g, blue_b, blue_c) = (blue_r / 100., blue_g / 100., blue_b / 100., blue_c / 100.);
let red = (r * red_r + g * red_g + b * red_b + red_c).clamp(0., 1.);
let green = (r * green_r + g * green_g + b * green_b + green_c).clamp(0., 1.);
@ -779,7 +779,7 @@ fn selective_color_node(
return acc;
}
let (c, m, y, k) = (c as f32 / 100., m as f32 / 100., y as f32 / 100., k as f32 / 100.);
let (c, m, y, k) = (c / 100., m / 100., y / 100., k / 100.);
let color_parameter_group_scale_factor = match color_parameter_group {
SelectiveColorChoice::Reds | SelectiveColorChoice::Greens | SelectiveColorChoice::Blues => color_parameter_group_scale_factor_rgb,
@ -808,7 +808,7 @@ pub struct OpacityNode<O> {
#[node_macro::node_fn(OpacityNode)]
fn image_opacity(color: Color, opacity_multiplier: f32) -> Color {
let opacity_multiplier = opacity_multiplier as f32 / 100.;
let opacity_multiplier = opacity_multiplier / 100.;
Color::from_rgbaf32_unchecked(color.r(), color.g(), color.b(), color.a() * opacity_multiplier)
}
@ -823,7 +823,7 @@ pub struct PosterizeNode<P> {
fn posterize(color: Color, posterize_value: f32) -> Color {
let color = color.to_gamma_srgb();
let posterize_value = posterize_value as f32;
let posterize_value = posterize_value;
let number_of_areas = posterize_value.recip();
let size_of_areas = (posterize_value - 1.).recip();
let channel = |channel: f32| (channel / number_of_areas).floor() * size_of_areas;
@ -844,11 +844,11 @@ pub struct ExposureNode<Exposure, Offset, GammaCorrection> {
fn exposure(color: Color, exposure: f32, offset: f32, gamma_correction: f32) -> Color {
let adjusted = color
// Exposure
.map_rgb(|c: f32| c * 2_f32.powf(exposure as f32))
.map_rgb(|c: f32| c * 2_f32.powf(exposure))
// Offset
.map_rgb(|c: f32| c + offset as f32)
.map_rgb(|c: f32| c + offset)
// Gamma correction
.gamma(gamma_correction as f32);
.gamma(gamma_correction);
adjusted.map_rgb(|c: f32| c.clamp(0., 1.))
}

View file

@ -256,15 +256,15 @@ mod tests {
assert_eq!(brightness_contrast_legacy_map(-150., 100.), [0; 256]);
assert_eq!(brightness_contrast_legacy_map(-77., 100.), {
let mut x = [0; 153].into_iter().chain([2, 20, 65, 143].into_iter()).chain([255; 99].into_iter());
let mut x = [0; 153].into_iter().chain([2, 20, 65, 143]).chain([255; 99]);
core::array::from_fn(|_| x.next().unwrap())
});
assert_eq!(brightness_contrast_legacy_map(0., 100.), {
let mut x = [0; 54].into_iter().chain([13, 107].into_iter()).chain([255; 200].into_iter());
let mut x = [0; 54].into_iter().chain([13, 107]).chain([255; 200]);
core::array::from_fn(|_| x.next().unwrap())
});
assert_eq!(brightness_contrast_legacy_map(53., 100.), {
let mut x = [0; 18].into_iter().chain([132].into_iter()).chain([255; 237].into_iter());
let mut x = [0; 18].into_iter().chain([132]).chain([255; 237]);
core::array::from_fn(|_| x.next().unwrap())
});
assert_eq!(brightness_contrast_legacy_map(150., 100.), [255; 256]);
@ -279,13 +279,13 @@ mod tests {
assert_eq!(brightness_contrast_legacy_map(0., 0.), core::array::from_fn(|i| i as u8));
assert_eq!(
brightness_contrast_legacy_map(53., 0.),
string_data("9,14,18,21,24,27,29,32,34,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,66,68,70,72,73,75,77,79,80,82,84,85,87,89,90,92,94,95,97,99,100,102,104,105,107,108,110,111,113,115,116,118,119,121,122,124,126,127,129,130,132,133,135,136,138,139,141,142,144,145,147,148,150,151,153,154,156,157,159,160,161,163,164,166,167,169,170,172,173,175,176,177,179,180,182,183,185,186,187,189,190,192,193,195,196,197,199,200,202,203,204,206,207,209,210,211,213,214,216,217,218,220,221,223,224,225,227,228,230,231,232,234,235,236,238,239,241,242,243,245,246,247,249,250,251,253,254").into_iter().chain([255; 105].into_iter()).collect::<Vec<_>>().as_slice(),
string_data("9,14,18,21,24,27,29,32,34,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,66,68,70,72,73,75,77,79,80,82,84,85,87,89,90,92,94,95,97,99,100,102,104,105,107,108,110,111,113,115,116,118,119,121,122,124,126,127,129,130,132,133,135,136,138,139,141,142,144,145,147,148,150,151,153,154,156,157,159,160,161,163,164,166,167,169,170,172,173,175,176,177,179,180,182,183,185,186,187,189,190,192,193,195,196,197,199,200,202,203,204,206,207,209,210,211,213,214,216,217,218,220,221,223,224,225,227,228,230,231,232,234,235,236,238,239,241,242,243,245,246,247,249,250,251,253,254").into_iter().chain([255; 105]).collect::<Vec<_>>().as_slice(),
);
assert_eq!(
brightness_contrast_legacy_map(150., 0.),
string_data("78,93,105,114,122,129,135,141,147,152,157,162,167,171,176,180,184,188,192,196,200,204,208,211,215,218,222,225,229,232,236,239,242,245,249,252")
.into_iter()
.chain([255; 220].into_iter())
.chain([255; 220])
.collect::<Vec<_>>()
.as_slice(),
);

View file

@ -11,6 +11,7 @@ mod base64_serde {
//! Basic wrapper for [`serde`] to perform [`base64`] encoding
use super::super::Pixel;
use base64::Engine;
use serde::{Deserialize, Deserializer, Serializer};
pub fn as_base64<S, P: Pixel>(key: &[P], serializer: S) -> Result<S::Ok, S::Error>
@ -18,7 +19,7 @@ mod base64_serde {
S: Serializer,
{
let u8_data = key.iter().flat_map(|color| color.to_bytes()).collect::<Vec<_>>();
serializer.serialize_str(&base64::encode(u8_data))
serializer.serialize_str(&base64::engine::general_purpose::STANDARD.encode(u8_data))
}
pub fn from_base64<'a, D, P: Pixel>(deserializer: D) -> Result<Vec<P>, D::Error>
@ -32,7 +33,7 @@ mod base64_serde {
let colors_from_bytes = |bytes: Vec<u8>| bytes.chunks_exact(P::byte_size()).map(color_from_chunk).collect();
String::deserialize(deserializer)
.and_then(|string| base64::decode(string).map_err(|err| Error::custom(err.to_string())))
.and_then(|string| base64::engine::general_purpose::STANDARD.decode(string).map_err(|err| Error::custom(err.to_string())))
.map(colors_from_bytes)
.map_err(serde::de::Error::custom)
}

View file

@ -97,7 +97,9 @@ impl BrushStroke {
// placing a blit point every time we travelled our spacing distance.
let spacing_dist = self.style.spacing / 100. * self.style.diameter;
let Some(first_sample) = self.trace.first() else { return Vec::new(); };
let Some(first_sample) = self.trace.first() else {
return Vec::new();
};
let mut cur_pos = first_sample.position;
let mut result = vec![cur_pos];

View file

@ -23,8 +23,8 @@ dyn-any = { path = "../../libraries/dyn-any", features = [
num-traits = "0.2"
log = "0.4"
serde = { version = "1", features = ["derive", "rc"] }
glam = { version = "0.22" }
base64 = "0.13"
glam = { version = "0.24" }
base64 = "0.21"
bytemuck = { version = "1.8" }
nvtx = { version = "1.1.1", optional = true }

View file

@ -13,7 +13,7 @@ crate-type = ["dylib", "lib"]
libm = { git = "https://github.com/rust-lang/libm", tag = "0.2.5" }
[dependencies]
spirv-std = { version = "0.7" }
spirv-std = { version = "0.8" }
graphene-core = { path = "{{gcore_path}}", default-features = false, features = [
"gpu",
] }

View file

@ -26,8 +26,8 @@ dyn-any = { path = "../../libraries/dyn-any", features = [
num-traits = "0.2"
log = "0.4"
serde = { version = "1", features = ["derive", "rc"] }
glam = "0.22"
base64 = "0.13"
glam = "0.24"
base64 = "0.21"
bytemuck = { version = "1.8" }
anyhow = "1.0.66"

View file

@ -41,10 +41,10 @@ pub trait Texture {
pub trait GpuExecutor {
type ShaderHandle;
type BufferHandle;
type TextureHandle;
type TextureView;
type Surface;
type BufferHandle: Send + Sync;
type TextureHandle: Send + Sync;
type TextureView: Send + Sync;
type Surface: Send + Sync;
type Window;
type CommandBuffer;

View file

@ -18,8 +18,8 @@ num-traits = "0.2"
dyn-clone = "1.0"
log = "0.4"
serde = { version = "1", features = ["derive", "rc"], optional = true }
glam = { version = "0.22" }
base64 = "0.13"
glam = { version = "0.24" }
base64 = "0.21"
bezier-rs = { path = "../../libraries/bezier-rs", features = ["dyn-any"] }
specta.workspace = true

View file

@ -111,7 +111,7 @@ impl DocumentNode {
P: Fn(String, usize) -> Option<NodeInput>,
{
for (index, input) in self.inputs.iter_mut().enumerate() {
let &mut NodeInput::Node{node_id: id, output_index, lambda} = input else {
let &mut NodeInput::Node { node_id: id, output_index, lambda } = input else {
continue;
};
if let Some(&new_id) = new_ids.get(&id) {
@ -538,7 +538,7 @@ impl NodeNetwork {
while !dependencies.is_empty() {
let Some((&disconnected, _)) = dependencies.iter().find(|(_, l)| l.is_empty()) else {
error!("Dependencies {dependencies:?}");
return false
return false;
};
dependencies.remove(&disconnected);
for connections in dependencies.values_mut() {
@ -655,12 +655,10 @@ impl NodeNetwork {
/// Recursively dissolve non-primitive document nodes and return a single flattened network of nodes.
pub fn flatten_with_fns(&mut self, node: NodeId, map_ids: impl Fn(NodeId, NodeId) -> NodeId + Copy, gen_id: impl Fn() -> NodeId + Copy) {
self.resolve_extract_nodes();
let Some((id, mut node)) = self
.nodes
.remove_entry(&node) else {
warn!("The node which was supposed to be flattened does not exist in the network, id {} network {:#?}", node, self);
return;
};
let Some((id, mut node)) = self.nodes.remove_entry(&node) else {
warn!("The node which was supposed to be flattened does not exist in the network, id {} network {:#?}", node, self);
return;
};
if self.disabled.contains(&id) {
node.implementation = DocumentNodeImplementation::Unresolved("graphene_core::ops::IdNode".into());

View file

@ -194,7 +194,7 @@ impl<'a> TaggedValue {
TaggedValue::F64(x) => x.to_string() + "_f64",
TaggedValue::Bool(x) => x.to_string(),
TaggedValue::BlendMode(blend_mode) => "BlendMode::".to_string() + &blend_mode.to_string(),
TaggedValue::Color(color) => "graphene_core::Color::from_rgbaf32_unchecked(0.,0.,0.,1.)".to_string(),
TaggedValue::Color(color) => format!("Color {color:?}"),
_ => panic!("Cannot convert to primitive string"),
}
}

View file

@ -112,8 +112,8 @@ impl ImaginateStatus {
Self::Beginning => Cow::Borrowed("Beginning…"),
Self::Uploading => Cow::Borrowed("Downloading Image…"),
Self::Generating(percent) => Cow::Owned(format!("Generating {percent:.0}%")),
Self::Terminating => Cow::Owned(format!("Terminating…")),
Self::Terminated => Cow::Owned(format!("Terminated")),
Self::Terminating => Cow::Owned("Terminating…".to_string()),
Self::Terminated => Cow::Owned("Terminated".to_string()),
Self::Failed(err) => Cow::Owned(format!("Failed: {err}")),
}
}

View file

@ -2,7 +2,6 @@ use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
use std::ops::Deref;
use std::sync::Arc;
use std::hash::Hash;
use xxhash_rust::xxh3::Xxh3;
@ -19,13 +18,16 @@ pub type DynFuture<'n, T> = Pin<Box<dyn core::future::Future<Output = T> + 'n>>;
pub type LocalFuture<'n, T> = Pin<Box<dyn core::future::Future<Output = T> + 'n>>;
pub type Any<'n> = Box<dyn DynAny<'n> + 'n>;
pub type FutureAny<'n> = DynFuture<'n, Any<'n>>;
// TODO: is this safe? This is assumed to be send+sync.
pub type TypeErasedNode<'n> = dyn for<'i> NodeIO<'i, Any<'i>, Output = FutureAny<'i>> + 'n;
pub type TypeErasedPinnedRef<'n> = Pin<&'n TypeErasedNode<'n>>;
pub type TypeErasedRef<'n> = &'n TypeErasedNode<'n>;
pub type TypeErasedBox<'n> = Box<TypeErasedNode<'n>>;
pub type TypeErasedPinned<'n> = Pin<Box<TypeErasedNode<'n>>>;
pub type NodeConstructor = for<'a> fn(Vec<Arc<NodeContainer>>) -> DynFuture<'static, TypeErasedBox<'static>>;
pub type SharedNodeContainer = std::rc::Rc<NodeContainer>;
pub type NodeConstructor = for<'a> fn(Vec<SharedNodeContainer>) -> DynFuture<'static, TypeErasedBox<'static>>;
#[derive(Clone)]
pub struct NodeContainer {
@ -64,9 +66,9 @@ impl core::fmt::Debug for NodeContainer {
}
impl NodeContainer {
pub fn new(node: TypeErasedBox<'static>) -> Arc<Self> {
pub fn new(node: TypeErasedBox<'static>) -> SharedNodeContainer {
let node = Box::leak(node);
Arc::new(Self { node })
Self { node }.into()
}
#[cfg(feature = "dealloc_nodes")]
@ -89,7 +91,7 @@ impl core::fmt::Display for ProtoNetwork {
f.write_str("Proto Network with nodes: ")?;
fn write_node(f: &mut core::fmt::Formatter<'_>, network: &ProtoNetwork, id: NodeId, indent: usize) -> core::fmt::Result {
f.write_str(&"\t".repeat(indent))?;
let Some((_, node)) = network.nodes.iter().find(|(node_id, _)|*node_id == id) else {
let Some((_, node)) = network.nodes.iter().find(|(node_id, _)| *node_id == id) else {
return f.write_str("{{Unknown Node}}");
};
f.write_str("Node: ")?;

View file

@ -30,7 +30,7 @@ bitflags = "1.2.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0" }
bezier-rs = { path = "../../libraries/bezier-rs" }
glam = { version = "0.22", features = ["serde"] }
glam = { version = "0.24", features = ["serde"] }
# Node graph
graphene-std = { path = "../gstd" }

View file

@ -1,21 +1,17 @@
use fern::colors::{Color, ColoredLevelConfig};
use std::{collections::HashMap, error::Error, sync::Arc};
use std::{error::Error, sync::Arc};
use document_legacy::{
document::Document,
layers::layer_info::{LayerData, LayerDataType},
};
use document_legacy::{document::Document, layers::layer_info::LayerDataType};
use futures::executor::block_on;
use graph_craft::{
concrete,
document::{value::TaggedValue, *},
document::*,
graphene_compiler::{Compiler, Executor},
imaginate_input::ImaginatePreferences,
NodeIdentifier, Type, TypeDescriptor,
};
use graphene_core::{
application_io::{self, ApplicationIo, NodeGraphUpdateSender},
raster::ImageFrame,
application_io::{ApplicationIo, NodeGraphUpdateSender},
text::FontCache,
Cow,
};
@ -63,12 +59,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
loop {
//println!("executing");
let result = (&executor).execute(editor_api.clone()).await?;
let _result = (&executor).execute(editor_api.clone()).await?;
//println!("result: {:?}", result);
std::thread::sleep(std::time::Duration::from_millis(16));
}
Ok(())
}
fn init_logging() {
@ -94,7 +88,9 @@ fn init_logging() {
fn create_executor(document_string: String) -> Result<DynamicExecutor, Box<dyn Error>> {
let document: serde_json::Value = serde_json::from_str(&document_string).expect("Failed to parse document");
let document = serde_json::from_value::<Document>(document["document_legacy"].clone()).expect("Failed to parse document");
let Some(LayerDataType::Layer(ref node_graph)) = document.root.iter().find(|layer| matches!(layer.data, LayerDataType::Layer(_))).map(|x|&x.data) else { panic!("failed to extract node graph from docmuent") };
let Some(LayerDataType::Layer(ref node_graph)) = document.root.iter().find(|layer| matches!(layer.data, LayerDataType::Layer(_))).map(|x| &x.data) else {
panic!("failed to extract node graph from docmuent")
};
let network = &node_graph.network;
let wrapped_network = wrap_network_in_scope(network.clone());
let compiler = Compiler {};
@ -103,43 +99,6 @@ fn create_executor(document_string: String) -> Result<DynamicExecutor, Box<dyn E
Ok(executor)
}
#[cfg(test)]
mod test {
use super::*;
#[tokio::test]
#[cfg_attr(not(feature = "wayland"), ignore)]
async fn grays_scale() {
let document_string = include_str!("../test_files/gray.graphite");
let executor = create_executor(document_string.to_string()).unwrap();
let editor_api = WasmEditorApi {
image_frame: None,
font_cache: &FontCache::default(),
application_io: &block_on(WasmApplicationIo::new()),
node_graph_message_sender: &UpdateLogger {},
imaginate_preferences: &ImaginatePreferences::default(),
};
let result = (&executor).execute(editor_api.clone()).await.unwrap();
println!("result: {:?}", result);
}
#[tokio::test]
#[cfg_attr(not(feature = "wayland"), ignore)]
async fn hue() {
let document_string = include_str!("../test_files/hue.graphite");
let executor = create_executor(document_string.to_string()).unwrap();
let editor_api = WasmEditorApi {
image_frame: None,
font_cache: &FontCache::default(),
application_io: &block_on(WasmApplicationIo::new()),
node_graph_message_sender: &UpdateLogger {},
imaginate_preferences: &ImaginatePreferences::default(),
};
let result = (&executor).execute(editor_api.clone()).await.unwrap();
println!("result: {:?}", result);
}
}
pub fn wrap_network_in_scope(mut network: NodeNetwork) -> NodeNetwork {
let node_ids = network.nodes.keys().copied().collect::<Vec<_>>();
@ -232,3 +191,40 @@ fn begin_scope() -> DocumentNode {
..Default::default()
}
}
#[cfg(test)]
mod test {
use super::*;
#[tokio::test]
#[cfg_attr(not(feature = "wayland"), ignore)]
async fn grays_scale() {
let document_string = include_str!("../test_files/gray.graphite");
let executor = create_executor(document_string.to_string()).unwrap();
let editor_api = WasmEditorApi {
image_frame: None,
font_cache: &FontCache::default(),
application_io: &block_on(WasmApplicationIo::new()),
node_graph_message_sender: &UpdateLogger {},
imaginate_preferences: &ImaginatePreferences::default(),
};
let result = (&executor).execute(editor_api.clone()).await.unwrap();
println!("result: {:?}", result);
}
#[tokio::test]
#[cfg_attr(not(feature = "wayland"), ignore)]
async fn hue() {
let document_string = include_str!("../test_files/hue.graphite");
let executor = create_executor(document_string.to_string()).unwrap();
let editor_api = WasmEditorApi {
image_frame: None,
font_cache: &FontCache::default(),
application_io: &block_on(WasmApplicationIo::new()),
node_graph_message_sender: &UpdateLogger {},
imaginate_preferences: &ImaginatePreferences::default(),
};
let result = (&executor).execute(editor_api.clone()).await.unwrap();
println!("result: {:?}", result);
}
}

View file

@ -51,7 +51,7 @@ bezier-rs = { path = "../../libraries/bezier-rs", features = ["serde"] }
kurbo = { git = "https://github.com/linebender/kurbo.git", features = [
"serde",
] }
glam = { version = "0.22", features = ["serde"] }
glam = { version = "0.24", features = ["serde"] }
node-macro = { path = "../node-macro" }
xxhash-rust = { workspace = true }
serde_json = "1.0.96"

View file

@ -1,9 +1,9 @@
use dyn_any::StaticType;
pub use graph_craft::proto::{Any, NodeContainer, TypeErasedBox, TypeErasedNode};
use graph_craft::proto::{DynFuture, FutureAny};
use graph_craft::proto::{DynFuture, FutureAny, SharedNodeContainer};
use graphene_core::NodeIO;
pub use graphene_core::{generic, ops, Node};
use std::{marker::PhantomData, sync::Arc};
use std::marker::PhantomData;
pub struct DynAnyNode<I, O, Node> {
node: Node,
@ -164,7 +164,7 @@ where
/// Wraps around a node taking Box<dyn DynAny> and returning Box<dyn DynAny>
#[derive(Clone)]
pub struct DowncastBothNode<I, O> {
node: Arc<NodeContainer>,
node: SharedNodeContainer,
_i: PhantomData<I>,
_o: PhantomData<O>,
}
@ -184,7 +184,7 @@ impl<'input, O: 'input + StaticType, I: 'input + StaticType> Node<'input, I> for
}
}
impl<I, O> DowncastBothNode<I, O> {
pub const fn new(node: Arc<NodeContainer>) -> Self {
pub const fn new(node: SharedNodeContainer) -> Self {
Self {
node,
_i: core::marker::PhantomData,
@ -196,7 +196,7 @@ impl<I, O> DowncastBothNode<I, O> {
/// Wraps around a node taking Box<dyn DynAny> and returning Box<dyn DynAny>
#[derive(Clone)]
pub struct DowncastBothRefNode<I, O> {
node: Arc<NodeContainer>,
node: SharedNodeContainer,
_i: PhantomData<(I, O)>,
}
impl<'input, O: 'input + StaticType, I: 'input + StaticType> Node<'input, I> for DowncastBothRefNode<I, O> {
@ -214,14 +214,14 @@ impl<'input, O: 'input + StaticType, I: 'input + StaticType> Node<'input, I> for
}
}
impl<I, O> DowncastBothRefNode<I, O> {
pub const fn new(node: Arc<NodeContainer>) -> Self {
pub const fn new(node: SharedNodeContainer) -> Self {
Self { node, _i: core::marker::PhantomData }
}
}
pub struct ComposeTypeErased {
first: Arc<NodeContainer>,
second: Arc<NodeContainer>,
first: SharedNodeContainer,
second: SharedNodeContainer,
}
impl<'i, 'a: 'i> Node<'i, Any<'i>> for ComposeTypeErased {
@ -235,12 +235,12 @@ impl<'i, 'a: 'i> Node<'i, Any<'i>> for ComposeTypeErased {
}
impl ComposeTypeErased {
pub const fn new(first: Arc<NodeContainer>, second: Arc<NodeContainer>) -> Self {
pub const fn new(first: SharedNodeContainer, second: SharedNodeContainer) -> Self {
ComposeTypeErased { first, second }
}
}
pub fn input_node<O: StaticType>(n: Arc<NodeContainer>) -> DowncastBothNode<(), O> {
pub fn input_node<O: StaticType>(n: SharedNodeContainer) -> DowncastBothNode<(), O> {
DowncastBothNode::new(n)
}
@ -262,7 +262,7 @@ impl<I, O> PanicNode<I, O> {
#[cfg(test)]
mod test {
use super::*;
use graphene_core::{ops::AddNode, ops::IdNode, value::ValueNode};
use graphene_core::{ops::AddNode, ops::IdNode};
#[test]
#[should_panic]

View file

@ -318,7 +318,7 @@ async fn brush(image: ImageFrame<Color>, bounds: ImageFrame<Color>, strokes: Vec
// Compute transformation from stroke texture space into layer space, and create the stroke texture.
let skip = if idx == 0 { brush_plan.first_stroke_point_skip } else { 0 };
let positions: Vec<_> = stroke.compute_blit_points().into_iter().skip(skip).collect();
let stroke_texture = if idx == 0 && positions.len() == 0 {
let stroke_texture = if idx == 0 && positions.is_empty() {
core::mem::take(&mut brush_plan.first_stroke_texture)
} else {
let mut bbox = stroke.bounding_box();

View file

@ -1,11 +1,11 @@
use dyn_any::{StaticType, StaticTypeSized};
use dyn_any::StaticTypeSized;
use glam::{DAffine2, DVec2, Mat2, Vec2};
use gpu_executor::{Bindgroup, ComputePassDimensions, PipelineLayout, StorageBufferOptions};
use gpu_executor::{GpuExecutor, ShaderIO, ShaderInput};
use graph_craft::document::value::TaggedValue;
use graph_craft::document::*;
use graph_craft::proto::*;
use graphene_core::quantization::{PackedPixel, QuantizationChannels};
use graphene_core::quantization::QuantizationChannels;
use graphene_core::raster::*;
use graphene_core::*;
use wgpu_executor::WgpuExecutor;
@ -292,7 +292,7 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
)
.unwrap();
let width_uniform = Arc::new(width_uniform);
let quantization_uniform = Arc::new(quantization_uniform);
let _quantization_uniform = Arc::new(quantization_uniform);
let storage_buffer = Arc::new(storage_buffer);
let output_buffer = executor.create_output_buffer(len, concrete!(Color), false).unwrap();
let output_buffer = Arc::new(output_buffer);
@ -322,11 +322,10 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
};
log::debug!("created pipeline");
let compute_pass_descriptor = ComputePass {
ComputePass {
pipeline_layout: pipeline,
readback_buffer: Some(readback_buffer.clone()),
};
compute_pass_descriptor
}
}
/*
#[node_macro::node_fn(MapGpuNode)]

View file

@ -2,7 +2,7 @@ use crate::wasm_application_io::WasmEditorApi;
use core::any::TypeId;
use core::future::Future;
use futures::{future::Either, TryFutureExt};
use glam::DVec2;
use glam::{DVec2, U64Vec2};
use graph_craft::imaginate_input::{ImaginateController, ImaginateMaskStartingFill, ImaginatePreferences, ImaginateSamplingMethod, ImaginateServerStatus, ImaginateStatus, ImaginateTerminationHandle};
use graphene_core::application_io::NodeGraphUpdateMessage;
use graphene_core::raster::{Color, Image, Luma, Pixel};
@ -62,6 +62,8 @@ impl Default for ImaginatePersistentData {
}
}
type ImaginateFuture = core::pin::Pin<Box<dyn Future<Output = ()> + 'static>>;
impl ImaginatePersistentData {
pub fn set_host_name(&mut self, name: &str) {
match parse_url(name) {
@ -70,9 +72,11 @@ impl ImaginatePersistentData {
}
}
fn initiate_server_check_maybe_fail(&mut self) -> Result<Option<core::pin::Pin<Box<dyn Future<Output = ()> + 'static>>>, Error> {
fn initiate_server_check_maybe_fail(&mut self) -> Result<Option<ImaginateFuture>, Error> {
use futures::future::FutureExt;
let Some(client) = &self.client else { return Ok(None); };
let Some(client) = &self.client else {
return Ok(None);
};
if self.pending_server_check.is_some() {
return Ok(None);
}
@ -87,7 +91,7 @@ impl ImaginatePersistentData {
Ok(Some(Box::pin(response_future)))
}
pub fn initiate_server_check(&mut self) -> Option<core::pin::Pin<Box<dyn Future<Output = ()> + 'static>>> {
pub fn initiate_server_check(&mut self) -> Option<ImaginateFuture> {
match self.initiate_server_check_maybe_fail() {
Ok(f) => f,
Err(err) => {
@ -256,6 +260,7 @@ struct ImaginateCommonImageRequest<'a> {
}
#[cfg(feature = "imaginate")]
#[allow(clippy::too_many_arguments)]
pub async fn imaginate<'a, P: Pixel>(
image: Image<P>,
editor_api: impl Future<Output = WasmEditorApi<'a>>,
@ -323,6 +328,7 @@ pub async fn imaginate<'a, P: Pixel>(
}
#[cfg(feature = "imaginate")]
#[allow(clippy::too_many_arguments)]
async fn imaginate_maybe_fail<'a, P: Pixel, F: Fn(ImaginateStatus)>(
image: Image<P>,
host_name: &str,
@ -492,26 +498,25 @@ pub fn pick_safe_imaginate_resolution((width, height): (f64, f64)) -> (u64, u64)
const MAX_DIMENSION: u64 = (MAX_RESOLUTION / 64) & !63;
// round the resolution to the nearest multiple of 64
let [width, height] = [width, height].map(|c| (c.round().clamp(0., MAX_DIMENSION as _) as u64 + 32).max(64) & !63);
let resolution = width * height;
let size = (DVec2::new(width, height).round().clamp(DVec2::ZERO, DVec2::splat(MAX_DIMENSION as _)).as_u64vec2() + U64Vec2::splat(32)).max(U64Vec2::splat(64)) & !U64Vec2::splat(63);
let resolution = size.x * size.y;
if resolution > MAX_RESOLUTION {
// scale down the image, so it is smaller than MAX_RESOLUTION
let scale = (MAX_RESOLUTION as f64 / resolution as f64).sqrt();
let [width, height] = [width, height].map(|c| c as f64 * scale);
let size = size.as_dvec2() * scale;
if width < 64.0 {
if size.x < 64.0 {
// the image is extremely wide
(64, MAX_DIMENSION)
} else if height < 64.0 {
} else if size.y < 64.0 {
// the image is extremely high
(MAX_DIMENSION, 64)
} else {
// round down to a multiple of 64, so that the resolution still is smaller than MAX_RESOLUTION
let [width, height] = [width, height].map(|c| c as u64 & !63);
(width, height)
(size.as_u64vec2() & !U64Vec2::splat(63)).into()
}
} else {
(width, height)
size.into()
}
}

View file

@ -256,7 +256,9 @@ where
let foreground_aabb = Bbox::unit().affine_transform(foreground.transform()).to_axis_aligned_bbox();
let background_aabb = Bbox::unit().affine_transform(background.transform()).to_axis_aligned_bbox();
let Some(aabb) = foreground_aabb.union_non_empty(&background_aabb) else {return ImageFrame::empty()};
let Some(aabb) = foreground_aabb.union_non_empty(&background_aabb) else {
return ImageFrame::empty();
};
if background_aabb.contains(foreground_aabb.start) && background_aabb.contains(foreground_aabb.end) {
return blend_image(foreground, background, map_fn);
@ -434,6 +436,7 @@ macro_rules! generate_imaginate_node {
E: for<'any_input> Node<'any_input, (), Output = DynFuture<'any_input, WasmEditorApi<'e>>>,
C: for<'any_input> Node<'any_input, (), Output = DynFuture<'any_input, ImaginateController>>,
{
#[allow(clippy::too_many_arguments)]
pub fn new(editor_api: E, controller: C, $($val: $t,)* ) -> Self {
Self { editor_api, controller, $($val,)* cache: Default::default() }
}

View file

@ -1,23 +1,27 @@
use std::any::Any;
use std::cell::RefCell;
use core::future::Future;
use dyn_any::StaticType;
use graphene_core::application_io::{ApplicationError, ApplicationIo, SurfaceHandle, SurfaceHandleFrame, SurfaceId};
use graphene_core::application_io::{ApplicationError, ApplicationIo, ResourceFuture, SurfaceHandle, SurfaceHandleFrame, SurfaceId};
use graphene_core::raster::Image;
use graphene_core::Color;
use graphene_core::{
raster::{color::SRGBA8, ImageFrame},
Node,
};
#[cfg(target_arch = "wasm32")]
use js_sys::{Object, Reflect};
use std::collections::HashMap;
use std::pin::Pin;
use std::sync::Arc;
#[cfg(feature = "tokio")]
use tokio::io::AsyncReadExt;
use wasm_bindgen::{Clamped, JsCast, JsValue};
use web_sys::{window, CanvasRenderingContext2d, HtmlCanvasElement};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::JsValue;
use wasm_bindgen::{Clamped, JsCast};
#[cfg(target_arch = "wasm32")]
use web_sys::window;
use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement};
#[cfg(feature = "wgpu")]
use wgpu_executor::WgpuExecutor;
@ -25,6 +29,7 @@ pub struct Canvas(CanvasRenderingContext2d);
#[derive(Debug, Default)]
pub struct WasmApplicationIo {
#[cfg(target_arch = "wasm32")]
ids: RefCell<u64>,
#[cfg(feature = "wgpu")]
pub(crate) gpu_executor: Option<WgpuExecutor>,
@ -36,6 +41,7 @@ pub struct WasmApplicationIo {
impl WasmApplicationIo {
pub async fn new() -> Self {
let mut io = Self {
#[cfg(target_arch = "wasm32")]
ids: RefCell::new(0),
#[cfg(feature = "wgpu")]
gpu_executor: WgpuExecutor::new().await,
@ -161,7 +167,7 @@ impl ApplicationIo for WasmApplicationIo {
self.gpu_executor.as_ref()
}
fn load_resource(&self, url: impl AsRef<str>) -> Result<Pin<Box<dyn Future<Output = Result<Arc<[u8]>, ApplicationError>>>>, ApplicationError> {
fn load_resource(&self, url: impl AsRef<str>) -> Result<ResourceFuture, ApplicationError> {
let url = url::Url::parse(url.as_ref()).map_err(|_| ApplicationError::InvalidUrl)?;
log::info!("Loading resource: {:?}", url);
match url.scheme() {
@ -223,7 +229,7 @@ async fn draw_image_frame_node<'a: 'input>(image: ImageFrame<SRGBA8>, surface_ha
canvas.set_height(image.image.height);
// TODO: replace "2d" with "bitmaprenderer" once we switch to ImageBitmap (lives on gpu) from ImageData (lives on cpu)
let context = canvas.get_context("2d").unwrap().unwrap().dyn_into::<CanvasRenderingContext2d>().unwrap();
let image_data = web_sys::ImageData::new_with_u8_clamped_array_and_sh(array, image.image.width as u32, image.image.height as u32).expect("Failed to construct ImageData");
let image_data = web_sys::ImageData::new_with_u8_clamped_array_and_sh(array, image.image.width, image.image.height).expect("Failed to construct ImageData");
context.put_image_data(&image_data, 0.0, 0.0).unwrap();
}
SurfaceHandleFrame {

View file

@ -26,7 +26,7 @@ num-traits = "0.2"
dyn-clone = "1.0"
log = "0.4"
serde = { version = "1", features = ["derive"], optional = true }
glam = { version = "0.22" }
glam = { version = "0.24" }
once_cell = "1.17.0"
futures = "0.3.28"
typed-arena = "2.0.2"

View file

@ -1,13 +1,12 @@
use std::collections::{HashMap, HashSet};
use std::error::Error;
use std::sync::Arc;
use dyn_any::StaticType;
use graph_craft::document::value::{TaggedValue, UpcastNode};
use graph_craft::document::NodeId;
use graph_craft::graphene_compiler::Executor;
use graph_craft::proto::{ConstructionArgs, LocalFuture, NodeContainer, ProtoNetwork, ProtoNode, TypeErasedBox, TypingContext};
use graph_craft::proto::{ConstructionArgs, LocalFuture, NodeContainer, ProtoNetwork, ProtoNode, SharedNodeContainer, TypeErasedBox, TypingContext};
use graph_craft::Type;
use crate::node_registry;
@ -80,7 +79,7 @@ impl<'a, I: StaticType + 'a> Executor<I, TaggedValue> for &'a DynamicExecutor {
#[derive(Default)]
pub struct BorrowTree {
nodes: HashMap<NodeId, Arc<NodeContainer>>,
nodes: HashMap<NodeId, SharedNodeContainer>,
source_map: HashMap<Vec<NodeId>, NodeId>,
}
@ -109,11 +108,11 @@ impl BorrowTree {
Ok(old_nodes.into_iter().collect())
}
fn node_deps(&self, nodes: &[NodeId]) -> Vec<Arc<NodeContainer>> {
fn node_deps(&self, nodes: &[NodeId]) -> Vec<SharedNodeContainer> {
nodes.iter().map(|node| self.nodes.get(node).unwrap().clone()).collect()
}
fn store_node(&mut self, node: Arc<NodeContainer>, id: NodeId) {
fn store_node(&mut self, node: SharedNodeContainer, id: NodeId) {
self.nodes.insert(id, node);
}
@ -123,7 +122,7 @@ impl BorrowTree {
Some(node.serialize())
}
pub fn get(&self, id: NodeId) -> Option<Arc<NodeContainer>> {
pub fn get(&self, id: NodeId) -> Option<SharedNodeContainer> {
self.nodes.get(&id).cloned()
}

View file

@ -1,4 +1,4 @@
use graph_craft::imaginate_input::{ImaginateCache, ImaginateController, ImaginateMaskStartingFill, ImaginateSamplingMethod};
use graph_craft::imaginate_input::{ImaginateController, ImaginateMaskStartingFill, ImaginateSamplingMethod};
use graph_craft::proto::{NodeConstructor, TypeErasedBox};
use graphene_core::ops::IdNode;
use graphene_core::quantization::{PackedPixel, QuantizationChannels};
@ -464,7 +464,7 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
),
(
NodeIdentifier::new("graphene_std::raster::ImaginateNode<_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _>"),
|args: Vec<Arc<graph_craft::proto::NodeContainer>>| {
|args: Vec<graph_craft::proto::SharedNodeContainer>| {
Box::pin(async move {
use graphene_std::raster::ImaginateNode;
macro_rules! instanciate_imaginate_node {

View file

@ -128,7 +128,12 @@ fn node_impl_impl(attr: TokenStream, item: TokenStream, asyncness: Asyncness) ->
let (primary_input, parameter_inputs, parameter_pat_ident_patterns) = parse_inputs(&function, true);
let primary_input_ty = &primary_input.ty;
let Pat::Ident(PatIdent{ident: primary_input_ident, mutability: primary_input_mutability,..} ) =&*primary_input.pat else {
let Pat::Ident(PatIdent {
ident: primary_input_ident,
mutability: primary_input_mutability,
..
}) = &*primary_input.pat
else {
panic!("Expected ident as primary input.");
};
@ -232,7 +237,9 @@ fn parse_inputs(function: &ItemFn, remove_impl_node: bool) -> (&syn::PatType, Ve
.iter()
.filter(|input| !matches!(&*input.ty, Type::ImplTrait(_)) || !remove_impl_node)
.map(|input| {
let Pat::Ident(pat_ident) = &*input.pat else { panic!("Expected ident for secondary input."); };
let Pat::Ident(pat_ident) = &*input.pat else {
panic!("Expected ident for secondary input.");
};
pat_ident
})
.collect::<Vec<_>>();
@ -261,14 +268,20 @@ fn input_node_bounds(parameter_inputs: Vec<Type>, node_generics: Vec<GenericPara
.iter()
.zip(&node_generics)
.map(|(ty, name)| {
let GenericParam::Type(generic_ty) = name else { panic!("Expected type generic."); };
let GenericParam::Type(generic_ty) = name else {
panic!("Expected type generic.");
};
let ident = &generic_ty.ident;
let (lifetime, in_ty, out_ty) = match ty.clone() {
Type::ImplTrait(TypeImplTrait { bounds, .. }) if bounds.len() == 1 => {
let TypeParamBound::Trait(TraitBound { ref path, .. }) = bounds[0] else {panic!("impl Traits other then Node are not supported")};
let TypeParamBound::Trait(TraitBound { ref path, .. }) = bounds[0] else {
panic!("impl Traits other then Node are not supported")
};
let node_segment = path.segments.last().expect("Found an empty path in the impl Trait arg");
assert_eq!(node_segment.ident.to_string(), "Node", "Only impl Node is supported as an argument");
let PathArguments::AngleBracketed(AngleBracketedGenericArguments {ref args, .. }) = node_segment.arguments else { panic!("Node must have generic arguments")};
let PathArguments::AngleBracketed(AngleBracketedGenericArguments { ref args, .. }) = node_segment.arguments else {
panic!("Node must have generic arguments")
};
let mut args_iter = args.iter();
let lifetime = if args.len() == 2 {
Lifetime::new("'input", Span::call_site())
@ -278,8 +291,12 @@ fn input_node_bounds(parameter_inputs: Vec<Type>, node_generics: Vec<GenericPara
panic!("Invalid arguments for Node trait")
};
let Some(GenericArgument::Type(in_ty)) = args_iter.next() else { panic!("Expected type argument in Node<> declaration")};
let Some(GenericArgument::Binding(Binding {ty: out_ty, ..} )) = args_iter.next() else { panic!("Expected Output = in Node declaration")};
let Some(GenericArgument::Type(in_ty)) = args_iter.next() else {
panic!("Expected type argument in Node<> declaration")
};
let Some(GenericArgument::Binding(Binding { ty: out_ty, .. })) = args_iter.next() else {
panic!("Expected Output = in Node declaration")
};
(lifetime, in_ty.clone(), out_ty.clone())
}
ty => (

View file

@ -16,9 +16,9 @@ dyn-any = { path = "../../libraries/dyn-any", features = ["log-bad-types", "rc",
num-traits = "0.2"
log = "0.4"
serde = { version = "1", features = ["derive", "rc"], optional = true }
glam = { version = "0.22" }
base64 = "0.13"
glam = { version = "0.24" }
base64 = "0.21"
vulkano = { git = "https://github.com/GraphiteEditor/vulkano", branch = "fix_rust_gpu"}
bytemuck = {version = "1.8" }
anyhow = "1.0.66"
bytemuck = { version = "1.13" }
anyhow = "1.0"

View file

@ -110,7 +110,7 @@ fn create_buffer<T: Pod + Send + Sync>(data: Vec<T>, alloc: &StandardMemoryAlloc
..Default::default()
};
buffer::CpuAccessibleBuffer::from_iter(alloc, buffer_usage, false, data.into_iter())
buffer::CpuAccessibleBuffer::from_iter(alloc, buffer_usage, false, data)
}
// TODO: Fix this test

View file

@ -29,8 +29,8 @@ future-executor = { path = "../future-executor" }
num-traits = "0.2"
log = "0.4"
serde = { version = "1", features = ["derive", "rc"], optional = true }
glam = { version = "0.22" }
base64 = "0.13"
glam = { version = "0.24" }
base64 = "0.21"
bytemuck = { version = "1.8" }
anyhow = "1.0.66"

View file

@ -12,8 +12,10 @@ pub struct Context {
impl Context {
pub async fn new() -> Option<Self> {
// Instantiates instance of WebGPU
let mut instance_descriptor = wgpu::InstanceDescriptor::default();
instance_descriptor.backends = wgpu::Backends::VULKAN | wgpu::Backends::BROWSER_WEBGPU;
let instance_descriptor = wgpu::InstanceDescriptor {
backends: wgpu::Backends::VULKAN | wgpu::Backends::BROWSER_WEBGPU,
..Default::default()
};
let instance = wgpu::Instance::new(instance_descriptor);
// `request_adapter` instantiates the general connection to the GPU
@ -30,7 +32,7 @@ impl Context {
features: wgpu::Features::empty(),
#[cfg(feature = "passthrough")]
features: wgpu::Features::SPIRV_SHADER_PASSTHROUGH,
limits: limits,
limits,
},
None,
)

View file

@ -295,7 +295,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
log::warn!("No surface formats available");
//return Ok(());
}
let Some(config) = self.surface_config.take() else {return Ok(())};
let Some(config) = self.surface_config.take() else { return Ok(()) };
let new_config = config.clone();
self.surface_config.replace(Some(config));
let output = match result {

View file

@ -19,7 +19,7 @@ default = ["serde-discriminant"]
serde-discriminant = []
[dependencies]
proc-macro2 = "1.0.26"
proc-macro2 = "1"
syn = { version = "1.0.68", features = ["full"] }
quote = "1.0.9"

View file

@ -4,6 +4,7 @@ use syn::{Path, PathArguments, PathSegment, Token};
/// Returns `Ok(Vec<T>)` if all items are `Ok(T)`, else returns a combination of every error encountered (not just the first one)
pub fn fold_error_iter<T>(iter: impl Iterator<Item = syn::Result<T>>) -> syn::Result<Vec<T>> {
#[allow(clippy::manual_try_fold)]
iter.fold(Ok(vec![]), |acc, x| match acc {
Ok(mut v) => x.map(|x| {
v.push(x);

View file

@ -21,7 +21,7 @@ wasm-bindgen = { version = "0.2.73" }
serde_json = "*"
serde-wasm-bindgen = "0.4.1"
js-sys = "0.3.55"
glam = { version = "0.22", features = ["serde"] }
glam = { version = "0.24", features = ["serde"] }
[dev-dependencies]
wasm-bindgen-test = "0.3.22"