cranpose-core 0.0.60

Core runtime for a Jetpack Compose inspired UI framework in Rust
Documentation
use super::super::{
    ChildCursor, DetachedSubtree, FinishGroupResult, SlotLifecycleCoordinator, SlotTable,
    SlotWriteSession,
};
use super::SlotWriteSessionState;

impl SlotTable {
    fn detach_unvisited_children_internal(
        &mut self,
        state: &mut SlotWriteSessionState,
    ) -> Vec<DetachedSubtree> {
        let (parent_anchor, next_child_index) = {
            let frame = state
                .group_stack
                .last()
                .expect("detach_unvisited_children requires an active group");
            (frame.group_anchor, frame.next_child_index)
        };
        let cursor = ChildCursor::new(parent_anchor, next_child_index);
        let detached_children = self.detach_subtrees_at_cursor(cursor);
        state.note_detached_subtrees(&detached_children);
        detached_children
    }

    fn finish_group_body_internal(
        &mut self,
        lifecycle: &mut SlotLifecycleCoordinator,
        state: &mut SlotWriteSessionState,
    ) -> FinishGroupResult {
        let (group_anchor, payload_cursor, node_cursor, was_skipped) = {
            let frame = state
                .group_stack
                .last_mut()
                .expect("finish_group_body requires an active group");
            if !frame.mark_body_finished() {
                return FinishGroupResult {
                    detached_children: Vec::new(),
                    direct_nodes: Vec::new(),
                    root_nodes: Vec::new(),
                    was_skipped: false,
                };
            }

            (
                frame.group_anchor,
                frame.payload_cursor,
                frame.node_cursor,
                frame.was_skipped,
            )
        };

        {
            let removed = self.remove_payload_tail_at_cursor(group_anchor, payload_cursor);
            if !removed.is_empty() {
                let removed_payload_count = removed.len();
                for payload in removed {
                    lifecycle.queue_drop(payload.into_deferred_drop());
                }
                state.note_removed_payloads(removed_payload_count);
            }
        }
        self.flush_payload_location_refreshes(state);
        #[cfg(any(test, debug_assertions))]
        state.debug_assert_no_pending_payload_location_refreshes("finish_group_body");

        let mut direct_nodes = Vec::new();
        let removed = self.remove_group_node_tail_at_cursor(group_anchor, node_cursor);
        if !removed.is_empty() {
            direct_nodes.extend(removed.into_iter().map(|node| node.id));
        }

        let detached_children = self.detach_unvisited_children_internal(state);
        let root_nodes = if was_skipped {
            self.collect_subtree_root_node_ids(group_anchor)
        } else {
            Vec::new()
        };
        state.note_removed_nodes(direct_nodes.len());
        let result = FinishGroupResult {
            detached_children,
            direct_nodes,
            root_nodes,
            was_skipped,
        };

        #[cfg(any(test, debug_assertions))]
        if state.group_stack.len() == 1 {
            self.debug_assert_valid_after("finish_group_body");
        }

        result
    }
}

impl SlotWriteSession<'_> {
    pub(crate) fn finish_group_body(&mut self) -> FinishGroupResult {
        self.table
            .finish_group_body_internal(self.lifecycle, self.state)
    }
}