Merge pull request #46 from osui-rs/scope-performance-patch
Scope performance patch
This commit is contained in:
@@ -17,21 +17,23 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<b>OSUI is a customizable terminal user interface (TUI) library written in Rust. It provides a set of components and rsx to build interactive command-line interfaces with ease.</b>
|
<b>OSUI is a customizable terminal user interface (TUI) library written in Rust.</b>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use osui::prelude::*;
|
use osui::prelude::*;
|
||||||
|
|
||||||
fn main() -> std::io::Result<()> {
|
pub fn main() {
|
||||||
let screen = Screen::new();
|
let engine = Console::new();
|
||||||
|
engine.run(App {}).expect("Failed to run engine");
|
||||||
rsx! {
|
|
||||||
"Hello, World"
|
|
||||||
}
|
}
|
||||||
.draw(&screen);
|
|
||||||
|
|
||||||
screen.run()
|
#[component]
|
||||||
|
fn App(cx: &Arc<Context>) -> View {
|
||||||
|
rsx! {
|
||||||
|
"Hello World"
|
||||||
|
}
|
||||||
|
.view(&cx)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
+226
-226
@@ -1,227 +1,227 @@
|
|||||||
Iterx72,Nestingx72,Time µs
|
Iterx72,Nestingx72,Time µs
|
||||||
14,14,14236
|
14,14,11964
|
||||||
11,8,10608
|
0,1,1078
|
||||||
8,13,7793
|
5,8,1818
|
||||||
13,7,12073
|
10,13,2632
|
||||||
11,6,10495
|
14,2,3392
|
||||||
5,2,5135
|
0,9,520
|
||||||
6,12,6144
|
9,3,2360
|
||||||
6,3,6341
|
10,5,2551
|
||||||
12,7,11304
|
10,11,2548
|
||||||
11,5,10622
|
6,8,1738
|
||||||
0,9,497
|
12,12,2922
|
||||||
3,2,3303
|
0,8,601
|
||||||
5,1,5186
|
12,4,2919
|
||||||
10,8,9781
|
0,11,521
|
||||||
1,11,1358
|
6,4,1942
|
||||||
2,9,2341
|
11,7,2741
|
||||||
10,11,9788
|
9,4,2496
|
||||||
14,5,13036
|
5,9,1764
|
||||||
9,1,8807
|
13,9,3069
|
||||||
4,12,4249
|
2,5,1053
|
||||||
8,1,8306
|
5,11,1790
|
||||||
14,4,12985
|
14,1,3581
|
||||||
5,0,419
|
5,0,962
|
||||||
4,13,4234
|
0,3,845
|
||||||
10,1,9793
|
1,3,868
|
||||||
3,13,3255
|
7,8,2013
|
||||||
0,4,625
|
12,3,2987
|
||||||
7,6,7066
|
9,8,2328
|
||||||
8,12,7954
|
10,7,2533
|
||||||
10,12,9876
|
11,1,2766
|
||||||
8,11,8015
|
7,1,1938
|
||||||
6,8,6104
|
0,5,687
|
||||||
0,11,514
|
6,9,1830
|
||||||
2,10,2373
|
10,14,2628
|
||||||
8,2,7891
|
6,12,1786
|
||||||
2,14,2337
|
4,0,835
|
||||||
2,13,2337
|
4,14,2464
|
||||||
7,12,7006
|
10,1,2633
|
||||||
3,10,3300
|
12,7,2948
|
||||||
11,10,10772
|
2,9,1066
|
||||||
4,5,4299
|
4,6,2646
|
||||||
10,14,9909
|
7,11,1999
|
||||||
12,5,11532
|
5,13,1748
|
||||||
9,10,8809
|
13,4,3110
|
||||||
12,12,11954
|
13,13,3094
|
||||||
14,11,13452
|
3,5,1166
|
||||||
8,8,7965
|
11,12,2745
|
||||||
4,0,449
|
1,2,814
|
||||||
5,6,5127
|
9,5,2419
|
||||||
7,8,6921
|
2,11,1117
|
||||||
4,4,4244
|
1,13,835
|
||||||
1,10,1370
|
11,11,2759
|
||||||
5,9,5122
|
1,12,882
|
||||||
1,7,1369
|
9,1,2457
|
||||||
0,3,844
|
0,6,680
|
||||||
8,3,7937
|
5,12,1794
|
||||||
9,9,8777
|
9,11,2326
|
||||||
13,6,12476
|
10,9,2546
|
||||||
9,3,8961
|
10,10,2604
|
||||||
2,5,2368
|
13,2,3250
|
||||||
1,12,1363
|
13,7,3113
|
||||||
5,12,5075
|
7,10,1959
|
||||||
13,11,12363
|
1,14,833
|
||||||
6,13,5963
|
6,6,1886
|
||||||
0,8,484
|
14,7,3339
|
||||||
2,12,2370
|
6,7,1824
|
||||||
8,5,7946
|
11,6,2756
|
||||||
14,9,13504
|
12,6,3007
|
||||||
12,1,11839
|
14,6,3315
|
||||||
12,2,11601
|
4,3,11464
|
||||||
2,6,2329
|
2,14,924
|
||||||
10,10,9602
|
7,12,1966
|
||||||
7,3,6970
|
11,14,2817
|
||||||
14,6,13394
|
9,10,2367
|
||||||
0,7,628
|
1,11,827
|
||||||
6,9,6100
|
8,14,2184
|
||||||
12,13,11391
|
14,0,643
|
||||||
0,12,458
|
11,3,2781
|
||||||
1,14,1370
|
2,4,1123
|
||||||
12,10,11719
|
12,8,2950
|
||||||
9,8,8807
|
13,6,3160
|
||||||
4,7,4235
|
3,13,1289
|
||||||
1,0,462
|
7,7,1989
|
||||||
3,11,3538
|
3,9,1142
|
||||||
11,7,10786
|
3,6,1168
|
||||||
11,13,10710
|
4,8,2788
|
||||||
11,2,10394
|
14,12,3346
|
||||||
3,9,3315
|
1,1,805
|
||||||
4,6,4174
|
5,10,1781
|
||||||
13,8,12538
|
7,13,1988
|
||||||
9,11,8710
|
5,5,2015
|
||||||
12,14,11814
|
0,14,520
|
||||||
13,2,12647
|
11,8,2890
|
||||||
8,7,8019
|
3,10,1140
|
||||||
3,1,3287
|
13,10,3235
|
||||||
4,8,4591
|
3,14,1185
|
||||||
4,3,4197
|
8,10,2183
|
||||||
6,10,5985
|
12,10,2896
|
||||||
5,7,5171
|
2,8,1072
|
||||||
12,9,11579
|
9,6,2358
|
||||||
10,4,9714
|
13,1,3066
|
||||||
12,4,11811
|
3,8,1133
|
||||||
2,3,2391
|
11,10,2758
|
||||||
8,9,7997
|
4,13,2550
|
||||||
9,7,8853
|
1,0,643
|
||||||
11,1,10700
|
4,2,5482
|
||||||
11,11,10798
|
3,7,1155
|
||||||
13,4,12644
|
1,4,726
|
||||||
6,4,6290
|
3,3,1192
|
||||||
6,2,5916
|
4,11,2576
|
||||||
2,0,427
|
8,0,619
|
||||||
2,8,2355
|
9,2,2444
|
||||||
10,2,9637
|
10,3,2581
|
||||||
6,5,6069
|
4,5,5400
|
||||||
6,11,6048
|
5,3,2444
|
||||||
12,11,11921
|
1,10,804
|
||||||
9,4,8754
|
10,2,2563
|
||||||
5,4,5111
|
0,7,592
|
||||||
13,10,12518
|
0,2,802
|
||||||
8,14,7837
|
1,5,741
|
||||||
5,8,5127
|
2,7,984
|
||||||
8,10,8085
|
10,0,755
|
||||||
0,2,1028
|
13,14,3112
|
||||||
2,1,2400
|
5,14,1811
|
||||||
0,13,408
|
8,12,2180
|
||||||
6,14,6027
|
6,11,1723
|
||||||
12,8,11785
|
4,7,2897
|
||||||
2,2,2326
|
10,8,2536
|
||||||
1,2,1394
|
1,7,813
|
||||||
4,1,4251
|
6,0,699
|
||||||
1,1,1446
|
8,2,2187
|
||||||
3,0,433
|
5,7,1811
|
||||||
10,13,9693
|
14,8,3304
|
||||||
9,0,432
|
2,0,661
|
||||||
1,3,1441
|
8,13,2185
|
||||||
9,13,8858
|
1,9,786
|
||||||
9,14,8795
|
3,0,623
|
||||||
11,9,10632
|
12,5,3012
|
||||||
12,0,417
|
8,1,2203
|
||||||
7,1,7013
|
8,11,2285
|
||||||
6,1,6097
|
14,10,3413
|
||||||
10,7,10114
|
4,10,2613
|
||||||
10,9,9876
|
11,5,2729
|
||||||
10,5,9802
|
6,1,2035
|
||||||
2,4,2363
|
12,1,2891
|
||||||
11,12,10781
|
5,4,2036
|
||||||
11,14,10677
|
2,3,1083
|
||||||
3,7,3262
|
14,3,3312
|
||||||
6,7,6201
|
3,2,1278
|
||||||
4,9,4380
|
5,2,2392
|
||||||
3,8,3345
|
8,7,2151
|
||||||
13,9,12485
|
5,6,2072
|
||||||
0,14,419
|
3,12,1230
|
||||||
1,6,1347
|
2,10,954
|
||||||
4,2,4216
|
2,13,932
|
||||||
4,14,4209
|
13,8,3128
|
||||||
7,9,6976
|
0,12,521
|
||||||
13,0,458
|
11,4,2769
|
||||||
0,1,361
|
7,2,1947
|
||||||
5,14,5204
|
4,1,1802
|
||||||
14,2,13169
|
8,8,2163
|
||||||
5,10,5096
|
7,3,1966
|
||||||
1,5,1370
|
13,3,3207
|
||||||
8,0,431
|
1,8,746
|
||||||
6,6,6031
|
12,9,2955
|
||||||
8,4,7809
|
10,12,2570
|
||||||
9,12,11983
|
9,9,2388
|
||||||
3,4,3276
|
4,12,2566
|
||||||
12,6,11921
|
7,0,619
|
||||||
6,0,485
|
7,9,2004
|
||||||
1,13,1375
|
13,0,607
|
||||||
4,11,4237
|
14,9,3355
|
||||||
0,10,481
|
3,4,1154
|
||||||
13,13,12545
|
11,2,2753
|
||||||
14,12,13253
|
11,13,2739
|
||||||
3,5,3210
|
6,13,1735
|
||||||
5,5,5158
|
7,6,1983
|
||||||
7,7,6992
|
8,3,2166
|
||||||
5,11,5076
|
7,14,1958
|
||||||
7,13,7056
|
6,2,2101
|
||||||
11,3,10584
|
13,5,3221
|
||||||
3,3,3302
|
8,4,2120
|
||||||
14,13,13280
|
10,4,2716
|
||||||
13,3,12771
|
14,5,3264
|
||||||
14,0,429
|
14,13,3299
|
||||||
7,5,7065
|
11,9,2725
|
||||||
7,14,6952
|
13,11,3132
|
||||||
8,6,7835
|
1,6,809
|
||||||
2,7,2334
|
2,2,1155
|
||||||
2,11,2367
|
4,4,2242
|
||||||
11,4,10606
|
8,6,2218
|
||||||
7,11,6845
|
12,0,645
|
||||||
14,8,13736
|
7,4,1925
|
||||||
0,5,844
|
2,6,1054
|
||||||
1,9,1333
|
9,13,2340
|
||||||
10,6,9721
|
13,12,3112
|
||||||
9,6,8769
|
14,4,3334
|
||||||
7,10,6998
|
3,11,1139
|
||||||
10,3,9810
|
12,14,3004
|
||||||
14,7,13311
|
4,9,2649
|
||||||
14,14,13481
|
0,13,527
|
||||||
11,0,426
|
12,11,2976
|
||||||
5,3,5102
|
0,0,1559
|
||||||
1,4,1457
|
12,13,2952
|
||||||
13,14,12431
|
6,10,1749
|
||||||
12,3,11717
|
14,11,3365
|
||||||
13,5,12523
|
11,0,647
|
||||||
14,10,13457
|
2,12,1024
|
||||||
0,6,705
|
10,6,2562
|
||||||
3,14,3335
|
8,5,2227
|
||||||
13,12,12714
|
9,12,2363
|
||||||
7,4,6951
|
2,1,1023
|
||||||
3,6,3247
|
0,10,528
|
||||||
9,5,8713
|
6,3,2005
|
||||||
3,12,3401
|
8,9,2195
|
||||||
14,1,13199
|
7,5,1966
|
||||||
4,10,4260
|
6,14,1755
|
||||||
10,0,428
|
9,0,608
|
||||||
5,13,5103
|
14,14,3389
|
||||||
0,0,421
|
9,7,2391
|
||||||
14,3,13070
|
0,4,688
|
||||||
9,2,8816
|
5,1,2574
|
||||||
7,0,451
|
9,14,2353
|
||||||
7,2,6974
|
12,2,2975
|
||||||
1,8,1363
|
3,1,1276
|
||||||
13,1,12699
|
6,5,1804
|
||||||
|
+3
-5
@@ -76,15 +76,13 @@ 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 children.is_empty() {
|
if scope.children.lock().unwrap().is_empty() {
|
||||||
#(#kids)*
|
#(#kids)*
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
.children.clear();
|
scope.children.lock().unwrap().clear();
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}, #deps_vec_emit);
|
}, #deps_vec_emit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +103,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.access_children(|children| children.clear());
|
scope.children.lock().unwrap().clear();
|
||||||
for #pat in #expr {
|
for #pat in #expr {
|
||||||
#(#kids)*
|
#(#kids)*
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-46
@@ -20,7 +20,7 @@ pub struct Context {
|
|||||||
component: AccessCell<Component>,
|
component: AccessCell<Component>,
|
||||||
view: AccessCell<View>,
|
view: AccessCell<View>,
|
||||||
event_handlers: AccessCell<HashMap<TypeId, Vec<EventHandler>>>,
|
event_handlers: AccessCell<HashMap<TypeId, Vec<EventHandler>>>,
|
||||||
scopes: AccessCell<Vec<Arc<Scope>>>,
|
pub(crate) scopes: Mutex<Vec<Arc<Scope>>>,
|
||||||
executor: Arc<dyn CommandExecutor>,
|
executor: Arc<dyn CommandExecutor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ impl Context {
|
|||||||
component: AccessCell::new(Arc::new(component)),
|
component: AccessCell::new(Arc::new(component)),
|
||||||
view: AccessCell::new(Arc::new(|_| {})),
|
view: AccessCell::new(Arc::new(|_| {})),
|
||||||
event_handlers: AccessCell::new(HashMap::new()),
|
event_handlers: AccessCell::new(HashMap::new()),
|
||||||
scopes: AccessCell::new(Vec::new()),
|
scopes: Mutex::new(Vec::new()),
|
||||||
executor,
|
executor,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -111,16 +111,11 @@ impl Context {
|
|||||||
(h.lock().unwrap())(self, event.as_ref());
|
(h.lock().unwrap())(self, event.as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.scopes.access(move |scopes| {
|
for scope in self.scopes.lock().unwrap().iter() {
|
||||||
for scope in scopes {
|
for (child, _) in scope.children.lock().unwrap().iter() {
|
||||||
let event = event.clone();
|
|
||||||
scope.access_children(move |children| {
|
|
||||||
for (child, _) in children {
|
|
||||||
child.emit_event(event.clone());
|
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>(
|
||||||
@@ -139,26 +134,16 @@ impl Context {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let event = event.clone();
|
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_threaded(event);
|
||||||
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
|
||||||
}
|
}
|
||||||
@@ -169,11 +154,7 @@ 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);
|
||||||
|
|
||||||
@@ -191,34 +172,21 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_scope(self: &Arc<Self>, scope: Arc<Scope>) {
|
pub fn add_scope(self: &Arc<Self>, scope: Arc<Scope>) {
|
||||||
self.scopes.access(|scopes| scopes.push(scope));
|
self.scopes.lock().unwrap().push(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_children(self: &Arc<Self>, ctx: &mut DrawContext) {
|
pub fn draw_children(self: &Arc<Self>, ctx: &mut DrawContext) {
|
||||||
let c = ctx.clone();
|
for scope in self.scopes.lock().unwrap().iter() {
|
||||||
|
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(&mut c, view)
|
view_wrapper(ctx, view)
|
||||||
} else {
|
} else {
|
||||||
c.draw_view(c.area.clone(), view);
|
ctx.draw_view(ctx.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> {
|
||||||
|
|||||||
+8
-23
@@ -1,19 +1,18 @@
|
|||||||
use super::{context::Context, ComponentImpl};
|
use std::sync::{Arc, Mutex};
|
||||||
use crate::{engine::CommandExecutor, View, ViewWrapper};
|
|
||||||
use access_cell::AccessCell;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
pub type ScopeChildren = Vec<(Arc<Context>, Option<ViewWrapper>)>;
|
use crate::{engine::CommandExecutor, View, ViewWrapper};
|
||||||
|
|
||||||
|
use super::{context::Context, ComponentImpl};
|
||||||
|
|
||||||
pub struct Scope {
|
pub struct Scope {
|
||||||
children: AccessCell<ScopeChildren>,
|
pub children: Mutex<Vec<(Arc<Context>, Option<ViewWrapper>)>>,
|
||||||
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: AccessCell::new(Vec::new()),
|
children: Mutex::new(Vec::new()),
|
||||||
executor,
|
executor,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -27,8 +26,7 @@ impl Scope {
|
|||||||
|
|
||||||
ctx.refresh();
|
ctx.refresh();
|
||||||
|
|
||||||
self.children
|
self.children.lock().unwrap().push((ctx, view_wrapper));
|
||||||
.access(|children| children.push((ctx, view_wrapper)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view(self: &Arc<Self>, view: View) {
|
pub fn view(self: &Arc<Self>, view: View) {
|
||||||
@@ -36,19 +34,6 @@ impl Scope {
|
|||||||
|
|
||||||
ctx.refresh();
|
ctx.refresh();
|
||||||
|
|
||||||
self.children.access(|children| children.push((ctx, None)));
|
self.children.lock().unwrap().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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user