Merge pull request #45 from osui-rs/access-cell

Access cell
This commit is contained in:
Klesti Selimaj
2026-01-31 15:04:56 +01:00
committed by GitHub
7 changed files with 390 additions and 317 deletions
+1
View File
@@ -23,6 +23,7 @@ path = "src/main.rs"
cc = "1.0" cc = "1.0"
[dependencies] [dependencies]
access-cell = "0.1.3"
crossterm = "0.28.1" crossterm = "0.28.1"
figlet-rs = "0.1.5" figlet-rs = "0.1.5"
osui-macros = { path = "macros" } osui-macros = { path = "macros" }
+226 -226
View File
@@ -1,227 +1,227 @@
Iterx72,Nestingx72,Time µs Iterx72,Nestingx72,Time µs
14,14,21945 14,14,14236
2,0,625 11,8,10608
13,3,1177 8,13,7793
0,13,581 13,7,12073
13,13,1134 11,6,10495
12,6,1266 5,2,5135
0,14,530 6,12,6144
8,11,1003 6,3,6341
12,1,1147 12,7,11304
8,10,1060 11,5,10622
14,12,1142 0,9,497
6,12,1136 3,2,3303
10,6,1057 5,1,5186
13,1,1182 10,8,9781
8,13,1230 1,11,1358
3,6,1165 2,9,2341
11,4,17474 10,11,9788
6,11,1050 14,5,13036
7,5,1155 9,1,8807
11,11,1322 4,12,4249
12,7,1094 8,1,8306
12,8,1045 14,4,12985
10,11,1079 5,0,419
5,8,1142 4,13,4234
2,1,1038 10,1,9793
3,0,638 3,13,3255
1,9,1027 0,4,625
0,11,522 7,6,7066
4,13,1049 8,12,7954
3,9,1079 10,12,9876
11,5,1111 8,11,8015
1,12,1037 6,8,6104
9,7,1106 0,11,514
4,11,1172 2,10,2373
2,9,1226 8,2,7891
8,3,1124 2,14,2337
8,7,1123 2,13,2337
4,0,744 7,12,7006
10,10,1146 3,10,3300
10,2,1184 11,10,10772
7,2,1813 4,5,4299
10,13,1113 10,14,9909
14,9,1925 12,5,11532
2,14,3131 9,10,8809
9,11,1112 12,12,11954
11,9,1069 14,11,13452
1,14,1137 8,8,7965
5,13,1097 4,0,449
4,6,3971 5,6,5127
14,6,1603 7,8,6921
7,0,1663 4,4,4244
3,12,1205 1,10,1370
10,12,1083 5,9,5122
0,0,1429 1,7,1369
0,4,687 0,3,844
4,2,1504 8,3,7937
3,13,1190 9,9,8777
7,3,1402 13,6,12476
6,14,1047 9,3,8961
2,2,1133 2,5,2368
4,12,1099 1,12,1363
10,3,3732 5,12,5075
6,10,1193 13,11,12363
4,14,1457 6,13,5963
5,12,1716 0,8,484
3,1,1130 2,12,2370
13,12,1157 8,5,7946
6,13,1201 14,9,13504
6,5,1693 12,1,11839
12,10,1045 12,2,11601
7,10,2915 2,6,2329
14,8,1831 10,10,9602
3,2,1142 7,3,6970
9,9,7308 14,6,13394
7,7,6848 0,7,628
12,12,1053 6,9,6100
8,14,1144 12,13,11391
10,5,1117 0,12,458
11,13,1056 1,14,1370
0,9,524 12,10,11719
7,4,1888 9,8,8807
7,13,1136 4,7,4235
0,10,522 1,0,462
12,4,2243 3,11,3538
0,3,812 11,7,10786
2,6,1721 11,13,10710
0,1,1237 11,2,10394
6,4,1187 3,9,3315
1,3,559 4,6,4174
11,0,1186 13,8,12538
1,8,1068 9,11,8710
2,11,1147 12,14,11814
11,1,1006 13,2,12647
7,12,1183 8,7,8019
12,13,1214 3,1,3287
2,3,1149 4,8,4591
8,4,1135 4,3,4197
9,2,1030 6,10,5985
13,4,858 5,7,5171
3,8,1163 12,9,11579
13,0,1392 10,4,9714
4,3,1170 12,4,11811
8,2,2436 2,3,2391
5,10,3718 8,9,7997
13,5,3525 9,7,8853
5,0,1120 11,1,10700
5,11,4088 11,11,10798
10,8,1205 13,4,12644
4,10,1032 6,4,6290
10,4,1072 6,2,5916
6,7,1394 2,0,427
3,5,3701 2,8,2355
12,11,1012 10,2,9637
7,6,1110 6,5,6069
11,10,2031 6,11,6048
14,4,1088 12,11,11921
13,2,2757 9,4,8754
7,9,1647 5,4,5111
11,2,1225 13,10,12518
9,0,1117 8,14,7837
14,0,1063 5,8,5127
4,1,1204 8,10,8085
12,2,1098 0,2,1028
0,7,599 2,1,2400
3,3,1366 0,13,408
14,5,1161 6,14,6027
10,14,1130 12,8,11785
4,4,1057 2,2,2326
9,3,1085 1,2,1394
6,1,1092 4,1,4251
11,7,1168 1,1,1446
13,9,1214 3,0,433
14,3,889 10,13,9693
2,8,1329 9,0,432
9,6,1104 1,3,1441
14,7,2015 9,13,8858
9,10,1102 9,14,8795
2,13,1177 11,9,10632
4,5,2013 12,0,417
2,5,1099 7,1,7013
1,7,1083 6,1,6097
1,1,812 10,7,10114
1,13,892 10,9,9876
7,11,1310 10,5,9802
6,6,5371 2,4,2363
8,8,1164 11,12,10781
3,7,2720 11,14,10677
14,11,1263 3,7,3262
14,14,1111 6,7,6201
5,9,1105 4,9,4380
1,5,982 3,8,3345
10,1,3444 13,9,12485
12,5,1016 0,14,419
2,10,1120 1,6,1347
9,1,1865 4,2,4216
4,7,4106 4,14,4209
1,0,648 7,9,6976
3,4,1566 13,0,458
5,3,1112 0,1,361
11,8,951 5,14,5204
2,4,1134 14,2,13169
3,10,1430 5,10,5096
6,0,727 1,5,1370
7,14,1216 8,0,431
13,14,1940 6,6,6031
9,12,1322 8,4,7809
6,2,1115 9,12,11983
9,4,1129 3,4,3276
4,9,4591 12,6,11921
2,7,1120 6,0,485
3,14,2022 1,13,1375
6,3,1107 4,11,4237
14,13,1028 0,10,481
6,8,6169 13,13,12545
7,8,1256 14,12,13253
12,3,1042 3,5,3210
8,1,1500 5,5,5158
6,9,1069 7,7,6992
12,14,1044 5,11,5076
13,7,21445 7,13,7056
10,7,1166 11,3,10584
0,2,808 3,3,3302
12,9,1067 14,13,13280
8,12,1182 13,3,12771
13,10,1615 14,0,429
1,6,1091 7,5,7065
9,8,1183 7,14,6952
8,6,1090 8,6,7835
10,9,1130 2,7,2334
5,2,1382 2,11,2367
12,0,1302 11,4,10606
1,11,984 7,11,6845
10,0,1070 14,8,13736
1,4,1162 0,5,844
7,1,1454 1,9,1333
8,9,1125 10,6,9721
4,8,3043 9,6,8769
14,1,1119 7,10,6998
5,4,1077 10,3,9810
5,14,1345 14,7,13311
11,14,1040 14,14,13481
0,6,604 11,0,426
9,13,2238 5,3,5102
13,8,1379 1,4,1457
11,6,1041 13,14,12431
11,3,5384 12,3,11717
3,11,1130 13,5,12523
9,14,859 14,10,13457
0,12,525 0,6,705
14,2,1527 3,14,3335
8,0,1137 13,12,12714
14,10,6363 7,4,6951
0,5,686 3,6,3247
11,12,1118 9,5,8713
5,6,3832 3,12,3401
5,7,1065 14,1,13199
5,1,1082 4,10,4260
1,10,990 10,0,428
0,8,609 5,13,5103
1,2,1036 0,0,421
9,5,1046 14,3,13070
13,6,3712 9,2,8816
13,11,1184 7,0,451
2,12,1164 7,2,6974
5,5,3398 1,8,1363
8,5,1119 13,1,12699
1 Iterx72 Nestingx72 Time µs
2 14 14 21945 14236
3 2 11 0 8 625 10608
4 13 8 3 13 1177 7793
5 0 13 13 7 581 12073
6 13 11 13 6 1134 10495
7 12 5 6 2 1266 5135
8 0 6 14 12 530 6144
9 8 6 11 3 1003 6341
10 12 1 7 1147 11304
11 8 11 10 5 1060 10622
12 14 0 12 9 1142 497
13 6 3 12 2 1136 3303
14 10 5 6 1 1057 5186
15 13 10 1 8 1182 9781
16 8 1 13 11 1230 1358
17 3 2 6 9 1165 2341
18 11 10 4 11 17474 9788
19 6 14 11 5 1050 13036
20 7 9 5 1 1155 8807
21 11 4 11 12 1322 4249
22 12 8 7 1 1094 8306
23 12 14 8 4 1045 12985
24 10 5 11 0 1079 419
25 5 4 8 13 1142 4234
26 2 10 1 1038 9793
27 3 0 13 638 3255
28 1 0 9 4 1027 625
29 0 7 11 6 522 7066
30 4 8 13 12 1049 7954
31 3 10 9 12 1079 9876
32 11 8 5 11 1111 8015
33 1 6 12 8 1037 6104
34 9 0 7 11 1106 514
35 4 2 11 10 1172 2373
36 2 8 9 2 1226 7891
37 8 2 3 14 1124 2337
38 8 2 7 13 1123 2337
39 4 7 0 12 744 7006
40 10 3 10 1146 3300
41 10 11 2 10 1184 10772
42 7 4 2 5 1813 4299
43 10 13 14 1113 9909
44 14 12 9 5 1925 11532
45 2 9 14 10 3131 8809
46 9 12 11 12 1112 11954
47 11 14 9 11 1069 13452
48 1 8 14 8 1137 7965
49 5 4 13 0 1097 449
50 4 5 6 3971 5127
51 14 7 6 8 1603 6921
52 7 4 0 4 1663 4244
53 3 1 12 10 1205 1370
54 10 5 12 9 1083 5122
55 0 1 0 7 1429 1369
56 0 4 3 687 844
57 4 8 2 3 1504 7937
58 3 9 13 9 1190 8777
59 7 13 3 6 1402 12476
60 6 9 14 3 1047 8961
61 2 2 5 1133 2368
62 4 1 12 1099 1363
63 10 5 3 12 3732 5075
64 6 13 10 11 1193 12363
65 4 6 14 13 1457 5963
66 5 0 12 8 1716 484
67 3 2 1 12 1130 2370
68 13 8 12 5 1157 7946
69 6 14 13 9 1201 13504
70 6 12 5 1 1693 11839
71 12 10 2 1045 11601
72 7 2 10 6 2915 2329
73 14 10 8 10 1831 9602
74 3 7 2 3 1142 6970
75 9 14 9 6 7308 13394
76 7 0 7 6848 628
77 12 6 12 9 1053 6100
78 8 12 14 13 1144 11391
79 10 0 5 12 1117 458
80 11 1 13 14 1056 1370
81 0 12 9 10 524 11719
82 7 9 4 8 1888 8807
83 7 4 13 7 1136 4235
84 0 1 10 0 522 462
85 12 3 4 11 2243 3538
86 0 11 3 7 812 10786
87 2 11 6 13 1721 10710
88 0 11 1 2 1237 10394
89 6 3 4 9 1187 3315
90 1 4 3 6 559 4174
91 11 13 0 8 1186 12538
92 1 9 8 11 1068 8710
93 2 12 11 14 1147 11814
94 11 13 1 2 1006 12647
95 7 8 12 7 1183 8019
96 12 3 13 1 1214 3287
97 2 4 3 8 1149 4591
98 8 4 4 3 1135 4197
99 9 6 2 10 1030 5985
100 13 5 4 7 858 5171
101 3 12 8 9 1163 11579
102 13 10 0 4 1392 9714
103 4 12 3 4 1170 11811
104 8 2 2 3 2436 2391
105 5 8 10 9 3718 7997
106 13 9 5 7 3525 8853
107 5 11 0 1 1120 10700
108 5 11 11 4088 10798
109 10 13 8 4 1205 12644
110 4 6 10 4 1032 6290
111 10 6 4 2 1072 5916
112 6 2 7 0 1394 427
113 3 2 5 8 3701 2355
114 12 10 11 2 1012 9637
115 7 6 6 5 1110 6069
116 11 6 10 11 2031 6048
117 14 12 4 11 1088 11921
118 13 9 2 4 2757 8754
119 7 5 9 4 1647 5111
120 11 13 2 10 1225 12518
121 9 8 0 14 1117 7837
122 14 5 0 8 1063 5127
123 4 8 1 10 1204 8085
124 12 0 2 1098 1028
125 0 2 7 1 599 2400
126 3 0 3 13 1366 408
127 14 6 5 14 1161 6027
128 10 12 14 8 1130 11785
129 4 2 4 2 1057 2326
130 9 1 3 2 1085 1394
131 6 4 1 1092 4251
132 11 1 7 1 1168 1446
133 13 3 9 0 1214 433
134 14 10 3 13 889 9693
135 2 9 8 0 1329 432
136 9 1 6 3 1104 1441
137 14 9 7 13 2015 8858
138 9 10 14 1102 8795
139 2 11 13 9 1177 10632
140 4 12 5 0 2013 417
141 2 7 5 1 1099 7013
142 1 6 7 1 1083 6097
143 1 10 1 7 812 10114
144 1 10 13 9 892 9876
145 7 10 11 5 1310 9802
146 6 2 6 4 5371 2363
147 8 11 8 12 1164 10781
148 3 11 7 14 2720 10677
149 14 3 11 7 1263 3262
150 14 6 14 7 1111 6201
151 5 4 9 1105 4380
152 1 3 5 8 982 3345
153 10 13 1 9 3444 12485
154 12 0 5 14 1016 419
155 2 1 10 6 1120 1347
156 9 4 1 2 1865 4216
157 4 7 14 4106 4209
158 1 7 0 9 648 6976
159 3 13 4 0 1566 458
160 5 0 3 1 1112 361
161 11 5 8 14 951 5204
162 2 14 4 2 1134 13169
163 3 5 10 1430 5096
164 6 1 0 5 727 1370
165 7 8 14 0 1216 431
166 13 6 14 6 1940 6031
167 9 8 12 4 1322 7809
168 6 9 2 12 1115 11983
169 9 3 4 1129 3276
170 4 12 9 6 4591 11921
171 2 6 7 0 1120 485
172 3 1 14 13 2022 1375
173 6 4 3 11 1107 4237
174 14 0 13 10 1028 481
175 6 13 8 13 6169 12545
176 7 14 8 12 1256 13253
177 12 3 3 5 1042 3210
178 8 5 1 5 1500 5158
179 6 7 9 7 1069 6992
180 12 5 14 11 1044 5076
181 13 7 7 13 21445 7056
182 10 11 7 3 1166 10584
183 0 3 2 3 808 3302
184 12 14 9 13 1067 13280
185 8 13 12 3 1182 12771
186 13 14 10 0 1615 429
187 1 7 6 5 1091 7065
188 9 7 8 14 1183 6952
189 8 6 1090 7835
190 10 2 9 7 1130 2334
191 5 2 2 11 1382 2367
192 12 11 0 4 1302 10606
193 1 7 11 984 6845
194 10 14 0 8 1070 13736
195 1 0 4 5 1162 844
196 7 1 1 9 1454 1333
197 8 10 9 6 1125 9721
198 4 9 8 6 3043 8769
199 14 7 1 10 1119 6998
200 5 10 4 3 1077 9810
201 5 14 14 7 1345 13311
202 11 14 14 1040 13481
203 0 11 6 0 604 426
204 9 5 13 3 2238 5102
205 13 1 8 4 1379 1457
206 11 13 6 14 1041 12431
207 11 12 3 5384 11717
208 3 13 11 5 1130 12523
209 9 14 14 10 859 13457
210 0 12 6 525 705
211 14 3 2 14 1527 3335
212 8 13 0 12 1137 12714
213 14 7 10 4 6363 6951
214 0 3 5 6 686 3247
215 11 9 12 5 1118 8713
216 5 3 6 12 3832 3401
217 5 14 7 1 1065 13199
218 5 4 1 10 1082 4260
219 1 10 10 0 990 428
220 0 5 8 13 609 5103
221 1 0 2 0 1036 421
222 9 14 5 3 1046 13070
223 13 9 6 2 3712 8816
224 13 7 11 0 1184 451
225 2 7 12 2 1164 6974
226 5 1 5 8 3398 1363
227 8 13 5 1 1119 12699
+5 -3
View File
@@ -76,13 +76,15 @@ fn emit_node_scope(node: &RsxNode) -> TokenStream {
{ {
#deps_emit #deps_emit
r.dynamic_scope(move |scope| { r.dynamic_scope(move |scope| {
scope.access_children(|children| {
if #cond { if #cond {
if scope.children.lock().unwrap().is_empty() { if children.is_empty() {
#(#kids)* #(#kids)*
} }
} else { } else {
scope.children.lock().unwrap().clear(); .children.clear();
} }
})
}, #deps_vec_emit); }, #deps_vec_emit);
} }
} }
@@ -103,7 +105,7 @@ fn emit_node_scope(node: &RsxNode) -> TokenStream {
#deps_emit #deps_emit
#[allow(unused_parens)] #[allow(unused_parens)]
r.dynamic_scope(move |scope| { r.dynamic_scope(move |scope| {
scope.children.lock().unwrap().clear(); scope.access_children(|children| children.clear());
for #pat in #expr { for #pat in #expr {
#(#kids)* #(#kids)*
} }
+111 -57
View File
@@ -4,6 +4,8 @@ use std::{
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use access_cell::AccessCell;
use crate::{ use crate::{
component::EventHandler, component::EventHandler,
engine::{Command, CommandExecutor}, engine::{Command, CommandExecutor},
@@ -15,10 +17,10 @@ use crate::{
use super::{scope::Scope, Component, ComponentImpl}; use super::{scope::Scope, Component, ComponentImpl};
pub struct Context { pub struct Context {
component: Mutex<Component>, component: AccessCell<Component>,
event_handlers: Mutex<HashMap<TypeId, Vec<EventHandler>>>, view: AccessCell<View>,
view: Mutex<View>, event_handlers: AccessCell<HashMap<TypeId, Vec<EventHandler>>>,
pub(crate) scopes: Mutex<Vec<Arc<Scope>>>, scopes: AccessCell<Vec<Arc<Scope>>>,
executor: Arc<dyn CommandExecutor>, executor: Arc<dyn CommandExecutor>,
} }
@@ -28,104 +30,135 @@ impl Context {
executor: Arc<dyn CommandExecutor>, executor: Arc<dyn CommandExecutor>,
) -> Arc<Self> { ) -> Arc<Self> {
Arc::new(Self { Arc::new(Self {
component: Mutex::new(Arc::new(component)), component: AccessCell::new(Arc::new(component)),
event_handlers: Mutex::new(HashMap::new()), view: AccessCell::new(Arc::new(|_| {})),
view: Mutex::new(Arc::new(|_| {})), event_handlers: AccessCell::new(HashMap::new()),
scopes: Mutex::new(Vec::new()), scopes: AccessCell::new(Vec::new()),
executor, executor,
}) })
} }
pub fn refresh(self: &Arc<Self>) { pub fn refresh(self: &Arc<Self>) {
self.event_handlers
.access(|event_handlers| event_handlers.clear());
self.component.access({
let s = self.clone(); let s = self.clone();
move |component| {
std::thread::spawn({ let component = component.clone();
move || { s.view.access({
s.event_handlers.lock().unwrap().clear(); let s = s.clone();
let c = s.component.lock().unwrap().clone(); move |view| *view = component.call(&s)
*s.view.lock().unwrap() = c.call(&s); })
} }
}); });
} }
pub fn refresh_atomic(self: &Arc<Self>) -> Arc<Mutex<bool>> { pub fn refresh_sync(self: &Arc<Self>) {
let s = self.clone(); let (tx, rx) = std::sync::mpsc::channel::<()>();
let done = Arc::new(Mutex::new(false));
std::thread::spawn({ self.event_handlers
let done = done.clone(); .access(|event_handlers| event_handlers.clear());
move || {
s.event_handlers.lock().unwrap().clear(); self.component.access({
let c = s.component.lock().unwrap().clone(); let s = self.clone();
*s.view.lock().unwrap() = c.call(&s); move |component| {
*done.lock().unwrap() = true; let component = component.clone();
s.view.access({
let s = s.clone();
let tx = tx.clone();
move |view| {
*view = component.call(&s);
let _ = tx.send(()); // signal completion
}
});
} }
}); });
done // BLOCK until view closure finishes
let _ = rx.recv();
} }
pub fn get_view(self: &Arc<Self>) -> View { pub fn get_view(self: &Arc<Self>) -> View {
self.view.lock().unwrap().clone() self.view.access_ref().clone()
} }
pub fn on_event<T: Any + 'static, F: Fn(&Arc<Self>, &T) + Send + Sync + 'static>( pub fn on_event<T: Any + 'static, F: Fn(&Arc<Self>, &T) + Send + Sync + 'static>(
self: &Arc<Self>, self: &Arc<Self>,
handler: F, handler: F,
) { ) {
self.event_handlers let new_handler: EventHandler =
.lock() Arc::new(Mutex::new(move |ctx: &Arc<Context>, event: &dyn Any| {
.unwrap()
.entry(TypeId::of::<T>())
.or_insert_with(|| Vec::new())
.push(Arc::new(Mutex::new(
move |ctx: &Arc<Self>, event: &dyn Any| {
if let Some(e) = event.downcast_ref::<T>() { if let Some(e) = event.downcast_ref::<T>() {
(handler)(ctx, e); (handler)(ctx, e);
} }
}, }));
))); self.event_handlers.access(|event_handlers| {
event_handlers
.entry(TypeId::of::<T>())
.or_insert_with(Vec::new)
.push(new_handler);
});
} }
pub fn emit_event<E: Any + 'static>(self: &Arc<Self>, event: &E) { pub fn emit_event<E: Send + Sync + Any + 'static>(self: &Arc<Self>, event: E) {
if let Some(v) = self.event_handlers.lock().unwrap().get(&TypeId::of::<E>()) { let event = Arc::new(event);
for i in v { let handlers_to_call: Vec<EventHandler> = {
(i.lock().unwrap())(self, event); let guard = self.event_handlers.access_ref();
} guard.get(&TypeId::of::<E>()).cloned().unwrap_or_default()
};
for h in &handlers_to_call {
(h.lock().unwrap())(self, event.as_ref());
} }
for scope in self.scopes.lock().unwrap().iter() { self.scopes.access(move |scopes| {
for (child, _) in scope.children.lock().unwrap().iter() { for scope in scopes {
child.emit_event(event); let event = event.clone();
scope.access_children(move |children| {
for (child, _) in children {
child.emit_event(event.clone());
} }
});
} }
});
} }
pub fn emit_event_threaded<E: Any + Send + Sync + Clone + 'static>( pub fn emit_event_threaded<E: Any + Send + Sync + Clone + 'static>(
self: &Arc<Self>, self: &Arc<Self>,
event: &E, event: &E,
) { ) {
if let Some(v) = self.event_handlers.lock().unwrap().get(&TypeId::of::<E>()) { let handlers_to_call: Vec<EventHandler> = {
for i in v { let guard = self.event_handlers.access_ref();
let i = i.clone(); guard.get(&TypeId::of::<E>()).cloned().unwrap_or_default()
};
for h in handlers_to_call {
let event = event.clone(); let event = event.clone();
let s = self.clone(); let s = self.clone();
std::thread::spawn(move || { std::thread::spawn(move || {
(i.lock().unwrap())(&s, &event); (h.lock().unwrap())(&s, &event);
}); });
} }
}
for scope in self.scopes.lock().unwrap().iter() { let event = event.clone();
for (child, _) in scope.children.lock().unwrap().iter() { self.scopes.access(move |scopes| {
child.emit_event_threaded(event); for scope in scopes {
let event = event.clone();
scope.access_children(move |children| {
for (child, _) in children {
child.emit_event_threaded(&event);
} }
});
} }
});
} }
pub fn scope(self: &Arc<Self>) -> Arc<Scope> { pub fn scope(self: &Arc<Self>) -> Arc<Scope> {
let scope = Scope::new(self.executor.clone()); let scope = Scope::new(self.executor.clone());
self.scopes.lock().unwrap().push(scope.clone());
self.scopes.access({
let scope = scope.clone();
move |scopes| scopes.push(scope)
});
scope scope
} }
@@ -136,7 +169,11 @@ impl Context {
dependencies: &[&dyn HookDependency], dependencies: &[&dyn HookDependency],
) -> Arc<Scope> { ) -> Arc<Scope> {
let scope = Scope::new(self.executor.clone()); let scope = Scope::new(self.executor.clone());
self.scopes.lock().unwrap().push(scope.clone());
self.scopes.access({
let scope = scope.clone();
move |scopes| scopes.push(scope)
});
drawer(&scope); drawer(&scope);
@@ -153,18 +190,35 @@ impl Context {
scope scope
} }
pub fn add_scope(self: &Arc<Self>, scope: Arc<Scope>) {
self.scopes.access(|scopes| scopes.push(scope));
}
pub fn draw_children(self: &Arc<Self>, ctx: &mut DrawContext) { pub fn draw_children(self: &Arc<Self>, ctx: &mut DrawContext) {
for scope in self.scopes.lock().unwrap().iter() { let c = ctx.clone();
for (child, view_wrapper) in scope.children.lock().unwrap().iter() {
let (tx, rx) = std::sync::mpsc::channel::<DrawContext>();
self.scopes.access(move |scopes| {
for scope in scopes {
let mut c = c.clone();
let tx = tx.clone();
scope.access_children(move |children| {
for (child, view_wrapper) in children {
let view = child.get_view(); let view = child.get_view();
if let Some(view_wrapper) = view_wrapper { if let Some(view_wrapper) = view_wrapper {
view_wrapper(ctx, view) view_wrapper(&mut c, view)
} else { } else {
ctx.draw_view(ctx.area.clone(), view); c.draw_view(c.area.clone(), view);
} }
} }
tx.send(c.clone()).expect("Failed transmitting DrawContext");
});
} }
});
*ctx = rx.recv().expect("Failed receiving DrawContext");
} }
pub fn get_executor(self: &Arc<Self>) -> Arc<dyn CommandExecutor> { pub fn get_executor(self: &Arc<Self>) -> Arc<dyn CommandExecutor> {
+23 -8
View File
@@ -1,18 +1,19 @@
use std::sync::{Arc, Mutex};
use crate::{engine::CommandExecutor, View, ViewWrapper};
use super::{context::Context, ComponentImpl}; use super::{context::Context, ComponentImpl};
use crate::{engine::CommandExecutor, View, ViewWrapper};
use access_cell::AccessCell;
use std::sync::Arc;
pub type ScopeChildren = Vec<(Arc<Context>, Option<ViewWrapper>)>;
pub struct Scope { pub struct Scope {
pub children: Mutex<Vec<(Arc<Context>, Option<ViewWrapper>)>>, children: AccessCell<ScopeChildren>,
executor: Arc<dyn CommandExecutor>, executor: Arc<dyn CommandExecutor>,
} }
impl Scope { impl Scope {
pub fn new(executor: Arc<dyn CommandExecutor>) -> Arc<Self> { pub fn new(executor: Arc<dyn CommandExecutor>) -> Arc<Self> {
Arc::new(Self { Arc::new(Self {
children: Mutex::new(Vec::new()), children: AccessCell::new(Vec::new()),
executor, executor,
}) })
} }
@@ -26,7 +27,8 @@ impl Scope {
ctx.refresh(); ctx.refresh();
self.children.lock().unwrap().push((ctx, view_wrapper)); self.children
.access(|children| children.push((ctx, view_wrapper)));
} }
pub fn view(self: &Arc<Self>, view: View) { pub fn view(self: &Arc<Self>, view: View) {
@@ -34,6 +36,19 @@ impl Scope {
ctx.refresh(); ctx.refresh();
self.children.lock().unwrap().push((ctx, None)); self.children.access(|children| children.push((ctx, None)));
}
pub fn view_wrapper(self: &Arc<Self>, view: View, view_wrapper: Option<ViewWrapper>) {
let ctx = Context::new(view, self.executor.clone());
ctx.refresh();
self.children
.access(|children| children.push((ctx, view_wrapper)));
}
pub fn access_children(self: &Arc<Self>, f: impl FnOnce(&mut ScopeChildren) + Send + 'static) {
self.children.access(f);
} }
} }
+1 -1
View File
@@ -50,7 +50,7 @@ impl Rsx {
RsxScope::Static(scope_fn) => { RsxScope::Static(scope_fn) => {
let scope = Scope::new(executor.clone()); let scope = Scope::new(executor.clone());
(scope_fn)(&scope); (scope_fn)(&scope);
context.scopes.lock().unwrap().push(scope) context.add_scope(scope)
} }
RsxScope::Dynamic(drawer, dependencies) => { RsxScope::Dynamic(drawer, dependencies) => {
let drawer = drawer.clone(); let drawer = drawer.clone();
+3 -2
View File
@@ -192,7 +192,7 @@ pub fn use_sync_state<
pub fn use_sync_effect< pub fn use_sync_effect<
T: Send + Sync + 'static, T: Send + Sync + 'static,
Ev: 'static, Ev: Send + Sync + 'static,
E: Fn(&State<T>) -> Ev + Send + Sync + 'static, E: Fn(&State<T>) -> Ev + Send + Sync + 'static,
>( >(
cx: &Arc<Context>, cx: &Arc<Context>,
@@ -205,7 +205,8 @@ pub fn use_sync_effect<
let state = state.clone(); let state = state.clone();
let cx = cx.clone(); let cx = cx.clone();
move || { move || {
cx.emit_event(&encoder(&state)); let ev = encoder(&state);
cx.emit_event(ev);
} }
}, },
deps, deps,