diff --git a/internal/interpreter/dynamic_item_tree.rs b/internal/interpreter/dynamic_item_tree.rs index ea8cc2661..92740afb4 100644 --- a/internal/interpreter/dynamic_item_tree.rs +++ b/internal/interpreter/dynamic_item_tree.rs @@ -36,7 +36,7 @@ use i_slint_core::window::{WindowAdapterRc, WindowInner}; use i_slint_core::{Brush, Color, Property, SharedString, SharedVector}; #[cfg(feature = "internal")] use itertools::Either; -use once_cell::unsync::OnceCell; +use once_cell::unsync::{Lazy, OnceCell}; use smol_str::{SmolStr, ToSmolStr}; use std::collections::BTreeMap; use std::collections::HashMap; @@ -935,61 +935,68 @@ pub async fn load( } } +fn generate_rtti() -> HashMap<&'static str, Rc> { + let mut rtti = HashMap::new(); + use i_slint_core::items::*; + rtti.extend( + [ + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + rtti_for::(), + ] + .iter() + .cloned(), + ); + + trait NativeHelper { + fn push(rtti: &mut HashMap<&str, Rc>); + } + impl NativeHelper for () { + fn push(_rtti: &mut HashMap<&str, Rc>) {} + } + impl< + T: 'static + Default + rtti::BuiltinItem + vtable::HasStaticVTable, + Next: NativeHelper, + > NativeHelper for (T, Next) + { + fn push(rtti: &mut HashMap<&str, Rc>) { + let info = rtti_for::(); + rtti.insert(info.0, info.1); + Next::push(rtti); + } + } + i_slint_backend_selector::NativeWidgets::push(&mut rtti); + + rtti +} + pub(crate) fn generate_item_tree<'id>( component: &Rc, compiled_globals: Option>, guard: generativity::Guard<'id>, ) -> Rc> { //dbg!(&*component.root_element.borrow()); - let mut rtti = HashMap::new(); - { - use i_slint_core::items::*; - rtti.extend( - [ - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - rtti_for::(), - ] - .iter() - .cloned(), - ); - trait NativeHelper { - fn push(rtti: &mut HashMap<&str, Rc>); - } - impl NativeHelper for () { - fn push(_rtti: &mut HashMap<&str, Rc>) {} - } - impl< - T: 'static + Default + rtti::BuiltinItem + vtable::HasStaticVTable, - Next: NativeHelper, - > NativeHelper for (T, Next) - { - fn push(rtti: &mut HashMap<&str, Rc>) { - let info = rtti_for::(); - rtti.insert(info.0, info.1); - Next::push(rtti); - } - } - i_slint_backend_selector::NativeWidgets::push(&mut rtti); + thread_local! { + static RTTI: Lazy>> = Lazy::new(|| generate_rtti()); } struct TreeBuilder<'id> { @@ -1001,7 +1008,6 @@ pub(crate) fn generate_item_tree<'id>( type_builder: dynamic_type::TypeBuilder<'id>, repeater: Vec>, repeater_names: HashMap, - rtti: Rc>>, change_callbacks: Vec<(NamedReference, Expression)>, } impl<'id> generator::ItemTreeBuilder for TreeBuilder<'id> { @@ -1050,8 +1056,15 @@ pub(crate) fn generate_item_tree<'id>( _component_state: &Self::SubComponentState, ) { let item = rc_item.borrow(); - let rt = self.rtti.get(&*item.base_type.as_native().class_name).unwrap_or_else(|| { - panic!("Native type not registered: {}", item.base_type.as_native().class_name) + let rt = RTTI.with(|rtti| { + rtti.get(&*item.base_type.as_native().class_name) + .unwrap_or_else(|| { + panic!( + "Native type not registered: {}", + item.base_type.as_native().class_name + ) + }) + .clone() }); let offset = self.type_builder.add_field(rt.type_info); @@ -1068,7 +1081,7 @@ pub(crate) fn generate_item_tree<'id>( debug_assert_eq!(self.original_elements.len(), self.tree_array.len()); self.items_types.insert( item.id.clone(), - ItemWithinItemTree { offset, rtti: rt.clone(), elem: rc_item.clone() }, + ItemWithinItemTree { offset, rtti: rt, elem: rc_item.clone() }, ); for (prop, expr) in &item.change_callbacks { self.change_callbacks.push(( @@ -1107,7 +1120,6 @@ pub(crate) fn generate_item_tree<'id>( type_builder: dynamic_type::TypeBuilder::new(guard), repeater: vec![], repeater_names: HashMap::new(), - rtti: Rc::new(rtti), change_callbacks: vec![], };