/* called with cs_cfgui held */ static void cfgui_clear_params(khui_config_node_i * node) { khui_config_node_i * c; node->hwnd = NULL; node->param = 0; node->flags &= KHUI_CNFLAGMASK_STATIC; clear_node_data(node); c = TFIRSTCHILD(node); while(c) { cfgui_clear_params(c); c = LNEXT(c); } }
/*------------------------------------- * Node Deletion -------------------------------------*/ unsigned SceneGraph::delete_node(const unsigned nodeIndex) noexcept { unsigned numDeleted = 1; if (nodeIndex == scene_property_t::SCENE_GRAPH_ROOT_ID) { numDeleted = nodes.size(); clear_node_data(); return numDeleted; } // No mercy for client code LS_DEBUG_ASSERT(nodeIndex < nodes.size()); // Remove all child nodes and their data for (unsigned i = nodes.size(); i --> nodeIndex;) { if (currentTransforms[i].parentId == nodeIndex) { numDeleted += delete_node(i); } } const SceneNode& n = nodes[nodeIndex]; const scene_node_t typeId = n.type; const uint32_t dataId = n.dataId; const uint32_t animId = n.animListId; LS_DEBUG_ASSERT(nodeIndex == n.nodeId); // Delete any specific data associated with the node. switch (typeId) { case scene_node_t::NODE_TYPE_CAMERA: delete_camera_node_data(dataId); break; case scene_node_t::NODE_TYPE_MESH: delete_mesh_node_data(dataId); break; case scene_node_t::NODE_TYPE_EMPTY: break; } // Delete the actual node nodes.erase (nodes.begin() + nodeIndex); currentTransforms.erase (currentTransforms.begin() + nodeIndex); baseTransforms.erase (baseTransforms.begin() + nodeIndex); modelMatrices.erase (modelMatrices.begin() + nodeIndex); nodeNames.erase (nodeNames.begin() + nodeIndex); // early exit in case there are no animations tied to the current node. delete_node_animation_data(nodeIndex, animId); // Decrement all node ID and data ID indices that are greater than those in // the current node. Also deal with the last bit of transformation data in // case a recursive deletion is in required. for (unsigned i = nodes.size(); i --> nodeIndex;) { SceneNode& nextNode = nodes[i]; const scene_node_t nextType = nextNode.type; unsigned& nextDataId = nextNode.dataId; unsigned& nextAnimId = nextNode.animListId; Transform& nextTransform = currentTransforms[i]; const unsigned nextParentId = nextTransform.parentId; // Placing assertion here because nodeIds must never equate to the // root node ID. They must always have tangible data to point at. LS_DEBUG_ASSERT(nextNode.nodeId != scene_property_t::SCENE_GRAPH_ROOT_ID); nodes[i].nodeId = i; if (nextParentId > nodeIndex && nextParentId != scene_property_t::SCENE_GRAPH_ROOT_ID) { // decrement the next node's parent ID if necessary nextTransform.parentId = nextParentId - 1; } // the node dataId member can be equal to the root node ID. This is // because empty nodes may not have have data to use. if (nextType == typeId && nextDataId > dataId && nextDataId != scene_property_t::SCENE_GRAPH_ROOT_ID ) { --nextDataId; } // decrement the animation ID from all nodes with a value greater than // the current node's if (nextAnimId > animId && nextAnimId != scene_property_t::SCENE_GRAPH_ROOT_ID) { --nextAnimId; } } return numDeleted; }