+1
package.json
+1
package.json
+10
pnpm-lock.yaml
+10
pnpm-lock.yaml
···
11
11
'@tauri-apps/api':
12
12
specifier: ^2.9.0
13
13
version: 2.9.0
14
+
'@tauri-apps/plugin-clipboard-manager':
15
+
specifier: ~2
16
+
version: 2.3.2
14
17
'@tauri-apps/plugin-dialog':
15
18
specifier: ~2.4.2
16
19
version: 2.4.2
···
478
481
resolution: {integrity: sha512-BQ7iLUXTQcyG1PpzLWeVSmBCedYDpnA/6Cm/kRFGtqjTf/eVUlyYO5S2ee07tLum3nWwDBWTGFZeruO8yEukfA==}
479
482
engines: {node: '>= 10'}
480
483
hasBin: true
484
+
485
+
'@tauri-apps/plugin-clipboard-manager@2.3.2':
486
+
resolution: {integrity: sha512-CUlb5Hqi2oZbcZf4VUyUH53XWPPdtpw43EUpCza5HWZJwxEoDowFzNUDt1tRUXA8Uq+XPn17Ysfptip33sG4eQ==}
481
487
482
488
'@tauri-apps/plugin-dialog@2.4.2':
483
489
resolution: {integrity: sha512-lNIn5CZuw8WZOn8zHzmFmDSzg5zfohWoa3mdULP0YFh/VogVdMVWZPcWSHlydsiJhRQYaTNSYKN7RmZKE2lCYQ==}
···
1064
1070
'@tauri-apps/cli-win32-arm64-msvc': 2.9.3
1065
1071
'@tauri-apps/cli-win32-ia32-msvc': 2.9.3
1066
1072
'@tauri-apps/cli-win32-x64-msvc': 2.9.3
1073
+
1074
+
'@tauri-apps/plugin-clipboard-manager@2.3.2':
1075
+
dependencies:
1076
+
'@tauri-apps/api': 2.9.0
1067
1077
1068
1078
'@tauri-apps/plugin-dialog@2.4.2':
1069
1079
dependencies:
+286
-8
src-tauri/Cargo.lock
+286
-8
src-tauri/Cargo.lock
···
14
14
"serde_json",
15
15
"tauri",
16
16
"tauri-build",
17
+
"tauri-plugin-clipboard-manager",
17
18
"tauri-plugin-dialog",
18
19
"tauri-plugin-opener",
19
20
"tokio",
···
65
66
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
66
67
67
68
[[package]]
69
+
name = "arboard"
70
+
version = "3.6.1"
71
+
source = "registry+https://github.com/rust-lang/crates.io-index"
72
+
checksum = "0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf"
73
+
dependencies = [
74
+
"clipboard-win",
75
+
"image",
76
+
"log",
77
+
"objc2 0.6.3",
78
+
"objc2-app-kit",
79
+
"objc2-core-foundation",
80
+
"objc2-core-graphics",
81
+
"objc2-foundation 0.3.2",
82
+
"parking_lot",
83
+
"percent-encoding",
84
+
"windows-sys 0.60.2",
85
+
"wl-clipboard-rs",
86
+
"x11rb",
87
+
]
88
+
89
+
[[package]]
68
90
name = "ashpd"
69
91
version = "0.11.0"
70
92
source = "registry+https://github.com/rust-lang/crates.io-index"
···
136
158
"futures-lite",
137
159
"parking",
138
160
"polling",
139
-
"rustix",
161
+
"rustix 1.1.2",
140
162
"slab",
141
163
"windows-sys 0.61.2",
142
164
]
···
167
189
"cfg-if",
168
190
"event-listener",
169
191
"futures-lite",
170
-
"rustix",
192
+
"rustix 1.1.2",
171
193
]
172
194
173
195
[[package]]
···
193
215
"cfg-if",
194
216
"futures-core",
195
217
"futures-io",
196
-
"rustix",
218
+
"rustix 1.1.2",
197
219
"signal-hook-registry",
198
220
"slab",
199
221
"windows-sys 0.61.2",
···
498
520
"num-traits",
499
521
"serde",
500
522
"windows-link 0.2.1",
523
+
]
524
+
525
+
[[package]]
526
+
name = "clipboard-win"
527
+
version = "5.4.1"
528
+
source = "registry+https://github.com/rust-lang/crates.io-index"
529
+
checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4"
530
+
dependencies = [
531
+
"error-code",
501
532
]
502
533
503
534
[[package]]
···
609
640
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
610
641
611
642
[[package]]
643
+
name = "crunchy"
644
+
version = "0.2.4"
645
+
source = "registry+https://github.com/rust-lang/crates.io-index"
646
+
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
647
+
648
+
[[package]]
612
649
name = "crypto-common"
613
650
version = "0.1.6"
614
651
source = "registry+https://github.com/rust-lang/crates.io-index"
···
922
959
]
923
960
924
961
[[package]]
962
+
name = "error-code"
963
+
version = "3.3.2"
964
+
source = "registry+https://github.com/rust-lang/crates.io-index"
965
+
checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59"
966
+
967
+
[[package]]
925
968
name = "event-listener"
926
969
version = "5.4.1"
927
970
source = "registry+https://github.com/rust-lang/crates.io-index"
···
949
992
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
950
993
951
994
[[package]]
995
+
name = "fax"
996
+
version = "0.2.6"
997
+
source = "registry+https://github.com/rust-lang/crates.io-index"
998
+
checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab"
999
+
dependencies = [
1000
+
"fax_derive",
1001
+
]
1002
+
1003
+
[[package]]
1004
+
name = "fax_derive"
1005
+
version = "0.2.0"
1006
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1007
+
checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d"
1008
+
dependencies = [
1009
+
"proc-macro2",
1010
+
"quote",
1011
+
"syn 2.0.109",
1012
+
]
1013
+
1014
+
[[package]]
952
1015
name = "fdeflate"
953
1016
version = "0.3.7"
954
1017
source = "registry+https://github.com/rust-lang/crates.io-index"
···
974
1037
checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
975
1038
976
1039
[[package]]
1040
+
name = "fixedbitset"
1041
+
version = "0.5.7"
1042
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1043
+
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
1044
+
1045
+
[[package]]
977
1046
name = "flate2"
978
1047
version = "1.1.5"
979
1048
source = "registry+https://github.com/rust-lang/crates.io-index"
···
988
1057
version = "1.0.7"
989
1058
source = "registry+https://github.com/rust-lang/crates.io-index"
990
1059
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
1060
+
1061
+
[[package]]
1062
+
name = "foldhash"
1063
+
version = "0.1.5"
1064
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1065
+
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
991
1066
992
1067
[[package]]
993
1068
name = "foreign-types"
···
1239
1314
]
1240
1315
1241
1316
[[package]]
1317
+
name = "gethostname"
1318
+
version = "1.1.0"
1319
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1320
+
checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8"
1321
+
dependencies = [
1322
+
"rustix 1.1.2",
1323
+
"windows-link 0.2.1",
1324
+
]
1325
+
1326
+
[[package]]
1242
1327
name = "getrandom"
1243
1328
version = "0.1.16"
1244
1329
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1421
1506
]
1422
1507
1423
1508
[[package]]
1509
+
name = "half"
1510
+
version = "2.7.1"
1511
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1512
+
checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
1513
+
dependencies = [
1514
+
"cfg-if",
1515
+
"crunchy",
1516
+
"zerocopy",
1517
+
]
1518
+
1519
+
[[package]]
1424
1520
name = "hashbrown"
1425
1521
version = "0.12.3"
1426
1522
source = "registry+https://github.com/rust-lang/crates.io-index"
1427
1523
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
1524
+
1525
+
[[package]]
1526
+
name = "hashbrown"
1527
+
version = "0.15.5"
1528
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1529
+
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
1530
+
dependencies = [
1531
+
"foldhash",
1532
+
]
1428
1533
1429
1534
[[package]]
1430
1535
name = "hashbrown"
···
1706
1811
"moxcms",
1707
1812
"num-traits",
1708
1813
"png 0.18.0",
1814
+
"tiff",
1709
1815
]
1710
1816
1711
1817
[[package]]
···
1949
2055
1950
2056
[[package]]
1951
2057
name = "linux-raw-sys"
2058
+
version = "0.4.15"
2059
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2060
+
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
2061
+
2062
+
[[package]]
2063
+
name = "linux-raw-sys"
1952
2064
version = "0.11.0"
1953
2065
source = "registry+https://github.com/rust-lang/crates.io-index"
1954
2066
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
···
2031
2143
version = "0.3.17"
2032
2144
source = "registry+https://github.com/rust-lang/crates.io-index"
2033
2145
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
2146
+
2147
+
[[package]]
2148
+
name = "minimal-lexical"
2149
+
version = "0.2.1"
2150
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2151
+
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
2034
2152
2035
2153
[[package]]
2036
2154
name = "miniz_oxide"
···
2140
2258
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
2141
2259
2142
2260
[[package]]
2261
+
name = "nom"
2262
+
version = "7.1.3"
2263
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2264
+
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
2265
+
dependencies = [
2266
+
"memchr",
2267
+
"minimal-lexical",
2268
+
]
2269
+
2270
+
[[package]]
2143
2271
name = "num-conv"
2144
2272
version = "0.1.0"
2145
2273
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2475
2603
]
2476
2604
2477
2605
[[package]]
2606
+
name = "os_pipe"
2607
+
version = "1.2.3"
2608
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2609
+
checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967"
2610
+
dependencies = [
2611
+
"libc",
2612
+
"windows-sys 0.61.2",
2613
+
]
2614
+
2615
+
[[package]]
2478
2616
name = "pango"
2479
2617
version = "0.18.3"
2480
2618
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2541
2679
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
2542
2680
2543
2681
[[package]]
2682
+
name = "petgraph"
2683
+
version = "0.8.3"
2684
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2685
+
checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455"
2686
+
dependencies = [
2687
+
"fixedbitset",
2688
+
"hashbrown 0.15.5",
2689
+
"indexmap 2.12.0",
2690
+
]
2691
+
2692
+
[[package]]
2544
2693
name = "phf"
2545
2694
version = "0.8.0"
2546
2695
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2752
2901
"concurrent-queue",
2753
2902
"hermit-abi",
2754
2903
"pin-project-lite",
2755
-
"rustix",
2904
+
"rustix 1.1.2",
2756
2905
"windows-sys 0.61.2",
2757
2906
]
2758
2907
···
2862
3011
dependencies = [
2863
3012
"num-traits",
2864
3013
]
3014
+
3015
+
[[package]]
3016
+
name = "quick-error"
3017
+
version = "2.0.1"
3018
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3019
+
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
2865
3020
2866
3021
[[package]]
2867
3022
name = "quick-xml"
···
3152
3307
3153
3308
[[package]]
3154
3309
name = "rustix"
3310
+
version = "0.38.44"
3311
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3312
+
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
3313
+
dependencies = [
3314
+
"bitflags 2.10.0",
3315
+
"errno",
3316
+
"libc",
3317
+
"linux-raw-sys 0.4.15",
3318
+
"windows-sys 0.59.0",
3319
+
]
3320
+
3321
+
[[package]]
3322
+
name = "rustix"
3155
3323
version = "1.1.2"
3156
3324
source = "registry+https://github.com/rust-lang/crates.io-index"
3157
3325
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
···
3159
3327
"bitflags 2.10.0",
3160
3328
"errno",
3161
3329
"libc",
3162
-
"linux-raw-sys",
3330
+
"linux-raw-sys 0.11.0",
3163
3331
"windows-sys 0.61.2",
3164
3332
]
3165
3333
···
3858
4026
]
3859
4027
3860
4028
[[package]]
4029
+
name = "tauri-plugin-clipboard-manager"
4030
+
version = "2.3.2"
4031
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4032
+
checksum = "206dc20af4ed210748ba945c2774e60fd0acd52b9a73a028402caf809e9b6ecf"
4033
+
dependencies = [
4034
+
"arboard",
4035
+
"log",
4036
+
"serde",
4037
+
"serde_json",
4038
+
"tauri",
4039
+
"tauri-plugin",
4040
+
"thiserror 2.0.17",
4041
+
]
4042
+
4043
+
[[package]]
3861
4044
name = "tauri-plugin-dialog"
3862
4045
version = "2.4.2"
3863
4046
source = "registry+https://github.com/rust-lang/crates.io-index"
···
4028
4211
"fastrand",
4029
4212
"getrandom 0.3.4",
4030
4213
"once_cell",
4031
-
"rustix",
4214
+
"rustix 1.1.2",
4032
4215
"windows-sys 0.61.2",
4033
4216
]
4034
4217
···
4084
4267
]
4085
4268
4086
4269
[[package]]
4270
+
name = "tiff"
4271
+
version = "0.10.3"
4272
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4273
+
checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f"
4274
+
dependencies = [
4275
+
"fax",
4276
+
"flate2",
4277
+
"half",
4278
+
"quick-error",
4279
+
"weezl",
4280
+
"zune-jpeg",
4281
+
]
4282
+
4283
+
[[package]]
4087
4284
name = "time"
4088
4285
version = "0.3.44"
4089
4286
source = "registry+https://github.com/rust-lang/crates.io-index"
···
4360
4557
]
4361
4558
4362
4559
[[package]]
4560
+
name = "tree_magic_mini"
4561
+
version = "3.2.1"
4562
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4563
+
checksum = "52fac5f7d176f7f7f7e827299ead28ef98de642c5d93a97e0cd0816d17557f19"
4564
+
dependencies = [
4565
+
"memchr",
4566
+
"nom",
4567
+
"petgraph",
4568
+
]
4569
+
4570
+
[[package]]
4363
4571
name = "try-lock"
4364
4572
version = "0.2.5"
4365
4573
source = "registry+https://github.com/rust-lang/crates.io-index"
···
4640
4848
dependencies = [
4641
4849
"cc",
4642
4850
"downcast-rs",
4643
-
"rustix",
4851
+
"rustix 1.1.2",
4644
4852
"scoped-tls",
4645
4853
"smallvec",
4646
4854
"wayland-sys",
···
4653
4861
checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d"
4654
4862
dependencies = [
4655
4863
"bitflags 2.10.0",
4656
-
"rustix",
4864
+
"rustix 1.1.2",
4657
4865
"wayland-backend",
4658
4866
"wayland-scanner",
4659
4867
]
···
4667
4875
"bitflags 2.10.0",
4668
4876
"wayland-backend",
4669
4877
"wayland-client",
4878
+
"wayland-scanner",
4879
+
]
4880
+
4881
+
[[package]]
4882
+
name = "wayland-protocols-wlr"
4883
+
version = "0.3.9"
4884
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4885
+
checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec"
4886
+
dependencies = [
4887
+
"bitflags 2.10.0",
4888
+
"wayland-backend",
4889
+
"wayland-client",
4890
+
"wayland-protocols",
4670
4891
"wayland-scanner",
4671
4892
]
4672
4893
···
4781
5002
"windows",
4782
5003
"windows-core 0.61.2",
4783
5004
]
5005
+
5006
+
[[package]]
5007
+
name = "weezl"
5008
+
version = "0.1.12"
5009
+
source = "registry+https://github.com/rust-lang/crates.io-index"
5010
+
checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
4784
5011
4785
5012
[[package]]
4786
5013
name = "winapi"
···
5242
5469
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
5243
5470
5244
5471
[[package]]
5472
+
name = "wl-clipboard-rs"
5473
+
version = "0.9.2"
5474
+
source = "registry+https://github.com/rust-lang/crates.io-index"
5475
+
checksum = "8e5ff8d0e60065f549fafd9d6cb626203ea64a798186c80d8e7df4f8af56baeb"
5476
+
dependencies = [
5477
+
"libc",
5478
+
"log",
5479
+
"os_pipe",
5480
+
"rustix 0.38.44",
5481
+
"tempfile",
5482
+
"thiserror 2.0.17",
5483
+
"tree_magic_mini",
5484
+
"wayland-backend",
5485
+
"wayland-client",
5486
+
"wayland-protocols",
5487
+
"wayland-protocols-wlr",
5488
+
]
5489
+
5490
+
[[package]]
5245
5491
name = "writeable"
5246
5492
version = "0.6.2"
5247
5493
source = "registry+https://github.com/rust-lang/crates.io-index"
···
5312
5558
"once_cell",
5313
5559
"pkg-config",
5314
5560
]
5561
+
5562
+
[[package]]
5563
+
name = "x11rb"
5564
+
version = "0.13.2"
5565
+
source = "registry+https://github.com/rust-lang/crates.io-index"
5566
+
checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414"
5567
+
dependencies = [
5568
+
"gethostname",
5569
+
"rustix 1.1.2",
5570
+
"x11rb-protocol",
5571
+
]
5572
+
5573
+
[[package]]
5574
+
name = "x11rb-protocol"
5575
+
version = "0.13.2"
5576
+
source = "registry+https://github.com/rust-lang/crates.io-index"
5577
+
checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd"
5315
5578
5316
5579
[[package]]
5317
5580
name = "yoke"
···
5470
5733
"proc-macro2",
5471
5734
"quote",
5472
5735
"syn 2.0.109",
5736
+
]
5737
+
5738
+
[[package]]
5739
+
name = "zune-core"
5740
+
version = "0.4.12"
5741
+
source = "registry+https://github.com/rust-lang/crates.io-index"
5742
+
checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
5743
+
5744
+
[[package]]
5745
+
name = "zune-jpeg"
5746
+
version = "0.4.21"
5747
+
source = "registry+https://github.com/rust-lang/crates.io-index"
5748
+
checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713"
5749
+
dependencies = [
5750
+
"zune-core",
5473
5751
]
5474
5752
5475
5753
[[package]]
+1
src-tauri/Cargo.toml
+1
src-tauri/Cargo.toml
+3
-1
src-tauri/capabilities/default.json
+3
-1
src-tauri/capabilities/default.json
+2
-2
src-tauri/src/frontend_calls/close_app.rs
+2
-2
src-tauri/src/frontend_calls/close_app.rs
+9
-4
src-tauri/src/frontend_calls/load_previous_tabs.rs
+9
-4
src-tauri/src/frontend_calls/load_previous_tabs.rs
···
2
2
3
3
use tauri::{State, Window};
4
4
5
-
use crate::{ structs::nodes::Node, utils::config::Config };
5
+
use crate::{structs::nodes::Node, utils::config::Config};
6
6
7
7
#[tauri::command]
8
-
pub fn load_previous_tabs( window: Window, conf: State<Config> ) -> HashMap<String, ( Vec<Node>, String, Option<String> )> {
8
+
pub fn load_previous_tabs(
9
+
window: Window,
10
+
conf: State<Config>,
11
+
) -> HashMap<String, (Vec<Node>, String, Option<String>)> {
9
12
let config = conf.store.lock().unwrap();
10
13
11
-
if !config.hide_editor_on_start { window.show().unwrap(); }
14
+
if !config.hide_editor_on_start {
15
+
window.show().unwrap();
16
+
}
12
17
13
18
let tabs = config.loaded_tabs.clone();
14
19
tabs
15
-
}
20
+
}
+3
-3
src-tauri/src/frontend_calls/mod.rs
+3
-3
src-tauri/src/frontend_calls/mod.rs
+2
-2
src-tauri/src/frontend_calls/save_graph.rs
+2
-2
src-tauri/src/frontend_calls/save_graph.rs
···
1
1
use std::{fs::File, io::Write, path::PathBuf};
2
2
3
-
use flate2::{ write::GzEncoder, Compression };
3
+
use flate2::{write::GzEncoder, Compression};
4
4
use tauri::State;
5
5
6
6
use crate::utils::config::Config;
7
7
8
8
#[tauri::command]
9
-
pub fn save_graph( graph: String, path: PathBuf, conf: State<Config> ) {
9
+
pub fn save_graph(graph: String, path: PathBuf, conf: State<Config>) {
10
10
let file = File::create(&path).unwrap();
11
11
let mut encoder = GzEncoder::new(file, Compression::default());
12
12
+3
-3
src-tauri/src/frontend_calls/settings.rs
+3
-3
src-tauri/src/frontend_calls/settings.rs
···
3
3
use crate::utils::config::Config;
4
4
5
5
#[tauri::command]
6
-
pub fn set_hide_editor_on_app_start( value: bool, conf: State<Config> ){
6
+
pub fn set_hide_editor_on_app_start(value: bool, conf: State<Config>) {
7
7
let mut config = conf.store.lock().unwrap();
8
8
config.hide_editor_on_start = value;
9
9
}
10
10
11
11
#[tauri::command]
12
-
pub fn get_hide_editor_on_app_start( conf: State<Config> ) -> bool {
12
+
pub fn get_hide_editor_on_app_start(conf: State<Config>) -> bool {
13
13
let config = conf.store.lock().unwrap();
14
14
config.hide_editor_on_start
15
-
}
15
+
}
+15
-6
src-tauri/src/frontend_calls/sync_tab.rs
+15
-6
src-tauri/src/frontend_calls/sync_tab.rs
···
2
2
3
3
use tauri::State;
4
4
5
-
use crate::{ runtime::commands::RuntimeCommand, structs::nodes::Node, utils::config::Config };
5
+
use crate::{runtime::commands::RuntimeCommand, structs::nodes::Node, utils::config::Config};
6
6
7
7
#[tauri::command]
8
-
pub fn sync_tab( graph: Vec<Node>, id: String, name: String, location: Option<String>, cmd: State<Sender<RuntimeCommand>>, conf: State<Config> ){
9
-
cmd.send(RuntimeCommand::AddTab(graph.clone(), id.clone())).unwrap();
8
+
pub fn sync_tab(
9
+
graph: Vec<Node>,
10
+
id: String,
11
+
name: String,
12
+
location: Option<String>,
13
+
cmd: State<Sender<RuntimeCommand>>,
14
+
conf: State<Config>,
15
+
) {
16
+
cmd
17
+
.send(RuntimeCommand::AddTab(graph.clone(), id.clone()))
18
+
.unwrap();
10
19
11
20
let mut config = conf.store.lock().unwrap();
12
-
config.loaded_tabs.insert(id, ( graph, name, location )); // TODO: When loading a tab into config, store the save state of it too
21
+
config.loaded_tabs.insert(id, (graph, name, location)); // TODO: When loading a tab into config, store the save state of it too
13
22
}
14
23
15
24
#[tauri::command]
16
-
pub fn discard_tab( id: String, cmd: State<Sender<RuntimeCommand>>, conf: State<Config> ){
25
+
pub fn discard_tab(id: String, cmd: State<Sender<RuntimeCommand>>, conf: State<Config>) {
17
26
cmd.send(RuntimeCommand::RemoveTab(id.clone())).unwrap();
18
27
19
28
let mut config = conf.store.lock().unwrap();
20
29
config.loaded_tabs.remove(&id);
21
-
}
30
+
}
+5
-5
src-tauri/src/lib.rs
+5
-5
src-tauri/src/lib.rs
···
1
-
use std::{ fs, sync::Mutex };
1
+
use std::{fs, sync::Mutex};
2
2
3
3
use crossbeam_channel::bounded;
4
4
use frontend_calls::*;
5
5
6
-
use crate::{ osc::OSCMessage, setup::setup, utils::config::Config };
6
+
use crate::{osc::OSCMessage, setup::setup, utils::config::Config};
7
7
8
8
mod frontend_calls;
9
9
mod osc;
10
+
mod runtime;
10
11
mod setup;
11
12
mod structs;
12
13
mod utils;
13
-
mod runtime;
14
14
15
15
// TODO: Add built-in OSC endpoints
16
16
···
35
35
36
36
static ADDRESSES: Mutex<Vec<OSCMessage>> = Mutex::new(Vec::new());
37
37
38
-
let ( runtime_sender, runtime_receiver ) = bounded(1024);
38
+
let (runtime_sender, runtime_receiver) = bounded(1024);
39
39
40
40
tauri::Builder::default()
41
+
.plugin(tauri_plugin_clipboard_manager::init())
41
42
.plugin(tauri_plugin_dialog::init())
42
43
.plugin(tauri_plugin_opener::init())
43
44
.invoke_handler(tauri::generate_handler![
···
47
48
sync_tab::discard_tab,
48
49
load_previous_tabs::load_previous_tabs,
49
50
close_app::close_app,
50
-
51
51
settings::set_hide_editor_on_app_start,
52
52
settings::get_hide_editor_on_app_start,
53
53
])
+34
-20
src-tauri/src/runtime.rs
+34
-20
src-tauri/src/runtime.rs
···
1
-
use anyhow::{ bail, Result };
1
+
use anyhow::{bail, Result};
2
2
3
-
use crate::{ runtime::nodes::RuntimeNodeTree, structs::parameter_types::ParameterType };
3
+
use crate::{runtime::nodes::RuntimeNodeTree, structs::parameter_types::ParameterType};
4
4
5
-
pub mod nodes;
6
5
pub mod commands;
6
+
pub mod nodes;
7
7
8
8
// This is horrible. I know, I'm sorry.
9
9
10
-
pub fn runtime_dry( entry: String, parameters: &Vec<ParameterType>, tab: &mut RuntimeNodeTree ) -> Result<()>{
10
+
pub fn runtime_dry(
11
+
entry: String,
12
+
parameters: &Vec<ParameterType>,
13
+
tab: &mut RuntimeNodeTree,
14
+
) -> Result<()> {
11
15
let node = tab.nodes.get_mut(&entry);
12
-
if node.is_none(){ bail!("Cannot find node"); }
16
+
if node.is_none() {
17
+
bail!("Cannot find node");
18
+
}
13
19
14
20
let node = node.unwrap();
15
21
16
22
let output_map = node.outputs();
17
23
let args = node.execute_dry(parameters);
18
24
19
-
if args.is_some(){
25
+
if args.is_some() {
20
26
let args = args.unwrap();
21
27
22
-
for i in 0..args.len(){
28
+
for i in 0..args.len() {
23
29
let arg = &args[i];
24
30
25
-
for output in &output_map[i]{
26
-
if output.2 == 5{ break; } // Ignore flow outputs
31
+
for output in &output_map[i] {
32
+
if output.2 == 5 {
33
+
break;
34
+
} // Ignore flow outputs
27
35
28
36
let next_node = tab.nodes.get_mut(&output.0);
29
-
if next_node.is_none(){ bail!("Cannot find node {}", output.0) }
37
+
if next_node.is_none() {
38
+
bail!("Cannot find node {}", output.0)
39
+
}
30
40
31
41
let next_node = next_node.unwrap();
32
42
let can_update = next_node.update_arg(output.1 as usize, arg.clone());
33
43
34
-
if can_update{
44
+
if can_update {
35
45
runtime_dry(output.0.clone(), &vec![], tab)?;
36
46
}
37
47
}
···
41
51
Ok(())
42
52
}
43
53
44
-
pub fn runtime( entry: String, tab: &mut RuntimeNodeTree ) -> Result<()>{
54
+
pub fn runtime(entry: String, tab: &mut RuntimeNodeTree) -> Result<()> {
45
55
let node = tab.nodes.get_mut(&entry);
46
-
if node.is_none(){ bail!("Cannot find node"); }
56
+
if node.is_none() {
57
+
bail!("Cannot find node");
58
+
}
47
59
48
60
let node = node.unwrap();
49
61
50
62
let next = node.execute();
51
-
if next.is_some(){
63
+
if next.is_some() {
52
64
let next = next.unwrap();
53
65
54
66
let outputs = node.outputs();
55
67
56
-
for i in 0..next.len(){
68
+
for i in 0..next.len() {
57
69
let arg = &next[i];
58
-
if i >= outputs.len() { break; }
70
+
if i >= outputs.len() {
71
+
break;
72
+
}
59
73
60
-
for output in &outputs[i]{
61
-
if let ParameterType::Flow(next) = arg{
62
-
if *next{
74
+
for output in &outputs[i] {
75
+
if let ParameterType::Flow(next) = arg {
76
+
if *next {
63
77
// This is a flow output, continue
64
78
runtime(output.0.clone(), tab)?;
65
79
}
···
69
83
}
70
84
71
85
Ok(())
72
-
}
86
+
}
+4
-4
src-tauri/src/runtime/commands.rs
+4
-4
src-tauri/src/runtime/commands.rs
···
1
-
use crate::{ osc::OSCMessage, structs::nodes::Node };
1
+
use crate::{osc::OSCMessage, structs::nodes::Node};
2
2
3
3
#[derive(Debug)]
4
-
pub enum RuntimeCommand{
4
+
pub enum RuntimeCommand {
5
5
OSCMessage(OSCMessage),
6
6
7
7
AddTab(Vec<Node>, String),
8
-
RemoveTab(String)
9
-
}
8
+
RemoveTab(String),
9
+
}
+59
-28
src-tauri/src/runtime/nodes.rs
+59
-28
src-tauri/src/runtime/nodes.rs
···
1
1
use std::collections::HashMap;
2
2
3
-
use crate::{ runtime::nodes::{ conditional::{ ifequal::ConditionalIfEqual, iffalse::ConditionalIfFalse, iftrue::ConditionalIfTrue }, debug::Debug, oscactions::sendchatbox::OSCActionsSendChatbox, osctrigger::OSCTrigger, statics::{ float::StaticFloat, int::StaticInt, string::StaticString } }, structs::{ nodes::Node, parameter_types::ParameterType } };
3
+
use crate::{
4
+
runtime::nodes::{
5
+
conditional::{
6
+
ifequal::ConditionalIfEqual, iffalse::ConditionalIfFalse, iftrue::ConditionalIfTrue,
7
+
},
8
+
debug::Debug,
9
+
oscactions::sendchatbox::OSCActionsSendChatbox,
10
+
osctrigger::OSCTrigger,
11
+
statics::{float::StaticFloat, int::StaticInt, string::StaticString},
12
+
},
13
+
structs::{nodes::Node, parameter_types::ParameterType},
14
+
};
4
15
5
-
mod osctrigger;
16
+
mod conditional;
6
17
mod debug;
18
+
mod oscactions;
19
+
mod osctrigger;
7
20
mod statics;
8
-
mod conditional;
9
-
mod oscactions;
10
21
11
-
pub struct RuntimeNodeTree{
12
-
pub nodes: HashMap<String, Box<dyn RuntimeNode>>
22
+
pub struct RuntimeNodeTree {
23
+
pub nodes: HashMap<String, Box<dyn RuntimeNode>>,
13
24
}
14
25
15
-
unsafe impl Send for RuntimeNodeTree{}
26
+
unsafe impl Send for RuntimeNodeTree {}
16
27
17
-
impl RuntimeNodeTree{
18
-
pub fn from( tree: Vec<Node> ) -> Self{
28
+
impl RuntimeNodeTree {
29
+
pub fn from(tree: Vec<Node>) -> Self {
19
30
let mut runtime_nodes: HashMap<String, Box<dyn RuntimeNode>> = HashMap::new();
20
-
for node in tree{
21
-
match node.type_id.as_str(){
22
-
"osctrigger" => { runtime_nodes.insert(node.id.clone(), OSCTrigger::new(node)); }
31
+
for node in tree {
32
+
match node.type_id.as_str() {
33
+
"osctrigger" => {
34
+
runtime_nodes.insert(node.id.clone(), OSCTrigger::new(node));
35
+
}
23
36
24
-
"staticstring" => { runtime_nodes.insert(node.id.clone(), StaticString::new(node)); }
25
-
"staticint" => { runtime_nodes.insert(node.id.clone(), StaticInt::new(node)); }
26
-
"staticfloat" => { runtime_nodes.insert(node.id.clone(), StaticFloat::new(node)); }
37
+
"staticstring" => {
38
+
runtime_nodes.insert(node.id.clone(), StaticString::new(node));
39
+
}
40
+
"staticint" => {
41
+
runtime_nodes.insert(node.id.clone(), StaticInt::new(node));
42
+
}
43
+
"staticfloat" => {
44
+
runtime_nodes.insert(node.id.clone(), StaticFloat::new(node));
45
+
}
27
46
28
-
"iftrue" => { runtime_nodes.insert(node.id.clone(), ConditionalIfTrue::new(node)); }
29
-
"iffalse" => { runtime_nodes.insert(node.id.clone(), ConditionalIfFalse::new(node)); }
30
-
"ifequal" => { runtime_nodes.insert(node.id.clone(), ConditionalIfEqual::new(node)); }
47
+
"iftrue" => {
48
+
runtime_nodes.insert(node.id.clone(), ConditionalIfTrue::new(node));
49
+
}
50
+
"iffalse" => {
51
+
runtime_nodes.insert(node.id.clone(), ConditionalIfFalse::new(node));
52
+
}
53
+
"ifequal" => {
54
+
runtime_nodes.insert(node.id.clone(), ConditionalIfEqual::new(node));
55
+
}
31
56
32
-
"oscsendchatbox" => { runtime_nodes.insert(node.id.clone(), OSCActionsSendChatbox::new(node)); }
57
+
"oscsendchatbox" => {
58
+
runtime_nodes.insert(node.id.clone(), OSCActionsSendChatbox::new(node));
59
+
}
33
60
34
-
"debug" => { runtime_nodes.insert(node.id.clone(), Debug::new(node)); }
61
+
"debug" => {
62
+
runtime_nodes.insert(node.id.clone(), Debug::new(node));
63
+
}
35
64
_ => {}
36
65
}
37
66
}
38
67
39
-
Self { nodes: runtime_nodes }
68
+
Self {
69
+
nodes: runtime_nodes,
70
+
}
40
71
}
41
72
}
42
73
43
-
pub trait RuntimeNode{
44
-
fn outputs( &self ) -> Vec<Vec<( String, isize, isize )>>; // Node ID, input index, output value type
45
-
fn execute_dry( &mut self, msg: &Vec<ParameterType> ) -> Option<Vec<ParameterType>>; // Only update values on the first loop through
46
-
fn execute( &mut self ) -> Option<Vec<ParameterType>>; // Then call functions on the second loop
47
-
fn update_arg( &mut self, index: usize, value: ParameterType ) -> bool;
48
-
fn is_entrypoint( &self ) -> bool;
49
-
}
74
+
pub trait RuntimeNode {
75
+
fn outputs(&self) -> Vec<Vec<(String, isize, isize)>>; // Node ID, input index, output value type
76
+
fn execute_dry(&mut self, msg: &Vec<ParameterType>) -> Option<Vec<ParameterType>>; // Only update values on the first loop through
77
+
fn execute(&mut self) -> Option<Vec<ParameterType>>; // Then call functions on the second loop
78
+
fn update_arg(&mut self, index: usize, value: ParameterType) -> bool;
79
+
fn is_entrypoint(&self) -> bool;
80
+
}
+39
-21
src-tauri/src/runtime/nodes/conditional/ifequal.rs
+39
-21
src-tauri/src/runtime/nodes/conditional/ifequal.rs
···
1
-
use crate::{ runtime::nodes::RuntimeNode, structs::{ nodes::Node, parameter_types::ParameterType } };
1
+
use crate::{
2
+
runtime::nodes::RuntimeNode,
3
+
structs::{nodes::Node, parameter_types::ParameterType},
4
+
};
2
5
3
-
pub struct ConditionalIfEqual{
4
-
outputs: Vec<Vec<( String, isize, isize )>>,
6
+
pub struct ConditionalIfEqual {
7
+
outputs: Vec<Vec<(String, isize, isize)>>,
5
8
value1: ParameterType,
6
-
value2: ParameterType
9
+
value2: ParameterType,
7
10
}
8
11
9
-
impl ConditionalIfEqual{
10
-
pub fn new( node: Node ) -> Box<Self>{
12
+
impl ConditionalIfEqual {
13
+
pub fn new(node: Node) -> Box<Self> {
11
14
Box::new(Self {
12
-
outputs: node.outputs.iter()
13
-
.map(| x | {
14
-
x.connections.iter().map(| x | { ( x.node.clone(), x.index, x.value_type ) }).collect()
15
-
}).collect(),
15
+
outputs: node
16
+
.outputs
17
+
.iter()
18
+
.map(|x| {
19
+
x.connections
20
+
.iter()
21
+
.map(|x| (x.node.clone(), x.index, x.value_type))
22
+
.collect()
23
+
})
24
+
.collect(),
16
25
value1: ParameterType::None,
17
26
value2: ParameterType::None,
18
27
})
19
28
}
20
29
}
21
30
22
-
impl RuntimeNode for ConditionalIfEqual{
23
-
fn outputs( &self ) -> Vec<Vec<( String, isize, isize )>> { self.outputs.clone() }
24
-
fn execute_dry( &mut self, _: &Vec<ParameterType> ) -> Option<Vec<ParameterType>> { Some(vec![]) }
31
+
impl RuntimeNode for ConditionalIfEqual {
32
+
fn outputs(&self) -> Vec<Vec<(String, isize, isize)>> {
33
+
self.outputs.clone()
34
+
}
35
+
fn execute_dry(&mut self, _: &Vec<ParameterType>) -> Option<Vec<ParameterType>> {
36
+
Some(vec![])
37
+
}
25
38
26
-
fn execute( &mut self ) -> Option<Vec<ParameterType>> {
27
-
if self.value1 == ParameterType::None && self.value2 == ParameterType::None{
39
+
fn execute(&mut self) -> Option<Vec<ParameterType>> {
40
+
if self.value1 == ParameterType::None && self.value2 == ParameterType::None {
28
41
None
29
-
} else{
42
+
} else {
30
43
let equal = self.value1 == self.value2;
31
-
Some(vec![ ParameterType::Flow(equal), ParameterType::Flow(!equal) ])
44
+
Some(vec![
45
+
ParameterType::Flow(equal),
46
+
ParameterType::Flow(!equal),
47
+
])
32
48
}
33
49
}
34
50
35
-
fn update_arg( &mut self, index: usize, arg: ParameterType ) -> bool {
36
-
match index{
51
+
fn update_arg(&mut self, index: usize, arg: ParameterType) -> bool {
52
+
match index {
37
53
1 => {
38
54
self.value1 = arg;
39
55
}
···
46
62
false
47
63
}
48
64
49
-
fn is_entrypoint( &self ) -> bool { false }
50
-
}
65
+
fn is_entrypoint(&self) -> bool {
66
+
false
67
+
}
68
+
}
+39
-21
src-tauri/src/runtime/nodes/conditional/iffalse.rs
+39
-21
src-tauri/src/runtime/nodes/conditional/iffalse.rs
···
1
-
use crate::{ runtime::nodes::RuntimeNode, structs::{ nodes::Node, parameter_types::ParameterType } };
1
+
use crate::{
2
+
runtime::nodes::RuntimeNode,
3
+
structs::{nodes::Node, parameter_types::ParameterType},
4
+
};
2
5
3
-
pub struct ConditionalIfFalse{
4
-
outputs: Vec<Vec<( String, isize, isize )>>,
5
-
runtime_active: bool
6
+
pub struct ConditionalIfFalse {
7
+
outputs: Vec<Vec<(String, isize, isize)>>,
8
+
runtime_active: bool,
6
9
}
7
10
8
-
impl ConditionalIfFalse{
9
-
pub fn new( node: Node ) -> Box<Self>{
11
+
impl ConditionalIfFalse {
12
+
pub fn new(node: Node) -> Box<Self> {
10
13
Box::new(Self {
11
-
outputs: node.outputs.iter()
12
-
.map(| x | {
13
-
x.connections.iter().map(| x | { ( x.node.clone(), x.index, x.value_type ) }).collect()
14
-
}).collect(),
15
-
runtime_active: false
14
+
outputs: node
15
+
.outputs
16
+
.iter()
17
+
.map(|x| {
18
+
x.connections
19
+
.iter()
20
+
.map(|x| (x.node.clone(), x.index, x.value_type))
21
+
.collect()
22
+
})
23
+
.collect(),
24
+
runtime_active: false,
16
25
})
17
26
}
18
27
}
19
28
20
-
impl RuntimeNode for ConditionalIfFalse{
21
-
fn outputs( &self ) -> Vec<Vec<( String, isize, isize )>> { self.outputs.clone() }
22
-
fn execute_dry( &mut self, _: &Vec<ParameterType> ) -> Option<Vec<ParameterType>> { Some(vec![]) }
29
+
impl RuntimeNode for ConditionalIfFalse {
30
+
fn outputs(&self) -> Vec<Vec<(String, isize, isize)>> {
31
+
self.outputs.clone()
32
+
}
33
+
fn execute_dry(&mut self, _: &Vec<ParameterType>) -> Option<Vec<ParameterType>> {
34
+
Some(vec![])
35
+
}
23
36
24
-
fn execute( &mut self ) -> Option<Vec<ParameterType>> {
25
-
Some(vec![ ParameterType::Flow(!self.runtime_active), ParameterType::Flow(self.runtime_active) ])
37
+
fn execute(&mut self) -> Option<Vec<ParameterType>> {
38
+
Some(vec![
39
+
ParameterType::Flow(!self.runtime_active),
40
+
ParameterType::Flow(self.runtime_active),
41
+
])
26
42
}
27
43
28
-
fn update_arg( &mut self, _: usize, arg: ParameterType ) -> bool {
29
-
if arg.as_bool().unwrap(){
44
+
fn update_arg(&mut self, _: usize, arg: ParameterType) -> bool {
45
+
if arg.as_bool().unwrap() {
30
46
self.runtime_active = true;
31
47
true
32
-
} else{
48
+
} else {
33
49
self.runtime_active = false;
34
50
false
35
51
}
36
52
}
37
53
38
-
fn is_entrypoint( &self ) -> bool { false }
39
-
}
54
+
fn is_entrypoint(&self) -> bool {
55
+
false
56
+
}
57
+
}
+39
-21
src-tauri/src/runtime/nodes/conditional/iftrue.rs
+39
-21
src-tauri/src/runtime/nodes/conditional/iftrue.rs
···
1
-
use crate::{ runtime::nodes::RuntimeNode, structs::{ nodes::Node, parameter_types::ParameterType } };
1
+
use crate::{
2
+
runtime::nodes::RuntimeNode,
3
+
structs::{nodes::Node, parameter_types::ParameterType},
4
+
};
2
5
3
-
pub struct ConditionalIfTrue{
4
-
outputs: Vec<Vec<( String, isize, isize )>>,
5
-
runtime_active: bool
6
+
pub struct ConditionalIfTrue {
7
+
outputs: Vec<Vec<(String, isize, isize)>>,
8
+
runtime_active: bool,
6
9
}
7
10
8
-
impl ConditionalIfTrue{
9
-
pub fn new( node: Node ) -> Box<Self>{
11
+
impl ConditionalIfTrue {
12
+
pub fn new(node: Node) -> Box<Self> {
10
13
Box::new(Self {
11
-
outputs: node.outputs.iter()
12
-
.map(| x | {
13
-
x.connections.iter().map(| x | { ( x.node.clone(), x.index, x.value_type ) }).collect()
14
-
}).collect(),
15
-
runtime_active: false
14
+
outputs: node
15
+
.outputs
16
+
.iter()
17
+
.map(|x| {
18
+
x.connections
19
+
.iter()
20
+
.map(|x| (x.node.clone(), x.index, x.value_type))
21
+
.collect()
22
+
})
23
+
.collect(),
24
+
runtime_active: false,
16
25
})
17
26
}
18
27
}
19
28
20
-
impl RuntimeNode for ConditionalIfTrue{
21
-
fn outputs( &self ) -> Vec<Vec<( String, isize, isize )>> { self.outputs.clone() }
22
-
fn execute_dry( &mut self, _: &Vec<ParameterType> ) -> Option<Vec<ParameterType>> { Some(vec![]) }
29
+
impl RuntimeNode for ConditionalIfTrue {
30
+
fn outputs(&self) -> Vec<Vec<(String, isize, isize)>> {
31
+
self.outputs.clone()
32
+
}
33
+
fn execute_dry(&mut self, _: &Vec<ParameterType>) -> Option<Vec<ParameterType>> {
34
+
Some(vec![])
35
+
}
23
36
24
-
fn execute( &mut self ) -> Option<Vec<ParameterType>> {
25
-
Some(vec![ ParameterType::Flow(self.runtime_active), ParameterType::Flow(!self.runtime_active) ])
37
+
fn execute(&mut self) -> Option<Vec<ParameterType>> {
38
+
Some(vec![
39
+
ParameterType::Flow(self.runtime_active),
40
+
ParameterType::Flow(!self.runtime_active),
41
+
])
26
42
}
27
43
28
-
fn update_arg( &mut self, _: usize, arg: ParameterType ) -> bool {
29
-
if arg.as_bool().unwrap(){
44
+
fn update_arg(&mut self, _: usize, arg: ParameterType) -> bool {
45
+
if arg.as_bool().unwrap() {
30
46
self.runtime_active = true;
31
47
true
32
-
} else{
48
+
} else {
33
49
self.runtime_active = false;
34
50
false
35
51
}
36
52
}
37
53
38
-
fn is_entrypoint( &self ) -> bool { false }
39
-
}
54
+
fn is_entrypoint(&self) -> bool {
55
+
false
56
+
}
57
+
}
+2
-2
src-tauri/src/runtime/nodes/conditional/mod.rs
+2
-2
src-tauri/src/runtime/nodes/conditional/mod.rs
+23
-14
src-tauri/src/runtime/nodes/debug.rs
+23
-14
src-tauri/src/runtime/nodes/debug.rs
···
1
-
use crate::{ runtime::nodes::RuntimeNode, structs::{ nodes::Node, parameter_types::ParameterType } };
1
+
use crate::{
2
+
runtime::nodes::RuntimeNode,
3
+
structs::{nodes::Node, parameter_types::ParameterType},
4
+
};
2
5
3
-
pub struct Debug{
4
-
to_log: Option<ParameterType>
6
+
pub struct Debug {
7
+
to_log: Option<ParameterType>,
5
8
}
6
9
7
-
impl Debug{
8
-
pub fn new( _: Node ) -> Box<Self>{
10
+
impl Debug {
11
+
pub fn new(_: Node) -> Box<Self> {
9
12
Box::new(Self { to_log: None })
10
13
}
11
14
}
12
15
13
-
impl RuntimeNode for Debug{
14
-
fn outputs( &self ) -> Vec<Vec<( String, isize, isize )>> { vec![] }
15
-
fn execute_dry( &mut self, _: &Vec<ParameterType> ) -> Option<Vec<ParameterType>> { Some(vec![]) }
16
+
impl RuntimeNode for Debug {
17
+
fn outputs(&self) -> Vec<Vec<(String, isize, isize)>> {
18
+
vec![]
19
+
}
20
+
fn execute_dry(&mut self, _: &Vec<ParameterType>) -> Option<Vec<ParameterType>> {
21
+
Some(vec![])
22
+
}
16
23
17
-
fn execute( &mut self ) -> Option<Vec<ParameterType>> {
24
+
fn execute(&mut self) -> Option<Vec<ParameterType>> {
18
25
dbg!(&self.to_log);
19
26
self.to_log = None;
20
27
21
28
None
22
29
}
23
30
24
-
fn update_arg( &mut self, index: usize, value: ParameterType ) -> bool {
25
-
if index == 1{
31
+
fn update_arg(&mut self, index: usize, value: ParameterType) -> bool {
32
+
if index == 1 {
26
33
self.to_log = Some(value);
27
34
true
28
-
} else{
35
+
} else {
29
36
false
30
37
}
31
38
}
32
39
33
-
fn is_entrypoint( &self ) -> bool { false }
34
-
}
40
+
fn is_entrypoint(&self) -> bool {
41
+
false
42
+
}
43
+
}
+1
-1
src-tauri/src/runtime/nodes/oscactions/mod.rs
+1
-1
src-tauri/src/runtime/nodes/oscactions/mod.rs
+33
-19
src-tauri/src/runtime/nodes/oscactions/sendchatbox.rs
+33
-19
src-tauri/src/runtime/nodes/oscactions/sendchatbox.rs
···
1
1
use std::vec;
2
2
3
-
use crate::{ osc, runtime::nodes::RuntimeNode, structs::{ nodes::Node, parameter_types::ParameterType } };
3
+
use crate::{
4
+
osc,
5
+
runtime::nodes::RuntimeNode,
6
+
structs::{nodes::Node, parameter_types::ParameterType},
7
+
};
4
8
5
-
pub struct OSCActionsSendChatbox{
6
-
to_log: String
9
+
pub struct OSCActionsSendChatbox {
10
+
to_log: String,
7
11
}
8
12
9
-
impl OSCActionsSendChatbox{
10
-
pub fn new( _: Node ) -> Box<Self>{
13
+
impl OSCActionsSendChatbox {
14
+
pub fn new(_: Node) -> Box<Self> {
11
15
Box::new(Self { to_log: "".into() })
12
16
}
13
17
}
14
18
15
-
impl RuntimeNode for OSCActionsSendChatbox{
16
-
fn outputs( &self ) -> Vec<Vec<( String, isize, isize )>> { vec![] }
17
-
fn execute_dry( &mut self, _: &Vec<ParameterType> ) -> Option<Vec<ParameterType>> { Some(vec![]) }
19
+
impl RuntimeNode for OSCActionsSendChatbox {
20
+
fn outputs(&self) -> Vec<Vec<(String, isize, isize)>> {
21
+
vec![]
22
+
}
23
+
fn execute_dry(&mut self, _: &Vec<ParameterType>) -> Option<Vec<ParameterType>> {
24
+
Some(vec![])
25
+
}
18
26
19
-
fn execute( &mut self ) -> Option<Vec<ParameterType>> {
20
-
osc::send_message("/chatbox/input", vec![
21
-
ParameterType::String(self.to_log.clone()),
22
-
ParameterType::Boolean(true),
23
-
ParameterType::Boolean(false)
24
-
], "127.0.0.1:9000");
27
+
fn execute(&mut self) -> Option<Vec<ParameterType>> {
28
+
osc::send_message(
29
+
"/chatbox/input",
30
+
vec![
31
+
ParameterType::String(self.to_log.clone()),
32
+
ParameterType::Boolean(true),
33
+
ParameterType::Boolean(false),
34
+
],
35
+
"127.0.0.1:9000",
36
+
);
25
37
26
38
None
27
39
}
28
40
29
-
fn update_arg( &mut self, index: usize, value: ParameterType ) -> bool {
30
-
if index == 1{
41
+
fn update_arg(&mut self, index: usize, value: ParameterType) -> bool {
42
+
if index == 1 {
31
43
self.to_log = value.as_string().unwrap();
32
44
true
33
-
} else{
45
+
} else {
34
46
false
35
47
}
36
48
}
37
49
38
-
fn is_entrypoint( &self ) -> bool { false }
39
-
}
50
+
fn is_entrypoint(&self) -> bool {
51
+
false
52
+
}
53
+
}
+43
-26
src-tauri/src/runtime/nodes/osctrigger.rs
+43
-26
src-tauri/src/runtime/nodes/osctrigger.rs
···
1
-
use crate::{ runtime::nodes::RuntimeNode, structs::{ nodes::Node, parameter_types::ParameterType } };
1
+
use crate::{
2
+
runtime::nodes::RuntimeNode,
3
+
structs::{nodes::Node, parameter_types::ParameterType},
4
+
};
2
5
3
-
pub struct OSCTrigger{
4
-
outputs: Vec<Vec<( String, isize, isize )>>,
6
+
pub struct OSCTrigger {
7
+
outputs: Vec<Vec<(String, isize, isize)>>,
5
8
address: Option<String>,
6
-
runtime_active: bool
9
+
runtime_active: bool,
7
10
}
8
11
9
-
impl OSCTrigger{
10
-
pub fn new( node: Node ) -> Box<Self>{
12
+
impl OSCTrigger {
13
+
pub fn new(node: Node) -> Box<Self> {
11
14
let value = &node.statics[0].value;
12
15
13
16
Box::new(Self {
14
-
address: if value.is_null(){ None } else { Some(value.as_str().unwrap().to_owned()) },
15
-
outputs: node.outputs.iter()
16
-
.map(| x | {
17
-
x.connections.iter().map(| x | { ( x.node.clone(), x.index, x.value_type ) }).collect()
18
-
}).collect(),
19
-
runtime_active: false
17
+
address: if value.is_null() {
18
+
None
19
+
} else {
20
+
Some(value.as_str().unwrap().to_owned())
21
+
},
22
+
outputs: node
23
+
.outputs
24
+
.iter()
25
+
.map(|x| {
26
+
x.connections
27
+
.iter()
28
+
.map(|x| (x.node.clone(), x.index, x.value_type))
29
+
.collect()
30
+
})
31
+
.collect(),
32
+
runtime_active: false,
20
33
})
21
34
}
22
35
}
23
36
24
-
impl RuntimeNode for OSCTrigger{
25
-
fn outputs( &self ) -> Vec<Vec<( String, isize, isize )>> {
37
+
impl RuntimeNode for OSCTrigger {
38
+
fn outputs(&self) -> Vec<Vec<(String, isize, isize)>> {
26
39
self.outputs.clone()
27
40
}
28
41
29
-
fn execute_dry( &mut self, msg: &Vec<ParameterType> ) -> Option<Vec<ParameterType>> {
30
-
if self.address.is_none(){
42
+
fn execute_dry(&mut self, msg: &Vec<ParameterType>) -> Option<Vec<ParameterType>> {
43
+
if self.address.is_none() {
31
44
self.runtime_active = false;
32
-
return None
45
+
return None;
33
46
}
34
47
35
-
if let ParameterType::String(address) = &msg[0]{
36
-
if *address == *self.address.as_ref().unwrap(){
48
+
if let ParameterType::String(address) = &msg[0] {
49
+
if *address == *self.address.as_ref().unwrap() {
37
50
self.runtime_active = true;
38
51
Some(msg.clone())
39
52
// The first value is technically the address value,
40
53
// but this value gets ignored as the first output of
41
54
// the osctrigger node is a flow output which gets ignored
42
55
// on dry runs.
43
-
} else{
56
+
} else {
44
57
self.runtime_active = false;
45
58
None
46
59
}
47
-
} else{
60
+
} else {
48
61
self.runtime_active = false;
49
62
None
50
63
}
51
64
}
52
65
53
-
fn execute( &mut self ) -> Option<Vec<ParameterType>> {
66
+
fn execute(&mut self) -> Option<Vec<ParameterType>> {
54
67
let execute = self.runtime_active;
55
68
self.runtime_active = false;
56
69
57
-
Some(vec![ ParameterType::Flow(execute) ])
70
+
Some(vec![ParameterType::Flow(execute)])
58
71
}
59
72
60
-
fn update_arg( &mut self, _: usize, _: ParameterType ) -> bool { false }
61
-
fn is_entrypoint( &self ) -> bool { true }
62
-
}
73
+
fn update_arg(&mut self, _: usize, _: ParameterType) -> bool {
74
+
false
75
+
}
76
+
fn is_entrypoint(&self) -> bool {
77
+
true
78
+
}
79
+
}
+40
-21
src-tauri/src/runtime/nodes/statics/float.rs
+40
-21
src-tauri/src/runtime/nodes/statics/float.rs
···
1
-
use crate::{ runtime::nodes::RuntimeNode, structs::{ nodes::Node, parameter_types::ParameterType } };
1
+
use crate::{
2
+
runtime::nodes::RuntimeNode,
3
+
structs::{nodes::Node, parameter_types::ParameterType},
4
+
};
2
5
3
-
pub struct StaticFloat{
4
-
outputs: Vec<Vec<( String, isize, isize )>>,
5
-
value: Option<f32>
6
+
pub struct StaticFloat {
7
+
outputs: Vec<Vec<(String, isize, isize)>>,
8
+
value: Option<f32>,
6
9
}
7
10
8
-
impl StaticFloat{
9
-
pub fn new( node: Node ) -> Box<Self>{
11
+
impl StaticFloat {
12
+
pub fn new(node: Node) -> Box<Self> {
10
13
let value = &node.statics[0].value;
11
14
12
15
Box::new(Self {
13
-
value: if value.is_null(){ None } else { Some(value.as_f64().unwrap() as f32) },
14
-
outputs: node.outputs.iter()
15
-
.map(| x | {
16
-
x.connections.iter().map(| x | { ( x.node.clone(), x.index, x.value_type ) }).collect()
17
-
}).collect(),
16
+
value: if value.is_null() {
17
+
None
18
+
} else {
19
+
Some(value.as_f64().unwrap() as f32)
20
+
},
21
+
outputs: node
22
+
.outputs
23
+
.iter()
24
+
.map(|x| {
25
+
x.connections
26
+
.iter()
27
+
.map(|x| (x.node.clone(), x.index, x.value_type))
28
+
.collect()
29
+
})
30
+
.collect(),
18
31
})
19
32
}
20
33
}
21
34
22
-
impl RuntimeNode for StaticFloat{
23
-
fn outputs( &self ) -> Vec<Vec<( String, isize, isize )>> {
35
+
impl RuntimeNode for StaticFloat {
36
+
fn outputs(&self) -> Vec<Vec<(String, isize, isize)>> {
24
37
self.outputs.clone()
25
38
}
26
39
27
-
fn execute_dry( &mut self, _: &Vec<ParameterType> ) -> Option<Vec<ParameterType>> {
28
-
if self.value.is_some(){
29
-
Some(vec![ ParameterType::Float(self.value.clone().unwrap()) ])
30
-
} else{
40
+
fn execute_dry(&mut self, _: &Vec<ParameterType>) -> Option<Vec<ParameterType>> {
41
+
if self.value.is_some() {
42
+
Some(vec![ParameterType::Float(self.value.clone().unwrap())])
43
+
} else {
31
44
None
32
45
}
33
46
}
34
47
35
-
fn execute( &mut self ) -> Option<Vec<ParameterType>> { None }
48
+
fn execute(&mut self) -> Option<Vec<ParameterType>> {
49
+
None
50
+
}
36
51
37
-
fn update_arg( &mut self, _: usize, _: ParameterType ) -> bool { false }
38
-
fn is_entrypoint( &self ) -> bool { true }
39
-
}
52
+
fn update_arg(&mut self, _: usize, _: ParameterType) -> bool {
53
+
false
54
+
}
55
+
fn is_entrypoint(&self) -> bool {
56
+
true
57
+
}
58
+
}
+40
-21
src-tauri/src/runtime/nodes/statics/int.rs
+40
-21
src-tauri/src/runtime/nodes/statics/int.rs
···
1
-
use crate::{ runtime::nodes::RuntimeNode, structs::{ nodes::Node, parameter_types::ParameterType } };
1
+
use crate::{
2
+
runtime::nodes::RuntimeNode,
3
+
structs::{nodes::Node, parameter_types::ParameterType},
4
+
};
2
5
3
-
pub struct StaticInt{
4
-
outputs: Vec<Vec<( String, isize, isize )>>,
5
-
value: Option<i32>
6
+
pub struct StaticInt {
7
+
outputs: Vec<Vec<(String, isize, isize)>>,
8
+
value: Option<i32>,
6
9
}
7
10
8
-
impl StaticInt{
9
-
pub fn new( node: Node ) -> Box<Self>{
11
+
impl StaticInt {
12
+
pub fn new(node: Node) -> Box<Self> {
10
13
let value = &node.statics[0].value;
11
14
12
15
Box::new(Self {
13
-
value: if value.is_null(){ None } else { Some(value.as_i64().unwrap() as i32) },
14
-
outputs: node.outputs.iter()
15
-
.map(| x | {
16
-
x.connections.iter().map(| x | { ( x.node.clone(), x.index, x.value_type ) }).collect()
17
-
}).collect(),
16
+
value: if value.is_null() {
17
+
None
18
+
} else {
19
+
Some(value.as_i64().unwrap() as i32)
20
+
},
21
+
outputs: node
22
+
.outputs
23
+
.iter()
24
+
.map(|x| {
25
+
x.connections
26
+
.iter()
27
+
.map(|x| (x.node.clone(), x.index, x.value_type))
28
+
.collect()
29
+
})
30
+
.collect(),
18
31
})
19
32
}
20
33
}
21
34
22
-
impl RuntimeNode for StaticInt{
23
-
fn outputs( &self ) -> Vec<Vec<( String, isize, isize )>> {
35
+
impl RuntimeNode for StaticInt {
36
+
fn outputs(&self) -> Vec<Vec<(String, isize, isize)>> {
24
37
self.outputs.clone()
25
38
}
26
39
27
-
fn execute_dry( &mut self, _: &Vec<ParameterType> ) -> Option<Vec<ParameterType>> {
28
-
if self.value.is_some(){
29
-
Some(vec![ ParameterType::Int(self.value.clone().unwrap()) ])
30
-
} else{
40
+
fn execute_dry(&mut self, _: &Vec<ParameterType>) -> Option<Vec<ParameterType>> {
41
+
if self.value.is_some() {
42
+
Some(vec![ParameterType::Int(self.value.clone().unwrap())])
43
+
} else {
31
44
None
32
45
}
33
46
}
34
47
35
-
fn execute( &mut self ) -> Option<Vec<ParameterType>> { None }
48
+
fn execute(&mut self) -> Option<Vec<ParameterType>> {
49
+
None
50
+
}
36
51
37
-
fn update_arg( &mut self, _: usize, _: ParameterType ) -> bool { false }
38
-
fn is_entrypoint( &self ) -> bool { true }
39
-
}
52
+
fn update_arg(&mut self, _: usize, _: ParameterType) -> bool {
53
+
false
54
+
}
55
+
fn is_entrypoint(&self) -> bool {
56
+
true
57
+
}
58
+
}
+2
-2
src-tauri/src/runtime/nodes/statics/mod.rs
+2
-2
src-tauri/src/runtime/nodes/statics/mod.rs
+40
-21
src-tauri/src/runtime/nodes/statics/string.rs
+40
-21
src-tauri/src/runtime/nodes/statics/string.rs
···
1
-
use crate::{ runtime::nodes::RuntimeNode, structs::{ nodes::Node, parameter_types::ParameterType } };
1
+
use crate::{
2
+
runtime::nodes::RuntimeNode,
3
+
structs::{nodes::Node, parameter_types::ParameterType},
4
+
};
2
5
3
-
pub struct StaticString{
4
-
outputs: Vec<Vec<( String, isize, isize )>>,
5
-
value: Option<String>
6
+
pub struct StaticString {
7
+
outputs: Vec<Vec<(String, isize, isize)>>,
8
+
value: Option<String>,
6
9
}
7
10
8
-
impl StaticString{
9
-
pub fn new( node: Node ) -> Box<Self>{
11
+
impl StaticString {
12
+
pub fn new(node: Node) -> Box<Self> {
10
13
let value = &node.statics[0].value;
11
14
12
15
Box::new(Self {
13
-
value: if value.is_null(){ None } else { Some(value.as_str().unwrap().to_owned()) },
14
-
outputs: node.outputs.iter()
15
-
.map(| x | {
16
-
x.connections.iter().map(| x | { ( x.node.clone(), x.index, x.value_type ) }).collect()
17
-
}).collect(),
16
+
value: if value.is_null() {
17
+
None
18
+
} else {
19
+
Some(value.as_str().unwrap().to_owned())
20
+
},
21
+
outputs: node
22
+
.outputs
23
+
.iter()
24
+
.map(|x| {
25
+
x.connections
26
+
.iter()
27
+
.map(|x| (x.node.clone(), x.index, x.value_type))
28
+
.collect()
29
+
})
30
+
.collect(),
18
31
})
19
32
}
20
33
}
21
34
22
-
impl RuntimeNode for StaticString{
23
-
fn outputs( &self ) -> Vec<Vec<( String, isize, isize )>> {
35
+
impl RuntimeNode for StaticString {
36
+
fn outputs(&self) -> Vec<Vec<(String, isize, isize)>> {
24
37
self.outputs.clone()
25
38
}
26
39
27
-
fn execute_dry( &mut self, _: &Vec<ParameterType> ) -> Option<Vec<ParameterType>> {
28
-
if self.value.is_some(){
29
-
Some(vec![ ParameterType::String(self.value.clone().unwrap()) ])
30
-
} else{
40
+
fn execute_dry(&mut self, _: &Vec<ParameterType>) -> Option<Vec<ParameterType>> {
41
+
if self.value.is_some() {
42
+
Some(vec![ParameterType::String(self.value.clone().unwrap())])
43
+
} else {
31
44
None
32
45
}
33
46
}
34
47
35
-
fn execute( &mut self ) -> Option<Vec<ParameterType>> { None }
48
+
fn execute(&mut self) -> Option<Vec<ParameterType>> {
49
+
None
50
+
}
36
51
37
-
fn update_arg( &mut self, _: usize, _: ParameterType ) -> bool { false }
38
-
fn is_entrypoint( &self ) -> bool { true }
39
-
}
52
+
fn update_arg(&mut self, _: usize, _: ParameterType) -> bool {
53
+
false
54
+
}
55
+
fn is_entrypoint(&self) -> bool {
56
+
true
57
+
}
58
+
}
+42
-33
src-tauri/src/setup.rs
+42
-33
src-tauri/src/setup.rs
···
1
-
use std::{ collections::HashMap, fs::File, io::Read, sync::Mutex };
2
-
use crossbeam_channel::{ Receiver, bounded };
1
+
use crossbeam_channel::{bounded, Receiver};
2
+
use std::{collections::HashMap, fs::File, io::Read, sync::Mutex};
3
3
4
4
use flate2::read::GzDecoder;
5
-
use serde_json::{ Map, Value };
6
-
use tauri::{ App, Emitter, Listener, Manager, WindowEvent };
5
+
use serde_json::{Map, Value};
6
+
use tauri::{App, Emitter, Listener, Manager, WindowEvent};
7
7
8
-
use crate::{ osc::{ self, OSCMessage }, runtime::{ commands::RuntimeCommand, nodes::RuntimeNodeTree, runtime, runtime_dry }, structs::parameter_types::ParameterType, utils::setup_traymenu::setup_traymenu };
8
+
use crate::{
9
+
osc::{self, OSCMessage},
10
+
runtime::{commands::RuntimeCommand, nodes::RuntimeNodeTree, runtime, runtime_dry},
11
+
structs::parameter_types::ParameterType,
12
+
utils::setup_traymenu::setup_traymenu,
13
+
};
9
14
10
15
pub fn setup(
11
16
app: &mut App,
12
17
addresses: &'static Mutex<Vec<OSCMessage>>,
13
-
runtime_command_receiver: Receiver<RuntimeCommand>
18
+
runtime_command_receiver: Receiver<RuntimeCommand>,
14
19
) {
15
20
let window = app.get_webview_window("main").unwrap();
16
21
window.hide().unwrap();
17
22
18
23
let win_handle = window.clone();
19
-
window.on_window_event(move | event | {
20
-
match event{
21
-
WindowEvent::CloseRequested { api, .. } => {
22
-
api.prevent_close();
24
+
window.on_window_event(move |event| match event {
25
+
WindowEvent::CloseRequested { api, .. } => {
26
+
api.prevent_close();
23
27
24
-
win_handle.hide().unwrap();
25
-
win_handle.emit("hide-window", ()).unwrap();
26
-
}
27
-
_ => {}
28
+
win_handle.hide().unwrap();
29
+
win_handle.emit("hide-window", ()).unwrap();
28
30
}
31
+
_ => {}
29
32
});
30
33
31
34
setup_traymenu(app.handle());
···
49
52
handle.emit("load_new_tab", Value::Object(map)).unwrap();
50
53
});
51
54
52
-
let ( sender, receiver ) = bounded(1024);
55
+
let (sender, receiver) = bounded(1024);
53
56
54
57
tokio::spawn(async move {
55
58
osc::start_server(sender, "127.0.0.1:9001");
56
59
});
57
60
58
-
let ( runtime_sender, runtime_receiver ) = bounded(1024);
61
+
let (runtime_sender, runtime_receiver) = bounded(1024);
59
62
60
63
let runtime_sender_1 = runtime_sender.clone();
61
64
tokio::spawn(async move {
···
73
76
74
77
let msg = message.clone();
75
78
let mut addrs = addresses.lock().unwrap();
76
-
if !addrs.contains(&msg) { addrs.push(msg); }
79
+
if !addrs.contains(&msg) {
80
+
addrs.push(msg);
81
+
}
77
82
78
-
runtime_sender.send(RuntimeCommand::OSCMessage(message)).unwrap();
83
+
runtime_sender
84
+
.send(RuntimeCommand::OSCMessage(message))
85
+
.unwrap();
79
86
}
80
87
});
81
88
···
85
92
loop {
86
93
let cmd = runtime_receiver.recv().unwrap();
87
94
88
-
match cmd{
89
-
RuntimeCommand::OSCMessage( msg ) => {
90
-
for ( _, mut tab ) in &mut tabs{
91
-
let keys: Vec<String> = tab.nodes.keys().map(| x | { x.clone() }).collect();
95
+
match cmd {
96
+
RuntimeCommand::OSCMessage(msg) => {
97
+
for (_, mut tab) in &mut tabs {
98
+
let keys: Vec<String> = tab.nodes.keys().map(|x| x.clone()).collect();
92
99
93
-
for id in keys.clone(){
100
+
for id in keys.clone() {
94
101
let entry = tab.nodes[&id].is_entrypoint();
95
102
96
-
if entry{
103
+
if entry {
97
104
let args = vec![
98
-
vec![ ParameterType::String(msg.address.clone()) ], msg.values.clone()
99
-
].concat();
105
+
vec![ParameterType::String(msg.address.clone())],
106
+
msg.values.clone(),
107
+
]
108
+
.concat();
100
109
101
110
runtime_dry(id.clone(), &args, &mut tab).unwrap();
102
111
}
103
112
}
104
113
105
-
for id in keys{
114
+
for id in keys {
106
115
let entry = tab.nodes[&id].is_entrypoint();
107
116
108
-
if entry{
117
+
if entry {
109
118
let _ = runtime(id.clone(), &mut tab);
110
119
}
111
120
}
112
121
}
113
-
},
122
+
}
114
123
115
-
RuntimeCommand::AddTab( graph, id ) => {
124
+
RuntimeCommand::AddTab(graph, id) => {
116
125
tabs.insert(id, RuntimeNodeTree::from(graph));
117
-
},
118
-
RuntimeCommand::RemoveTab( id ) => {
126
+
}
127
+
RuntimeCommand::RemoveTab(id) => {
119
128
tabs.remove(&id);
120
129
}
121
130
}
122
131
}
123
132
});
124
-
}
133
+
}
+1
-1
src-tauri/src/structs/mod.rs
+1
-1
src-tauri/src/structs/mod.rs
+11
-11
src-tauri/src/structs/nodes.rs
+11
-11
src-tauri/src/structs/nodes.rs
···
1
-
use serde::{ Deserialize, Serialize };
1
+
use serde::{Deserialize, Serialize};
2
2
use serde_json::Value;
3
3
4
4
#[derive(Serialize, Deserialize, Debug, Clone)]
5
-
pub struct Node{
5
+
pub struct Node {
6
6
pub id: String,
7
7
pub name: String,
8
8
pub outputs: Vec<NodeOutput>,
9
-
pub pos: [ f32; 2 ],
9
+
pub pos: [f32; 2],
10
10
pub statics: Vec<NodeStatic>,
11
11
12
12
#[serde(rename = "typeId")]
13
-
pub type_id: String
13
+
pub type_id: String,
14
14
}
15
15
16
16
#[derive(Serialize, Deserialize, Debug, Clone)]
17
-
pub struct NodeStatic{
17
+
pub struct NodeStatic {
18
18
pub name: String,
19
19
20
20
#[serde(rename = "type")]
21
21
pub value_type: isize,
22
-
pub value: Value
22
+
pub value: Value,
23
23
}
24
24
25
25
#[derive(Serialize, Deserialize, Debug, Clone)]
26
-
pub struct NodeOutput{
26
+
pub struct NodeOutput {
27
27
pub name: String,
28
28
29
29
#[serde(rename = "type")]
30
30
pub value_type: isize,
31
-
pub connections: Vec<NodeOutputConnections>
31
+
pub connections: Vec<NodeOutputConnections>,
32
32
}
33
33
34
34
#[derive(Serialize, Deserialize, Debug, Clone)]
35
-
pub struct NodeOutputConnections{
35
+
pub struct NodeOutputConnections {
36
36
pub name: String,
37
37
pub node: String,
38
38
pub index: isize,
39
39
40
40
#[serde(rename = "type")]
41
-
pub value_type: isize
42
-
}
41
+
pub value_type: isize,
42
+
}
+41
-29
src-tauri/src/structs/parameter_types.rs
+41
-29
src-tauri/src/structs/parameter_types.rs
···
1
-
use anyhow::{ Result, bail };
1
+
use anyhow::{bail, Result};
2
2
use serde::Serialize;
3
3
4
4
#[derive(Serialize, Clone, Debug, PartialEq)]
···
13
13
String(String),
14
14
Flow(bool),
15
15
16
-
None
16
+
None,
17
17
}
18
18
19
-
impl ParameterType{
20
-
pub fn as_bool( &self ) -> Result<bool>{
21
-
match self{
22
-
ParameterType::Boolean( val ) => Ok(val.clone()),
23
-
ParameterType::Int( val ) => if *val == 0{ Ok(false) } else { Ok(true) },
24
-
_ => bail!("Cannot cast to bool.")
19
+
impl ParameterType {
20
+
pub fn as_bool(&self) -> Result<bool> {
21
+
match self {
22
+
ParameterType::Boolean(val) => Ok(val.clone()),
23
+
ParameterType::Int(val) => {
24
+
if *val == 0 {
25
+
Ok(false)
26
+
} else {
27
+
Ok(true)
28
+
}
29
+
}
30
+
_ => bail!("Cannot cast to bool."),
25
31
}
26
32
}
27
33
28
-
pub fn as_int( &self ) -> Result<i32>{
29
-
match self{
30
-
ParameterType::Boolean( val ) => if *val{ Ok(1) } else { Ok(0) },
31
-
ParameterType::Int( val ) => Ok(val.clone()),
32
-
ParameterType::Float( val ) => Ok(val.round().clone() as i32),
33
-
ParameterType::String( val ) => Ok(val.clone().parse()?),
34
-
_ => bail!("Cannot cast to int.")
34
+
pub fn as_int(&self) -> Result<i32> {
35
+
match self {
36
+
ParameterType::Boolean(val) => {
37
+
if *val {
38
+
Ok(1)
39
+
} else {
40
+
Ok(0)
41
+
}
42
+
}
43
+
ParameterType::Int(val) => Ok(val.clone()),
44
+
ParameterType::Float(val) => Ok(val.round().clone() as i32),
45
+
ParameterType::String(val) => Ok(val.clone().parse()?),
46
+
_ => bail!("Cannot cast to int."),
35
47
}
36
48
}
37
49
38
-
pub fn as_float( &self ) -> Result<f32>{
39
-
match self{
40
-
ParameterType::Int( val ) => Ok(val.clone() as f32),
41
-
ParameterType::Float( val ) => Ok(val.clone()),
42
-
ParameterType::String( val ) => Ok(val.clone().parse()?),
43
-
_ => bail!("Cannot cast to float.")
50
+
pub fn as_float(&self) -> Result<f32> {
51
+
match self {
52
+
ParameterType::Int(val) => Ok(val.clone() as f32),
53
+
ParameterType::Float(val) => Ok(val.clone()),
54
+
ParameterType::String(val) => Ok(val.clone().parse()?),
55
+
_ => bail!("Cannot cast to float."),
44
56
}
45
57
}
46
58
47
-
pub fn as_string( &self ) -> Result<String>{
48
-
match self{
49
-
ParameterType::Boolean( val ) => Ok(val.clone().to_string()),
50
-
ParameterType::Int( val ) => Ok(val.clone().to_string()),
51
-
ParameterType::Float( val ) => Ok(val.clone().to_string()),
52
-
ParameterType::String( val ) => Ok(val.clone()),
53
-
_ => bail!("Cannot cast to string.")
59
+
pub fn as_string(&self) -> Result<String> {
60
+
match self {
61
+
ParameterType::Boolean(val) => Ok(val.clone().to_string()),
62
+
ParameterType::Int(val) => Ok(val.clone().to_string()),
63
+
ParameterType::Float(val) => Ok(val.clone().to_string()),
64
+
ParameterType::String(val) => Ok(val.clone()),
65
+
_ => bail!("Cannot cast to string."),
54
66
}
55
67
}
56
-
}
68
+
}
+12
-6
src-tauri/src/utils/config.rs
+12
-6
src-tauri/src/utils/config.rs
···
1
-
use std::{ collections::HashMap, fs::File, io::{ Read, Write }, path::PathBuf, sync::Mutex };
1
+
use std::{
2
+
collections::HashMap,
3
+
fs::File,
4
+
io::{Read, Write},
5
+
path::PathBuf,
6
+
sync::Mutex,
7
+
};
2
8
3
-
use flate2::{ read::GzDecoder, write::GzEncoder, Compression };
4
-
use serde::{ Deserialize, Serialize };
9
+
use flate2::{read::GzDecoder, write::GzEncoder, Compression};
10
+
use serde::{Deserialize, Serialize};
5
11
6
12
use crate::structs::nodes::Node;
7
13
8
14
#[derive(Clone, Serialize, Deserialize, Debug)]
9
-
pub struct ConfigValues{
15
+
pub struct ConfigValues {
10
16
#[serde(default)]
11
-
pub loaded_tabs: HashMap<String, ( Vec<Node>, String, Option<String> )>,
17
+
pub loaded_tabs: HashMap<String, (Vec<Node>, String, Option<String>)>,
12
18
13
19
#[serde(default)]
14
-
pub hide_editor_on_start: bool
20
+
pub hide_editor_on_start: bool,
15
21
}
16
22
17
23
pub struct Config {
+1
-1
src-tauri/src/utils/mod.rs
+1
-1
src-tauri/src/utils/mod.rs
+4
-1
src/App.tsx
+4
-1
src/App.tsx
···
17
17
18
18
let App = () => {
19
19
let [ selectedNodes, setSelectedNodes ] = createSignal<Node[]>([], { equals: false });
20
+
let [ mousePos, setMousePos ] = createSignal<[ number, number ]>([ 0, 0 ]);
20
21
21
22
let canvas!: HTMLCanvasElement;
22
23
let ctx: CanvasRenderingContext2D;
···
233
234
}
234
235
235
236
canvas.onmousemove = ( e ) => {
237
+
setMousePos([ e.clientX, e.clientY ]);
238
+
236
239
if(e.shiftKey && isMouseDown){
237
240
let nodes = NodeManager.Instance.GetNodes();
238
241
let hoveredNode: Node | null = null;
···
399
402
isMouseDown = false;
400
403
}
401
404
402
-
keybinds.load(selectedNodes, setSelectedNodes);
405
+
keybinds.load(mousePos, selectedNodes, setSelectedNodes);
403
406
requestAnimationFrame(update);
404
407
405
408
let unlisten_0 = await listen('hide-window', () => {
+23
-5
src/keybinds.ts
+23
-5
src/keybinds.ts
···
1
1
import { Accessor, Setter } from "solid-js";
2
2
import { NodeManager } from "./Mangers/NodeManager";
3
3
import { Node } from "./structs/node";
4
+
import { readText, writeText } from "@tauri-apps/plugin-clipboard-manager";
5
+
import { decodeNodeList, encodeNodeList } from "./utils/clipboard";
4
6
5
7
let isKeyDown: any = {};
6
8
7
-
export let load = ( selectedNode: Accessor<Node[]>, setSelectedNode: Setter<Node[]> ) => {
8
-
// TODO: Copy / paste
9
+
export let load = ( mousePos: Accessor<[ number, number ]>, selectedNode: Accessor<Node[]>, setSelectedNode: Setter<Node[]> ) => {
9
10
// TODO: Add undo / redo -ing
10
11
11
-
window.onkeydown = ( e ) => {
12
+
window.onkeydown = async ( e ) => {
12
13
isKeyDown[e.key] = true;
13
-
14
-
console.log(e.key);
15
14
16
15
switch(e.key){
17
16
case 'Delete':
···
50
49
51
50
// Save
52
51
NodeManager.Instance.SaveTab(currentTab, true);
52
+
}
53
+
break;
54
+
case 'c':
55
+
if(e.ctrlKey){
56
+
let nodes = selectedNode();
57
+
await writeText(encodeNodeList(nodes, mousePos()));
58
+
}
59
+
break;
60
+
case 'v':
61
+
if(e.ctrlKey){
62
+
let text = await readText();
63
+
64
+
let nodes = await decodeNodeList(text, mousePos());
65
+
if(!nodes)return;
66
+
67
+
for(let node of nodes)
68
+
NodeManager.Instance.AddNode(node);
69
+
70
+
setSelectedNode(nodes);
53
71
}
54
72
break;
55
73
}
+41
src/utils/clipboard.ts
+41
src/utils/clipboard.ts
···
1
+
import { NodeManager } from "../Mangers/NodeManager";
2
+
import { NodesByID } from "../Nodes/Nodes";
3
+
import { Node } from "../structs/node";
4
+
5
+
export let encodeNodeList = ( selectedNodes: Node[], mousePos: [ number, number ] ): string => {
6
+
let arr: any[] = [];
7
+
8
+
for(let node of selectedNodes){
9
+
arr.push({
10
+
type_id: node.typeId,
11
+
statics: node.statics,
12
+
x: node.x - mousePos[0],
13
+
y: node.y - mousePos[1]
14
+
})
15
+
}
16
+
17
+
return 'VRCMACRO' + btoa(JSON.stringify(arr));
18
+
}
19
+
20
+
export let decodeNodeList = async ( text: string, mousePos: [ number, number ] ): Promise<Node[] | null> => {
21
+
if(!text.startsWith("VRCMACRO"))return null;
22
+
23
+
let data = text.slice(8);
24
+
let json = JSON.parse(atob(data));
25
+
26
+
let nodes: Node[] = [];
27
+
for(let node of json){
28
+
let n = new Node(
29
+
[ node.x + mousePos[0] + 10, node.y + mousePos[1] + 10 ],
30
+
NodesByID[node.type_id],
31
+
await NodeManager.Instance.GetNewNodeId()
32
+
);
33
+
34
+
n.statics = node.statics;
35
+
await n.onStaticsUpdate(n);
36
+
37
+
nodes.push(n);
38
+
}
39
+
40
+
return nodes;
41
+
}