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) = 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)) 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 { } else {
" return {};".to_owned() "".to_owned()
}; };
component_struct.members.push(( component_struct.members.push((
Access::Private, Access::Private,
Declaration::Function(Function { Declaration::Function(Function {
name: "parent_item".into(), 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, is_static: true,
statements: Some(vec![ statements: Some(vec![
format!("auto self = reinterpret_cast<const {}*>(component.instance);", component_id), format!("auto self = reinterpret_cast<const {}*>(component.instance);", component_id),
"if (index == 0) {".into(), "if (index == 0) {".into(),
parent_item_from_parent_component, parent_item_from_parent_component,
" return;".into(),
"}".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() ..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 index == 0 {
#( #(
if let Some(parent) = self.parent.clone().into_dyn().upgrade() { 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] { let parent_index = match &Self::item_tree()[index] {
ItemTreeNode::Item { parent_index, .. } => *parent_index, ItemTreeNode::Item { parent_index, .. } => *parent_index,
ItemTreeNode::DynamicTree { parent_index, .. } => *parent_index, ItemTreeNode::DynamicTree { parent_index, .. } => *parent_index,
}; };
let self_rc = self.self_weak.get().unwrap().clone().into_dyn().upgrade().unwrap(); 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, index: usize,
) -> core::pin::Pin<VRef<ItemVTable>>, ) -> core::pin::Pin<VRef<ItemVTable>>,
/// Return the parent item. The return value is an item weak because it can be null if /// Return the parent item.
/// there is no parent /// 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, /// 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 /// Returns the layout info for this component
pub layout_info: extern "C" fn(core::pin::Pin<VRef<ComponentVTable>>) -> LayoutInfo, 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 { pub fn downgrade(&self) -> ItemWeak {
ItemWeak { component: VRc::downgrade(&self.component), index: self.index } 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 { pub fn parent_item(&self) -> ItemWeak {
let comp_ref_pin = vtable::VRc::borrow_pin(&self.component); 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. // indirection and call our implementation directly.
unsafe { get_item_ref(self.get_ref().borrow(), index) } unsafe { get_item_ref(self.get_ref().borrow(), index) }
} }
fn parent_item(self: Pin<&Self>, index: usize) -> ItemWeak { fn parent_item(self: Pin<&Self>, index: usize, result: &mut ItemWeak) {
self.borrow().as_ref().parent_item(index) 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); generativity::make_guard!(guard);
let instance_ref = InstanceRef::from_pin_ref(component, guard); let instance_ref = InstanceRef::from_pin_ref(component, guard);
if index == 0 { if index == 0 {
@ -1514,17 +1514,17 @@ unsafe extern "C" fn parent_item(component: ComponentRefPin, index: usize) -> It
.into_dyn() .into_dyn()
.upgrade() .upgrade()
.unwrap(); .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] { let parent_index = match &instance_ref.component_type.item_tree.as_slice()[index] {
ItemTreeNode::Item { parent_index, .. } => parent_index, ItemTreeNode::Item { parent_index, .. } => parent_index,
ItemTreeNode::DynamicTree { parent_index, .. } => parent_index, ItemTreeNode::DynamicTree { parent_index, .. } => parent_index,
}; };
let self_rc = instance_ref.self_weak().get().unwrap().clone().into_dyn().upgrade().unwrap(); 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 { unsafe extern "C" fn drop_in_place(component: vtable::VRefMut<ComponentVTable>) -> vtable::Layout {