Add a dummy indirection in C++ for the item vtable access

This will allow for a compile-time decision in the future whether
to use the vtable symbol or getter function.
This commit is contained in:
Simon Hausmann 2021-05-10 17:20:54 +02:00 committed by Simon Hausmann
parent c84e6d2945
commit 4198513832
3 changed files with 33 additions and 16 deletions

View file

@ -204,6 +204,12 @@ inline vtable::Layout drop_in_place(ComponentRef component)
return vtable::Layout { sizeof(T), alignof(T) }; return vtable::Layout { sizeof(T), alignof(T) };
} }
template<typename VTableType>
constexpr inline const VTableType *get_vtable(const VTableType *vtable_symbol)
{
return vtable_symbol;
}
template<typename T> template<typename T>
struct ReturnWrapper struct ReturnWrapper
{ {

View file

@ -1044,10 +1044,10 @@ fn generate_component(
)); ));
} else { } else {
tree_array.push(format!( tree_array.push(format!(
"sixtyfps::private_api::make_item_node(offsetof({}, {}), &sixtyfps::private_api::{}, {}, {}, {})", "sixtyfps::private_api::make_item_node(offsetof({}, {}), {}, {}, {}, {})",
component_id, component_id,
item.id, item.id,
item.base_type.as_native().vtable_symbol, item.base_type.as_native().cpp_vtable_getter,
item.children.len(), item.children.len(),
children_offset, children_offset,
parent_index, parent_index,
@ -1055,7 +1055,7 @@ fn generate_component(
} }
handle_item(item_rc, &mut component_struct, &mut init); handle_item(item_rc, &mut component_struct, &mut init);
item_names_and_vt_symbols item_names_and_vt_symbols
.push((item.id.clone(), item.base_type.as_native().vtable_symbol.clone())); .push((item.id.clone(), item.base_type.as_native().cpp_vtable_getter.clone()));
} }
}); });
@ -1089,10 +1089,18 @@ fn generate_component(
} }
if !item_names_and_vt_symbols.is_empty() { if !item_names_and_vt_symbols.is_empty() {
destructor.push("sixtyfps::private_api::ItemRef items[] = {".into()); destructor.push("sixtyfps::private_api::ItemRef items[] = {".into());
destructor.push(item_names_and_vt_symbols.iter() destructor.push(
.map(|(item_name, vt_symbol)| item_names_and_vt_symbols
format!("{{ &sixtyfps::private_api::{vt}, const_cast<decltype(this->{id})*>(&this->{id}) }}", id = item_name, vt = vt_symbol) .iter()
).join(",")); .map(|(item_name, vt_symbol)| {
format!(
"{{ {vt}, const_cast<decltype(this->{id})*>(&this->{id}) }}",
id = item_name,
vt = vt_symbol
)
})
.join(","),
);
destructor.push("};".into()); destructor.push("};".into());
destructor.push("window.free_graphics_resources(sixtyfps::Slice<sixtyfps::private_api::ItemRef>{items, std::size(items)});".into()); destructor.push("window.free_graphics_resources(sixtyfps::Slice<sixtyfps::private_api::ItemRef>{items, std::size(items)});".into());
} }
@ -1230,8 +1238,8 @@ fn generate_component(
name: "root_item".into(), name: "root_item".into(),
signature: "() const -> sixtyfps::private_api::ItemRef".into(), signature: "() const -> sixtyfps::private_api::ItemRef".into(),
statements: Some(vec![format!( statements: Some(vec![format!(
"return {{ &sixtyfps::private_api::{vt}, const_cast<decltype(this->{id})*>(&this->{id}) }};", "return {{ {vt}, const_cast<decltype(this->{id})*>(&this->{id}) }};",
vt = root_elem.base_type.as_native().vtable_symbol, vt = root_elem.base_type.as_native().cpp_vtable_getter,
id = root_elem.id id = root_elem.id
)]), )]),
..Default::default() ..Default::default()
@ -1570,8 +1578,8 @@ fn compile_expression(
let item = item.upgrade().unwrap(); let item = item.upgrade().unwrap();
let item = item.borrow(); let item = item.borrow();
let native_item = item.base_type.as_native(); let native_item = item.base_type.as_native();
format!("sixtyfps::private_api::{vt}.implicit_size({{&sixtyfps::private_api::{vt}, const_cast<sixtyfps::{ty}*>(&self->{id})}}, &window)", format!("{vt}->implicit_size({{{vt}, const_cast<sixtyfps::{ty}*>(&self->{id})}}, &window)",
vt = native_item.vtable_symbol, vt = native_item.cpp_vtable_getter,
ty = native_item.class_name, ty = native_item.class_name,
id = item.id id = item.id
) )
@ -1982,8 +1990,8 @@ fn get_layout_info_ref<'a, 'b>(
}); });
let elem_info = item.element.as_ref().map(|elem| { let elem_info = item.element.as_ref().map(|elem| {
format!( format!(
"sixtyfps::private_api::{vt}.layouting_info({{&sixtyfps::private_api::{vt}, const_cast<sixtyfps::{ty}*>(&self->{id})}}, &self->window)", "{vt}->layouting_info({{{vt}, const_cast<sixtyfps::{ty}*>(&self->{id})}}, &self->window)",
vt = elem.borrow().base_type.as_native().vtable_symbol, vt = elem.borrow().base_type.as_native().cpp_vtable_getter,
ty = elem.borrow().base_type.as_native().class_name, ty = elem.borrow().base_type.as_native().class_name,
id = elem.borrow().id, id = elem.borrow().id,
) )

View file

@ -492,7 +492,7 @@ impl Default for Type {
pub struct NativeClass { pub struct NativeClass {
pub parent: Option<Rc<NativeClass>>, pub parent: Option<Rc<NativeClass>>,
pub class_name: String, pub class_name: String,
pub vtable_symbol: String, pub cpp_vtable_getter: String,
pub properties: HashMap<String, Type>, pub properties: HashMap<String, Type>,
pub deprecated_aliases: HashMap<String, String>, pub deprecated_aliases: HashMap<String, String>,
pub cpp_type: Option<String>, pub cpp_type: Option<String>,
@ -501,10 +501,13 @@ pub struct NativeClass {
impl NativeClass { impl NativeClass {
pub fn new(class_name: &str) -> Self { pub fn new(class_name: &str) -> Self {
let vtable_symbol = format!("{}VTable", class_name); let cpp_vtable_getter = format!(
"sixtyfps::private_api::get_vtable(&sixtyfps::private_api::{}VTable)",
class_name
);
Self { Self {
class_name: class_name.into(), class_name: class_name.into(),
vtable_symbol, cpp_vtable_getter,
properties: Default::default(), properties: Default::default(),
..Default::default() ..Default::default()
} }