@@ -350,7 +350,7 @@ struct ConditionalIncludes {
350
350
351
351
#[ derive( Clone ) ]
352
352
struct CppGeneratorContext < ' a > {
353
- root_access : String ,
353
+ global_access : String ,
354
354
conditional_includes : & ' a ConditionalIncludes ,
355
355
}
356
356
@@ -795,12 +795,71 @@ pub fn generate(
795
795
file. declarations . push ( Declaration :: Struct ( sub_compo_struct) ) ;
796
796
}
797
797
798
- for glob in llr. globals . iter ( ) . filter ( |glob| !glob. is_builtin ) {
799
- generate_global ( & mut file, & conditional_includes, glob, & llr) ;
800
- file. definitions . extend ( glob. aliases . iter ( ) . map ( |name| {
801
- Declaration :: TypeAlias ( TypeAlias { old_name : ident ( & glob. name ) , new_name : ident ( name) } )
802
- } ) )
798
+ let mut globals_struct = Struct { name : "SharedGlobals" . into ( ) , ..Default :: default ( ) } ;
799
+
800
+ // The window need to be the first member so it is destroyed last
801
+ globals_struct. members . push ( (
802
+ // FIXME: many of the different component bindings need to access this
803
+ Access :: Public ,
804
+ Declaration :: Var ( Var {
805
+ ty : "std::optional<slint::Window>" . into ( ) ,
806
+ name : "m_window" . into ( ) ,
807
+ ..Default :: default ( )
808
+ } ) ,
809
+ ) ) ;
810
+
811
+ globals_struct. members . push ( (
812
+ Access :: Public ,
813
+ Declaration :: Var ( Var {
814
+ ty : "slint::cbindgen_private::ItemTreeWeak" . into ( ) ,
815
+ name : "root_weak" . into ( ) ,
816
+ ..Default :: default ( )
817
+ } ) ,
818
+ ) ) ;
819
+
820
+ globals_struct. members . push ( (
821
+ Access :: Public ,
822
+ Declaration :: Function ( Function {
823
+ name : "window" . into ( ) ,
824
+ signature : "() const -> slint::Window&" . into ( ) ,
825
+ statements : Some ( vec ! [
826
+ format!( "auto self = const_cast<SharedGlobals *>(this);" ) ,
827
+ "if (!self->m_window.has_value()) {" . into( ) ,
828
+ " auto &window = self->m_window.emplace(slint::private_api::WindowAdapterRc());"
829
+ . into( ) ,
830
+ " window.window_handle().set_component(self->root_weak);" . into( ) ,
831
+ "}" . into( ) ,
832
+ "return *self->m_window;" . into( ) ,
833
+ ] ) ,
834
+ ..Default :: default ( )
835
+ } ) ,
836
+ ) ) ;
837
+
838
+ for glob in & llr. globals {
839
+ let ty = if glob. is_builtin {
840
+ format ! ( "slint::cbindgen_private::{}" , glob. name)
841
+ } else {
842
+ generate_global ( & mut file, & conditional_includes, glob, & llr) ;
843
+ file. definitions . extend ( glob. aliases . iter ( ) . map ( |name| {
844
+ Declaration :: TypeAlias ( TypeAlias {
845
+ old_name : ident ( & glob. name ) ,
846
+ new_name : ident ( name) ,
847
+ } )
848
+ } ) ) ;
849
+ ident ( & glob. name )
850
+ } ;
851
+
852
+ globals_struct. members . push ( (
853
+ Access :: Public ,
854
+ Declaration :: Var ( Var {
855
+ ty : format ! ( "std::shared_ptr<{}>" , ty) ,
856
+ name : format ! ( "global_{}" , ident( & glob. name) ) ,
857
+ init : Some ( format ! ( "std::make_shared<{}>(this)" , ty) ) ,
858
+ ..Default :: default ( )
859
+ } ) ,
860
+ ) ) ;
803
861
}
862
+ file. declarations . push ( Declaration :: Struct ( globals_struct) ) ;
804
863
805
864
generate_public_component ( & mut file, & conditional_includes, & llr) ;
806
865
@@ -887,25 +946,55 @@ fn generate_public_component(
887
946
) {
888
947
let root_component = & component. item_tree . root ;
889
948
let component_id = ident ( & root_component. name ) ;
949
+
890
950
let mut component_struct = Struct { name : component_id. clone ( ) , ..Default :: default ( ) } ;
891
951
892
- // The window need to be the first member so it is destroyed last
952
+ // need to be the first member, because it contains the window which is to be destroyed last
893
953
component_struct. members . push ( (
894
- // FIXME: many of the different component bindings need to access this
895
- Access :: Public ,
954
+ Access :: Private ,
896
955
Declaration :: Var ( Var {
897
- ty : "std::optional<slint::Window> " . into ( ) ,
898
- name : "m_window " . into ( ) ,
956
+ ty : "SharedGlobals " . into ( ) ,
957
+ name : "m_globals " . into ( ) ,
899
958
..Default :: default ( )
900
959
} ) ,
901
960
) ) ;
902
961
962
+ for glob in component. globals . iter ( ) . filter ( |glob| !glob. is_builtin ) {
963
+ component_struct. friends . push ( ident ( & glob. name ) ) ;
964
+ }
965
+
966
+ let mut global_accessor_function_body = Vec :: new ( ) ;
967
+ for glob in component. globals . iter ( ) . filter ( |glob| glob. exported && !glob. is_builtin ) {
968
+ let accessor_statement = format ! (
969
+ "{0}if constexpr(std::is_same_v<T, {1}>) {{ return *m_globals.global_{1}.get(); }}" ,
970
+ if global_accessor_function_body. is_empty( ) { "" } else { "else " } ,
971
+ ident( & glob. name) ,
972
+ ) ;
973
+ global_accessor_function_body. push ( accessor_statement) ;
974
+ }
975
+ if !global_accessor_function_body. is_empty ( ) {
976
+ global_accessor_function_body. push (
977
+ "else { static_assert(!sizeof(T*), \" The type is not global/or exported\" ); }" . into ( ) ,
978
+ ) ;
979
+
980
+ component_struct. members . push ( (
981
+ Access :: Public ,
982
+ Declaration :: Function ( Function {
983
+ name : "global" . into ( ) ,
984
+ signature : "() const -> const T&" . into ( ) ,
985
+ statements : Some ( global_accessor_function_body) ,
986
+ template_parameters : Some ( "typename T" . into ( ) ) ,
987
+ ..Default :: default ( )
988
+ } ) ,
989
+ ) ) ;
990
+ }
991
+
903
992
let ctx = EvaluationContext {
904
993
public_component : component,
905
994
current_sub_component : Some ( & component. item_tree . root ) ,
906
995
current_global : None ,
907
996
generator_state : CppGeneratorContext {
908
- root_access : "this" . to_string ( ) ,
997
+ global_access : "(& this->m_globals) " . to_string ( ) ,
909
998
conditional_includes,
910
999
} ,
911
1000
parent : None ,
@@ -965,15 +1054,7 @@ fn generate_public_component(
965
1054
Declaration :: Function ( Function {
966
1055
name : "window" . into ( ) ,
967
1056
signature : "() const -> slint::Window&" . into ( ) ,
968
- statements : Some ( vec ! [
969
- format!( "auto self = const_cast<{} *>(this);" , component_struct. name) ,
970
- "if (!m_window.has_value()) {" . into( ) ,
971
- " auto &window = self->m_window.emplace(slint::private_api::WindowAdapterRc());"
972
- . into( ) ,
973
- " window.window_handle().set_component(*self);" . into( ) ,
974
- "}" . into( ) ,
975
- "return *self->m_window;" . into( ) ,
976
- ] ) ,
1057
+ statements : Some ( vec ! [ "return m_globals.window();" . into( ) ] ) ,
977
1058
..Default :: default ( )
978
1059
} ) ,
979
1060
) ) ;
@@ -1011,52 +1092,6 @@ fn generate_public_component(
1011
1092
}
1012
1093
}
1013
1094
1014
- for glob in & component. globals {
1015
- let ty = if glob. is_builtin {
1016
- format ! ( "slint::cbindgen_private::{}" , glob. name)
1017
- } else {
1018
- let ty = ident ( & glob. name ) ;
1019
- component_struct. friends . push ( ty. clone ( ) ) ;
1020
- ty
1021
- } ;
1022
-
1023
- component_struct. members . push ( (
1024
- Access :: Private ,
1025
- Declaration :: Var ( Var {
1026
- ty : format ! ( "std::shared_ptr<{}>" , ty) ,
1027
- name : format ! ( "global_{}" , ident( & glob. name) ) ,
1028
- init : Some ( format ! ( "std::make_shared<{}>(this)" , ty) ) ,
1029
- ..Default :: default ( )
1030
- } ) ,
1031
- ) ) ;
1032
- }
1033
-
1034
- let mut global_accessor_function_body = Vec :: new ( ) ;
1035
- for glob in component. globals . iter ( ) . filter ( |glob| glob. exported && !glob. is_builtin ) {
1036
- let accessor_statement = format ! (
1037
- "{0}if constexpr(std::is_same_v<T, {1}>) {{ return *global_{1}.get(); }}" ,
1038
- if global_accessor_function_body. is_empty( ) { "" } else { "else " } ,
1039
- ident( & glob. name) ,
1040
- ) ;
1041
- global_accessor_function_body. push ( accessor_statement) ;
1042
- }
1043
- if !global_accessor_function_body. is_empty ( ) {
1044
- global_accessor_function_body. push (
1045
- "else { static_assert(!sizeof(T*), \" The type is not global/or exported\" ); }" . into ( ) ,
1046
- ) ;
1047
-
1048
- component_struct. members . push ( (
1049
- Access :: Public ,
1050
- Declaration :: Function ( Function {
1051
- name : "global" . into ( ) ,
1052
- signature : "() const -> const T&" . into ( ) ,
1053
- statements : Some ( global_accessor_function_body) ,
1054
- template_parameters : Some ( "typename T" . into ( ) ) ,
1055
- ..Default :: default ( )
1056
- } ) ,
1057
- ) ) ;
1058
- }
1059
-
1060
1095
file. definitions . extend ( component_struct. extract_definitions ( ) . collect :: < Vec < _ > > ( ) ) ;
1061
1096
file. declarations . push ( Declaration :: Struct ( component_struct) ) ;
1062
1097
}
@@ -1477,15 +1512,17 @@ fn generate_item_tree(
1477
1512
] ;
1478
1513
1479
1514
if parent_ctx. is_none ( ) {
1515
+ create_code. push ( "self->globals = &self->m_globals;" . into ( ) ) ;
1516
+ create_code. push ( "self->m_globals.root_weak = self->self_weak;" . into ( ) ) ;
1480
1517
create_code. push ( "slint::cbindgen_private::slint_ensure_backend();" . into ( ) ) ;
1481
1518
}
1482
1519
1483
- let root_access = if parent_ctx. is_some ( ) { "parent->root " } else { "self" } ;
1520
+ let global_access = if parent_ctx. is_some ( ) { "parent->globals " } else { "self->globals " } ;
1484
1521
create_code. extend ( [
1485
1522
format ! (
1486
- "slint::private_api::register_item_tree(&self_rc.into_dyn(), {root_access }->m_window);" ,
1523
+ "slint::private_api::register_item_tree(&self_rc.into_dyn(), {global_access }->m_window);" ,
1487
1524
) ,
1488
- format ! ( "self->init({}, self->self_weak, 0, 1 {});" , root_access , init_parent_parameters) ,
1525
+ format ! ( "self->init({}, self->self_weak, 0, 1 {});" , global_access , init_parent_parameters) ,
1489
1526
] ) ;
1490
1527
1491
1528
// Repeaters run their user_init() code from Repeater::ensure_updated() after update() initialized model_data/index.
@@ -1512,9 +1549,8 @@ fn generate_item_tree(
1512
1549
} ) ,
1513
1550
) ) ;
1514
1551
1515
- let root_access = if parent_ctx. is_some ( ) { "root" } else { "this" } ;
1516
1552
let destructor = vec ! [ format!(
1517
- "if (auto &window = {root_access} ->m_window) window->window_handle().unregister_item_tree(this, item_array());"
1553
+ "if (auto &window = globals ->m_window) window->window_handle().unregister_item_tree(this, item_array());"
1518
1554
) ] ;
1519
1555
1520
1556
target_struct. members . push ( (
@@ -1538,10 +1574,10 @@ fn generate_sub_component(
1538
1574
file : & mut File ,
1539
1575
conditional_includes : & ConditionalIncludes ,
1540
1576
) {
1541
- let root_ptr_type = format ! ( "const {} *" , ident ( & root . item_tree . root . name ) ) ;
1577
+ let globals_type_ptr = "const class SharedGlobals*" ;
1542
1578
1543
1579
let mut init_parameters = vec ! [
1544
- format!( "{} root " , root_ptr_type ) ,
1580
+ format!( "{} globals " , globals_type_ptr ) ,
1545
1581
"slint::cbindgen_private::ItemTreeWeak enclosing_component" . into( ) ,
1546
1582
"uint32_t tree_index" . into( ) ,
1547
1583
"uint32_t tree_index_of_first_child" . into( ) ,
@@ -1561,9 +1597,13 @@ fn generate_sub_component(
1561
1597
1562
1598
target_struct. members . push ( (
1563
1599
field_access,
1564
- Declaration :: Var ( Var { ty : root_ptr_type, name : "root" . to_owned ( ) , ..Default :: default ( ) } ) ,
1600
+ Declaration :: Var ( Var {
1601
+ ty : globals_type_ptr. to_owned ( ) ,
1602
+ name : "globals" . to_owned ( ) ,
1603
+ ..Default :: default ( )
1604
+ } ) ,
1565
1605
) ) ;
1566
- init. push ( "self->root = root ;" . into ( ) ) ;
1606
+ init. push ( "self->globals = globals ;" . into ( ) ) ;
1567
1607
1568
1608
target_struct. members . push ( (
1569
1609
field_access,
@@ -1604,7 +1644,7 @@ fn generate_sub_component(
1604
1644
let ctx = EvaluationContext :: new_sub_component (
1605
1645
root,
1606
1646
component,
1607
- CppGeneratorContext { root_access : "self->root " . into ( ) , conditional_includes } ,
1647
+ CppGeneratorContext { global_access : "self->globals " . into ( ) , conditional_includes } ,
1608
1648
parent_ctx,
1609
1649
) ;
1610
1650
@@ -1679,7 +1719,7 @@ fn generate_sub_component(
1679
1719
} ;
1680
1720
1681
1721
init. push ( format ! (
1682
- "this->{}.init(root , self_weak.into_dyn(), {}, {});" ,
1722
+ "this->{}.init(globals , self_weak.into_dyn(), {}, {});" ,
1683
1723
field_name, global_index, global_children
1684
1724
) ) ;
1685
1725
user_init. push ( format ! ( "this->{}.user_init();" , field_name) ) ;
@@ -2117,7 +2157,7 @@ fn generate_repeated_component(
2117
2157
public_component : root,
2118
2158
current_sub_component : Some ( & repeated. sub_tree . root ) ,
2119
2159
current_global : None ,
2120
- generator_state : CppGeneratorContext { root_access : "self" . into ( ) , conditional_includes } ,
2160
+ generator_state : CppGeneratorContext { global_access : "self" . into ( ) , conditional_includes } ,
2121
2161
parent : Some ( parent_ctx) ,
2122
2162
argument_types : & [ ] ,
2123
2163
} ;
@@ -2248,11 +2288,11 @@ fn generate_global(
2248
2288
) ) ;
2249
2289
}
2250
2290
2251
- let mut init = vec ! [ "(void)this->root ;" . into( ) ] ;
2291
+ let mut init = vec ! [ "(void)this->globals ;" . into( ) ] ;
2252
2292
let ctx = EvaluationContext :: new_global (
2253
2293
root,
2254
2294
global,
2255
- CppGeneratorContext { root_access : "this->root " . into ( ) , conditional_includes } ,
2295
+ CppGeneratorContext { global_access : "this->globals " . into ( ) , conditional_includes } ,
2256
2296
) ;
2257
2297
2258
2298
for ( property_index, expression) in global. init_values . iter ( ) . enumerate ( ) {
@@ -2270,21 +2310,24 @@ fn generate_global(
2270
2310
}
2271
2311
}
2272
2312
2273
- let root_ptr_type = format ! ( "const {} *" , ident( & root. item_tree. root. name) ) ;
2274
2313
global_struct. members . push ( (
2275
2314
Access :: Public ,
2276
2315
Declaration :: Function ( Function {
2277
2316
name : ident ( & global. name ) ,
2278
- signature : format ! ( "({} root)" , root_ptr_type ) ,
2317
+ signature : "(const class SharedGlobals *globals)" . into ( ) ,
2279
2318
is_constructor_or_destructor : true ,
2280
2319
statements : Some ( init) ,
2281
- constructor_member_initializers : vec ! [ "root(root )" . into( ) ] ,
2320
+ constructor_member_initializers : vec ! [ "globals(globals )" . into( ) ] ,
2282
2321
..Default :: default ( )
2283
2322
} ) ,
2284
2323
) ) ;
2285
2324
global_struct. members . push ( (
2286
2325
Access :: Private ,
2287
- Declaration :: Var ( Var { ty : root_ptr_type, name : "root" . to_owned ( ) , ..Default :: default ( ) } ) ,
2326
+ Declaration :: Var ( Var {
2327
+ ty : "const class SharedGlobals*" . to_owned ( ) ,
2328
+ name : "globals" . to_owned ( ) ,
2329
+ ..Default :: default ( )
2330
+ } ) ,
2288
2331
) ) ;
2289
2332
2290
2333
generate_public_api_for_properties (
@@ -2512,8 +2555,7 @@ fn follow_sub_component_path<'a>(
2512
2555
}
2513
2556
2514
2557
fn access_window_field ( ctx : & EvaluationContext ) -> String {
2515
- let root = & ctx. generator_state . root_access ;
2516
- format ! ( "{}->window().window_handle()" , root)
2558
+ format ! ( "{}->window().window_handle()" , ctx. generator_state. global_access)
2517
2559
}
2518
2560
2519
2561
/// Returns the code that can access the given property (but without the set or get)
@@ -2613,21 +2655,21 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
2613
2655
}
2614
2656
}
2615
2657
llr:: PropertyReference :: Global { global_index, property_index } => {
2616
- let root_access = & ctx. generator_state . root_access ;
2658
+ let global_access = & ctx. generator_state . global_access ;
2617
2659
let global = & ctx. public_component . globals [ * global_index] ;
2618
2660
let global_id = format ! ( "global_{}" , ident( & global. name) ) ;
2619
2661
let property_name = ident (
2620
2662
& ctx. public_component . globals [ * global_index] . properties [ * property_index] . name ,
2621
2663
) ;
2622
- format ! ( "{}->{}->{}" , root_access , global_id, property_name)
2664
+ format ! ( "{}->{}->{}" , global_access , global_id, property_name)
2623
2665
}
2624
2666
llr:: PropertyReference :: GlobalFunction { global_index, function_index } => {
2625
- let root_access = & ctx. generator_state . root_access ;
2667
+ let global_access = & ctx. generator_state . global_access ;
2626
2668
let global = & ctx. public_component . globals [ * global_index] ;
2627
2669
let global_id = format ! ( "global_{}" , ident( & global. name) ) ;
2628
2670
let name =
2629
2671
ident ( & ctx. public_component . globals [ * global_index] . functions [ * function_index] . name ) ;
2630
- format ! ( "{root_access }->{global_id}->fn_{name}" )
2672
+ format ! ( "{global_access }->{global_id}->fn_{name}" )
2631
2673
}
2632
2674
}
2633
2675
}
0 commit comments