/* LICENSE BEGIN This file is part of the SixtyFPS Project -- https://sixtyfps.io Copyright (c) 2020 Olivier Goffart Copyright (c) 2020 Simon Hausmann SPDX-License-Identifier: GPL-3.0-only This file is also available under commercial licensing terms. Please contact info@sixtyfps.io for more information. LICENSE END */ #![warn(missing_docs)] //! This module contains the basic datastructures that are exposed to the C API use crate::graphics::Rect; use crate::item_tree::{ItemVisitorVTable, TraversalOrder, VisitChildrenResult}; use crate::items::ItemVTable; use crate::layout::LayoutInfo; use crate::window::ComponentWindow; use vtable::*; /// A Component is representing an unit that is allocated together #[vtable] #[repr(C)] pub struct ComponentVTable { /// Visit the children of the item at index `index`. /// Note that the root item is at index 0, so passing 0 would visit the item under root (the children of root). /// If you want to visit the root item, you need to pass -1 as an index. pub visit_children_item: extern "C" fn( core::pin::Pin>, index: isize, order: TraversalOrder, visitor: VRefMut, ) -> VisitChildrenResult, /// Return a reference to an item using the given index pub get_item_ref: extern "C" fn( core::pin::Pin>, index: usize, ) -> core::pin::Pin>, /// Returns the layout info for this component pub layout_info: extern "C" fn(core::pin::Pin>) -> LayoutInfo, /// Apply the layout to all the items in the component, and set the geometry of the root to the given rect pub apply_layout: extern "C" fn(core::pin::Pin>, Rect), /// in-place destructor (for VRc) pub drop_in_place: unsafe fn(VRefMut) -> vtable::Layout, /// dealloc function (for VRc) pub dealloc: unsafe fn(&ComponentVTable, ptr: *mut u8, layout: vtable::Layout), } /// Alias for `vtable::VRef` which represent a pointer to a `dyn Component` with /// the associated vtable pub type ComponentRef<'a> = vtable::VRef<'a, ComponentVTable>; /// Type alias to the commonly used `Pin>>` pub type ComponentRefPin<'a> = core::pin::Pin>; /// Type alias to the commonly used VRc> pub type ComponentRc = vtable::VRc; /// Type alias to the commonly used VWeak> pub type ComponentWeak = vtable::VWeak; /// Call init() on the ItemVTable for each item of the component. pub fn init_component_items( base: core::pin::Pin<&Base>, item_tree: &[crate::item_tree::ItemTreeNode], window: &ComponentWindow, ) { item_tree.iter().for_each(|entry| match entry { crate::item_tree::ItemTreeNode::Item { item, .. } => { item.apply_pin(base).as_ref().init(window) } crate::item_tree::ItemTreeNode::DynamicTree { .. } => {} }) } pub(crate) mod ffi { #![allow(unsafe_code)] use super::*; use crate::item_tree::*; use crate::slice::Slice; /// Call init() on the ItemVTable of each item of the component. #[no_mangle] pub unsafe extern "C" fn sixtyfps_component_init_items( component: ComponentRefPin, item_tree: Slice>, window_handle: *const crate::window::ffi::ComponentWindowOpaque, ) { let window = &*(window_handle as *const ComponentWindow); super::init_component_items( core::pin::Pin::new_unchecked(&*(component.as_ptr() as *const u8)), item_tree.as_slice(), window, ) } }