@@ -20,6 +20,7 @@ use crate::llr::{
20
20
TypeResolutionContext as _,
21
21
} ;
22
22
use crate :: object_tree:: Document ;
23
+ use crate :: typeloader:: LibraryInfo ;
23
24
use crate :: CompilerConfiguration ;
24
25
use itertools:: Either ;
25
26
use lyon_path:: geom:: euclid:: approxeq:: ApproxEq ;
@@ -160,6 +161,36 @@ pub fn generate(
160
161
return super :: rust_live_preview:: generate ( doc, compiler_config) ;
161
162
}
162
163
164
+ let module_header = generate_module_header ( ) ;
165
+ let qualified_name_ident = |symbol : & SmolStr , library_info : & LibraryInfo | {
166
+ let symbol = ident ( symbol) ;
167
+ let package = ident ( & library_info. package ) ;
168
+ if let Some ( module) = & library_info. module {
169
+ let module = ident ( module) ;
170
+ quote ! ( #package :: #module :: #symbol)
171
+ } else {
172
+ quote ! ( #package :: #symbol)
173
+ }
174
+ } ;
175
+
176
+ let library_imports = {
177
+ let doc_used_types = doc. used_types . borrow ( ) ;
178
+ doc_used_types
179
+ . library_types_imports
180
+ . iter ( )
181
+ . map ( |( symbol, library_info) | {
182
+ let ident = qualified_name_ident ( symbol, library_info) ;
183
+ quote ! ( pub use #ident; )
184
+ } )
185
+ . chain ( doc_used_types. library_global_imports . iter ( ) . map ( |( symbol, library_info) | {
186
+ let ident = qualified_name_ident ( symbol, library_info) ;
187
+ let inner_symbol_name = smol_str:: format_smolstr!( "Inner{}" , symbol) ;
188
+ let inner_ident = qualified_name_ident ( & inner_symbol_name, library_info) ;
189
+ quote ! ( pub use #ident, #inner_ident; )
190
+ } ) )
191
+ . collect :: < Vec < _ > > ( )
192
+ } ;
193
+
163
194
let ( structs_and_enums_ids, inner_module) =
164
195
generate_types ( & doc. used_types . borrow ( ) . structs_and_enums ) ;
165
196
@@ -180,12 +211,22 @@ pub fn generate(
180
211
let popup_menu =
181
212
llr. popup_menu . as_ref ( ) . map ( |p| generate_item_tree ( & p. item_tree , & llr, None , None , true ) ) ;
182
213
183
- let globals = llr
214
+ let mut global_exports = Vec :: < TokenStream > :: new ( ) ;
215
+ if let Some ( library_name) = & compiler_config. library_name {
216
+ // Building as a library, SharedGlobals needs to be exported
217
+ let ident = format_ident ! ( "{}SharedGlobals" , library_name) ;
218
+ global_exports. push ( quote ! ( SharedGlobals as #ident) ) ;
219
+ }
220
+ let globals =
221
+ llr. globals . iter_enumerated ( ) . filter ( |( _, glob) | glob. must_generate ( ) ) . map (
222
+ |( idx, glob) | generate_global ( idx, glob, & llr, compiler_config, & mut global_exports) ,
223
+ ) ;
224
+ let library_globals_getters = llr
184
225
. globals
185
226
. iter_enumerated ( )
186
- . filter ( |( _, glob) | glob. must_generate ( ) )
187
- . map ( |( idx , glob) | generate_global ( idx , glob, & llr) ) ;
188
- let shared_globals = generate_shared_globals ( & llr, compiler_config) ;
227
+ . filter ( |( _, glob) | glob. from_library )
228
+ . map ( |( _idx , glob) | generate_global_getters ( glob, & llr) ) ;
229
+ let shared_globals = generate_shared_globals ( & doc , & llr, compiler_config) ;
189
230
let globals_ids = llr. globals . iter ( ) . filter ( |glob| glob. exported ) . flat_map ( |glob| {
190
231
std:: iter:: once ( ident ( & glob. name ) ) . chain ( glob. aliases . iter ( ) . map ( |x| ident ( x) ) )
191
232
} ) ;
@@ -207,8 +248,11 @@ pub fn generate(
207
248
208
249
Ok ( quote ! {
209
250
mod #generated_mod {
251
+ #module_header
252
+ #( #library_imports) *
210
253
#inner_module
211
254
#( #globals) *
255
+ #( #library_globals_getters) *
212
256
#( #sub_compos) *
213
257
#popup_menu
214
258
#( #public_components) *
@@ -217,12 +261,25 @@ pub fn generate(
217
261
#translations
218
262
}
219
263
#[ allow( unused_imports) ]
220
- pub use #generated_mod:: { #( #compo_ids, ) * #( #structs_and_enums_ids, ) * #( #globals_ids, ) * #( #named_exports, ) * } ;
264
+ pub use #generated_mod:: { #( #compo_ids, ) * #( #structs_and_enums_ids, ) * #( #globals_ids, ) * #( #named_exports, ) * # ( #global_exports , ) * } ;
221
265
#[ allow( unused_imports) ]
222
266
pub use slint:: { ComponentHandle as _, Global as _, ModelExt as _} ;
223
267
} )
224
268
}
225
269
270
+ pub ( super ) fn generate_module_header ( ) -> TokenStream {
271
+ quote ! {
272
+ #![ allow( non_snake_case, non_camel_case_types) ]
273
+ #![ allow( unused_braces, unused_parens) ]
274
+ #![ allow( clippy:: all, clippy:: pedantic, clippy:: nursery) ]
275
+ #![ allow( unknown_lints, if_let_rescope, tail_expr_drop_order) ] // We don't have fancy Drop
276
+
277
+ use slint:: private_unstable_api:: re_exports as sp;
278
+ #[ allow( unused_imports) ]
279
+ use sp:: { RepeatedItemTree as _, ModelExt as _, Model as _, Float as _} ;
280
+ }
281
+ }
282
+
226
283
/// Generate the struct and enums. Return a vector of names to import and a token stream with the inner module
227
284
pub fn generate_types ( used_types : & [ Type ] ) -> ( Vec < Ident > , TokenStream ) {
228
285
let ( structs_and_enums_ids, structs_and_enum_def) : ( Vec < _ > , Vec < _ > ) = used_types
@@ -247,14 +304,6 @@ pub fn generate_types(used_types: &[Type]) -> (Vec<Ident>, TokenStream) {
247
304
) ;
248
305
249
306
let inner_module = quote ! {
250
- #![ allow( non_snake_case, non_camel_case_types) ]
251
- #![ allow( unused_braces, unused_parens) ]
252
- #![ allow( clippy:: all, clippy:: pedantic, clippy:: nursery) ]
253
- #![ allow( unknown_lints, if_let_rescope, tail_expr_drop_order) ] // We don't have fancy Drop
254
-
255
- use slint:: private_unstable_api:: re_exports as sp;
256
- #[ allow( unused_imports) ]
257
- use sp:: { RepeatedItemTree as _, ModelExt as _, Model as _, Float as _} ;
258
307
#( #structs_and_enum_def) *
259
308
const _THE_SAME_VERSION_MUST_BE_USED_FOR_THE_COMPILER_AND_THE_RUNTIME : slint:: #version_check = slint:: #version_check;
260
309
} ;
@@ -361,6 +410,7 @@ fn generate_public_component(
361
410
}
362
411
363
412
fn generate_shared_globals (
413
+ doc : & Document ,
364
414
llr : & llr:: CompilationUnit ,
365
415
compiler_config : & CompilerConfiguration ,
366
416
) -> TokenStream {
@@ -377,6 +427,15 @@ fn generate_shared_globals(
377
427
. map ( global_inner_name)
378
428
. collect :: < Vec < _ > > ( ) ;
379
429
430
+ let from_library_global_names = llr
431
+ . globals
432
+ . iter ( )
433
+ . filter ( |g| g. from_library )
434
+ . map ( |g| format_ident ! ( "global_{}" , ident( & g. name) ) )
435
+ . collect :: < Vec < _ > > ( ) ;
436
+
437
+ let from_library_global_types =
438
+ llr. globals . iter ( ) . filter ( |g| g. from_library ) . map ( global_inner_name) . collect :: < Vec < _ > > ( ) ;
380
439
let apply_constant_scale_factor = if !compiler_config. const_scale_factor . approx_eq ( & 1.0 ) {
381
440
let factor = compiler_config. const_scale_factor as f32 ;
382
441
Some (
@@ -386,18 +445,59 @@ fn generate_shared_globals(
386
445
None
387
446
} ;
388
447
448
+ let library_global_vars = llr
449
+ . globals
450
+ . iter ( )
451
+ . filter ( |g| g. from_library )
452
+ . map ( |g| {
453
+ let library_info = doc. library_exports . get ( g. name . as_str ( ) ) . unwrap ( ) ;
454
+ let shared_gloabls_var_name =
455
+ format_ident ! ( "library_{}_shared_globals" , library_info. name) ;
456
+ let global_name = format_ident ! ( "global_{}" , ident( & g. name) ) ;
457
+ quote ! ( #shared_gloabls_var_name. #global_name )
458
+ } )
459
+ . collect :: < Vec < _ > > ( ) ;
460
+ let pub_token = if compiler_config. library_name . is_some ( ) { quote ! ( pub ) } else { quote ! ( ) } ;
461
+
462
+ let ( library_shared_globals_names, library_shared_globals_types) : ( Vec < _ > , Vec < _ > ) = doc
463
+ . imports
464
+ . iter ( )
465
+ . filter_map ( |import| import. library_info . clone ( ) )
466
+ . map ( |library_info| {
467
+ let struct_name = format_ident ! ( "{}SharedGlobals" , library_info. name) ;
468
+ let shared_gloabls_var_name =
469
+ format_ident ! ( "library_{}_shared_globals" , library_info. name) ;
470
+ let shared_globals_type_name = if let Some ( module) = library_info. module {
471
+ let package = ident ( & library_info. package ) ;
472
+ let module = ident ( & module) ;
473
+ //(quote!(#shared_gloabls_var_name),quote!(let #shared_gloabls_var_name = #package::#module::#shared_globals_type_name::new(root_item_tree_weak.clone());))
474
+ quote ! ( #package:: #module:: #struct_name)
475
+ } else {
476
+ let package = ident ( & library_info. package ) ;
477
+ quote ! ( #package:: #struct_name)
478
+ } ;
479
+ ( quote ! ( #shared_gloabls_var_name) , shared_globals_type_name)
480
+ } )
481
+ . unzip ( ) ;
482
+
389
483
quote ! {
390
- struct SharedGlobals {
391
- #( #global_names : :: core:: pin:: Pin <sp:: Rc <#global_types>>, ) *
484
+ #pub_token struct SharedGlobals {
485
+ #( #pub_token #global_names : :: core:: pin:: Pin <sp:: Rc <#global_types>>, ) *
486
+ #( #pub_token #from_library_global_names : :: core:: pin:: Pin <sp:: Rc <#from_library_global_types>>, ) *
392
487
window_adapter : sp:: OnceCell <sp:: WindowAdapterRc >,
393
488
root_item_tree_weak : sp:: VWeak <sp:: ItemTreeVTable >,
489
+ #( #[ allow( dead_code) ]
490
+ #library_shared_globals_names : sp:: Rc <#library_shared_globals_types>, ) *
394
491
}
395
492
impl SharedGlobals {
396
- fn new( root_item_tree_weak : sp:: VWeak <sp:: ItemTreeVTable >) -> sp:: Rc <Self > {
493
+ #pub_token fn new( root_item_tree_weak : sp:: VWeak <sp:: ItemTreeVTable >) -> sp:: Rc <Self > {
494
+ #( let #library_shared_globals_names = #library_shared_globals_types:: new( root_item_tree_weak. clone( ) ) ; ) *
397
495
let _self = sp:: Rc :: new( Self {
398
496
#( #global_names : #global_types:: new( ) , ) *
497
+ #( #from_library_global_names : #library_global_vars. clone( ) , ) *
399
498
window_adapter : :: core:: default :: Default :: default ( ) ,
400
499
root_item_tree_weak,
500
+ #( #library_shared_globals_names, ) *
401
501
} ) ;
402
502
#( _self. #global_names. clone( ) . init( & _self) ; ) *
403
503
_self
@@ -1340,6 +1440,8 @@ fn generate_global(
1340
1440
global_idx : llr:: GlobalIdx ,
1341
1441
global : & llr:: GlobalComponent ,
1342
1442
root : & llr:: CompilationUnit ,
1443
+ compiler_config : & CompilerConfiguration ,
1444
+ global_exports : & mut Vec < TokenStream > ,
1343
1445
) -> TokenStream {
1344
1446
let mut declared_property_vars = vec ! [ ] ;
1345
1447
let mut declared_property_types = vec ! [ ] ;
@@ -1442,6 +1544,13 @@ fn generate_global(
1442
1544
}
1443
1545
} ) ) ;
1444
1546
1547
+ let pub_token = if compiler_config. library_name . is_some ( ) {
1548
+ global_exports. push ( quote ! ( #inner_component_id) ) ;
1549
+ quote ! ( pub )
1550
+ } else {
1551
+ quote ! ( )
1552
+ } ;
1553
+
1445
1554
let public_interface = global. exported . then ( || {
1446
1555
let property_and_callback_accessors = public_api (
1447
1556
& global. public_properties ,
@@ -1450,26 +1559,17 @@ fn generate_global(
1450
1559
& ctx,
1451
1560
) ;
1452
1561
let aliases = global. aliases . iter ( ) . map ( |name| ident ( name) ) ;
1453
- let getters = root. public_components . iter ( ) . map ( |c| {
1454
- let root_component_id = ident ( & c. name ) ;
1455
- quote ! {
1456
- impl <' a> slint:: Global <' a, #root_component_id> for #public_component_id<' a> {
1457
- fn get( component: & ' a #root_component_id) -> Self {
1458
- Self ( & component. 0 . globals. get( ) . unwrap( ) . #global_id)
1459
- }
1460
- }
1461
- }
1462
- } ) ;
1562
+ let getters = generate_global_getters ( global, root) ;
1463
1563
1464
1564
quote ! (
1465
1565
#[ allow( unused) ]
1466
- pub struct #public_component_id<' a>( & ' a :: core:: pin:: Pin <sp:: Rc <#inner_component_id>>) ;
1566
+ pub struct #public_component_id<' a>( #pub_token & ' a :: core:: pin:: Pin <sp:: Rc <#inner_component_id>>) ;
1467
1567
1468
1568
impl <' a> #public_component_id<' a> {
1469
1569
#property_and_callback_accessors
1470
1570
}
1471
1571
#( pub type #aliases<' a> = #public_component_id<' a>; ) *
1472
- #( # getters) *
1572
+ #getters
1473
1573
)
1474
1574
} ) ;
1475
1575
@@ -1478,10 +1578,10 @@ fn generate_global(
1478
1578
#[ const_field_offset( sp:: const_field_offset) ]
1479
1579
#[ repr( C ) ]
1480
1580
#[ pin]
1481
- struct #inner_component_id {
1482
- #( #declared_property_vars: sp:: Property <#declared_property_types>, ) *
1483
- #( #declared_callbacks: sp:: Callback <( #( #declared_callbacks_types, ) * ) , #declared_callbacks_ret>, ) *
1484
- #( #change_tracker_names : sp:: ChangeTracker , ) *
1581
+ #pub_token struct #inner_component_id {
1582
+ #( #pub_token # declared_property_vars: sp:: Property <#declared_property_types>, ) *
1583
+ #( #pub_token # declared_callbacks: sp:: Callback <( #( #declared_callbacks_types, ) * ) , #declared_callbacks_ret>, ) *
1584
+ #( #pub_token # change_tracker_names : sp:: ChangeTracker , ) *
1485
1585
globals : sp:: OnceCell <sp:: Weak <SharedGlobals >>,
1486
1586
}
1487
1587
@@ -1504,6 +1604,29 @@ fn generate_global(
1504
1604
)
1505
1605
}
1506
1606
1607
+ fn generate_global_getters (
1608
+ global : & llr:: GlobalComponent ,
1609
+ root : & llr:: CompilationUnit ,
1610
+ ) -> TokenStream {
1611
+ let public_component_id = ident ( & global. name ) ;
1612
+ let global_id = format_ident ! ( "global_{}" , public_component_id) ;
1613
+
1614
+ let getters = root. public_components . iter ( ) . map ( |c| {
1615
+ let root_component_id = ident ( & c. name ) ;
1616
+ quote ! {
1617
+ impl <' a> slint:: Global <' a, #root_component_id> for #public_component_id<' a> {
1618
+ fn get( component: & ' a #root_component_id) -> Self {
1619
+ Self ( & component. 0 . globals. get( ) . unwrap( ) . #global_id)
1620
+ }
1621
+ }
1622
+ }
1623
+ } ) ;
1624
+
1625
+ quote ! (
1626
+ #( #getters) *
1627
+ )
1628
+ }
1629
+
1507
1630
fn generate_item_tree (
1508
1631
sub_tree : & llr:: ItemTree ,
1509
1632
root : & llr:: CompilationUnit ,
0 commit comments