Don't return the ItemWeak by value

It is not working in C++ because ItemWeak has a destructor
This commit is contained in:
Olivier Goffart 2021-01-26 13:17:24 +01:00
parent 802383cd6b
commit a4abb86782
5 changed files with 25 additions and 18 deletions

View file

@ -1150,23 +1150,24 @@ fn generate_component(
let parent_item_from_parent_component = if let Some(parent_index) =
component.parent_element.upgrade().and_then(|e| e.borrow().item_index.get().map(|x| *x))
{
format!(" return {{ self->parent->self_weak.into_dyn(), {} }};", parent_index)
format!(" *result = {{ self->parent->self_weak.into_dyn(), {} }};", parent_index)
} else {
" return {};".to_owned()
"".to_owned()
};
component_struct.members.push((
Access::Private,
Declaration::Function(Function {
name: "parent_item".into(),
signature: "(sixtyfps::private_api::ComponentRef component, uintptr_t index) -> sixtyfps::private_api::ItemWeak".into(),
signature: "(sixtyfps::private_api::ComponentRef component, uintptr_t index, sixtyfps::private_api::ItemWeak *result) -> void".into(),
is_static: true,
statements: Some(vec![
format!("auto self = reinterpret_cast<const {}*>(component.instance);", component_id),
"if (index == 0) {".into(),
parent_item_from_parent_component,
" return;".into(),
"}".into(),
"return sixtyfps::private_api::parent_item(self->self_weak.into_dyn(), item_tree(), index);".into(),
"*result = sixtyfps::private_api::parent_item(self->self_weak.into_dyn(), item_tree(), index);".into(),
]),
..Default::default()
}),

View file

@ -713,21 +713,21 @@ fn generate_component(
}
}
fn parent_item(self: ::core::pin::Pin<&Self>, index: usize) -> sixtyfps::re_exports::ItemWeak {
fn parent_item(self: ::core::pin::Pin<&Self>, index: usize, result: &mut sixtyfps::re_exports::ItemWeak) {
if index == 0 {
#(
if let Some(parent) = self.parent.clone().into_dyn().upgrade() {
return sixtyfps::re_exports::ItemRc::new(parent, #parent_item_index).downgrade();
*result = sixtyfps::re_exports::ItemRc::new(parent, #parent_item_index).downgrade();
}
)*
return sixtyfps::re_exports::ItemWeak::default();
return;
}
let parent_index = match &Self::item_tree()[index] {
ItemTreeNode::Item { parent_index, .. } => *parent_index,
ItemTreeNode::DynamicTree { parent_index, .. } => *parent_index,
};
let self_rc = self.self_weak.get().unwrap().clone().into_dyn().upgrade().unwrap();
ItemRc::new(self_rc, parent_index as _).downgrade()
*result = ItemRc::new(self_rc, parent_index as _).downgrade()
}
}
}),

View file

@ -38,9 +38,11 @@ pub struct ComponentVTable {
index: usize,
) -> core::pin::Pin<VRef<ItemVTable>>,
/// Return the parent item. The return value is an item weak because it can be null if
/// there is no parent
pub parent_item: extern "C" fn(core::pin::Pin<VRef<ComponentVTable>>, index: usize) -> ItemWeak,
/// Return the parent item.
/// The return value is an item weak because it can be null if there is no parent.
/// And the return value is passed by &mut because ItemWeak has a destructor
pub parent_item:
extern "C" fn(core::pin::Pin<VRef<ComponentVTable>>, index: usize, result: &mut ItemWeak),
/// Returns the layout info for this component
pub layout_info: extern "C" fn(core::pin::Pin<VRef<ComponentVTable>>) -> LayoutInfo,

View file

@ -128,9 +128,13 @@ impl ItemRc {
pub fn downgrade(&self) -> ItemWeak {
ItemWeak { component: VRc::downgrade(&self.component), index: self.index }
}
/// Return the parent Item in the item tree.
/// This is weak because it can be null if there is no parent
pub fn parent_item(&self) -> ItemWeak {
let comp_ref_pin = vtable::VRc::borrow_pin(&self.component);
comp_ref_pin.as_ref().parent_item(self.index)
let mut r = ItemWeak::default();
comp_ref_pin.as_ref().parent_item(self.index, &mut r);
r
}
}

View file

@ -211,8 +211,8 @@ impl Component for ErasedComponentBox {
// indirection and call our implementation directly.
unsafe { get_item_ref(self.get_ref().borrow(), index) }
}
fn parent_item(self: Pin<&Self>, index: usize) -> ItemWeak {
self.borrow().as_ref().parent_item(index)
fn parent_item(self: Pin<&Self>, index: usize, result: &mut ItemWeak) {
self.borrow().as_ref().parent_item(index, result)
}
}
@ -1490,7 +1490,7 @@ unsafe extern "C" fn get_item_ref(component: ComponentRefPin, index: usize) -> P
}
}
unsafe extern "C" fn parent_item(component: ComponentRefPin, index: usize) -> ItemWeak {
unsafe extern "C" fn parent_item(component: ComponentRefPin, index: usize, result: &mut ItemWeak) {
generativity::make_guard!(guard);
let instance_ref = InstanceRef::from_pin_ref(component, guard);
if index == 0 {
@ -1514,17 +1514,17 @@ unsafe extern "C" fn parent_item(component: ComponentRefPin, index: usize) -> It
.into_dyn()
.upgrade()
.unwrap();
return ItemRc::new(parent_rc, parent_index).downgrade();
*result = ItemRc::new(parent_rc, parent_index).downgrade();
};
}
return ItemWeak::default();
return;
}
let parent_index = match &instance_ref.component_type.item_tree.as_slice()[index] {
ItemTreeNode::Item { parent_index, .. } => parent_index,
ItemTreeNode::DynamicTree { parent_index, .. } => parent_index,
};
let self_rc = instance_ref.self_weak().get().unwrap().clone().into_dyn().upgrade().unwrap();
ItemRc::new(self_rc, *parent_index as _).downgrade()
*result = ItemRc::new(self_rc, *parent_index as _).downgrade();
}
unsafe extern "C" fn drop_in_place(component: vtable::VRefMut<ComponentVTable>) -> vtable::Layout {