Ejemplo n.º 1
0
void ScrollingTree::updateTreeFromStateNode(const ScrollingStateNode* stateNode)
{
    if (!stateNode) {
        m_nodeMap.clear();
        m_rootNode = nullptr;
        return;
    }

    // This fuction recurses through the ScrollingStateTree and updates the corresponding ScrollingTreeNodes.
    // Find the ScrollingTreeNode associated with the current stateNode using the shared ID and our HashMap.
    ScrollingTreeNodeMap::const_iterator it = m_nodeMap.find(stateNode->scrollingNodeID());

    ScrollingTreeNode* node;
    if (it != m_nodeMap.end()) {
        node = it->value;
        node->updateBeforeChildren(*stateNode);
    } else {
        // If the node isn't found, it's either new and needs to be added to the tree, or there is a new ID for our
        // root node.
        ScrollingNodeID nodeID = stateNode->scrollingNodeID();
        if (!stateNode->parent()) {
            // This is the root node. Nuke the node map.
            m_nodeMap.clear();

            m_rootNode = static_pointer_cast<ScrollingTreeScrollingNode>(createNode(FrameScrollingNode, nodeID));
            m_nodeMap.set(nodeID, m_rootNode.get());
            m_rootNode->updateBeforeChildren(*stateNode);
            node = m_rootNode.get();
        } else {
            OwnPtr<ScrollingTreeNode> newNode = createNode(stateNode->nodeType(), nodeID);
            node = newNode.get();
            m_nodeMap.set(nodeID, node);
            ScrollingTreeNodeMap::const_iterator it = m_nodeMap.find(stateNode->parent()->scrollingNodeID());
            ASSERT(it != m_nodeMap.end());
            if (it != m_nodeMap.end()) {
                ScrollingTreeNode* parent = it->value;
                newNode->setParent(parent);
                parent->appendChild(newNode.release());
            }
            node->updateBeforeChildren(*stateNode);
        }
    }

    // Now update the children if we have any.
    Vector<OwnPtr<ScrollingStateNode>>* stateNodeChildren = stateNode->children();
    if (stateNodeChildren) {
        size_t size = stateNodeChildren->size();
        for (size_t i = 0; i < size; ++i)
            updateTreeFromStateNode(stateNodeChildren->at(i).get());
    }
    node->updateAfterChildren(*stateNode);
}