//============================================================================== bool Node::isRemoved() const { if(nullptr == mBodyNode) { REPORT_INVALID_NODE(isRemoved); return true; } return !mAmAttached; }
//============================================================================== bool Node::isRemoved() const { if(nullptr == mBodyNode) { REPORT_INVALID_NODE(isRemoved); return true; } return (mBodyNode->mNodeMap.find(this) == mBodyNode->mNodeMap.end()); }
//============================================================================== void Node::stageForRemoval() { if(nullptr == mBodyNode) { REPORT_INVALID_NODE(stageForRemoval); return; } // If we are in release mode, and the Node believes it is detached, then we // can shortcut this procedure. #ifdef NDEBUG if(!mAmAttached) return; #endif mBodyNode->incrementVersion(); BodyNode::NodeMap::iterator it = mBodyNode->mNodeMap.find(typeid(*this)); NodeDestructorPtr destructor = getOrCreateDestructor(); BodyNode::NodeDestructorSet& destructors = mBodyNode->mNodeDestructors; if(mBodyNode->mNodeMap.end() == it) { // If the Node was not in the map, then its index should be invalid assert(INVALID_INDEX == mIndexInBodyNode); // If the Node was not in the map, then its destructor should not be in the set assert(destructors.find(destructor) == destructors.end()); return; } BodyNode::NodeDestructorSet::iterator destructor_iter = destructors.find(destructor); // This Node's destructor should be in the set of destructors assert(destructors.end() != destructor_iter); std::vector<Node*>& nodes = it->second; // This Node's index in the vector should be referring to this Node assert(nodes[mIndexInBodyNode] == this); nodes.erase(nodes.begin() + mIndexInBodyNode); destructors.erase(destructor_iter); // Reset all the Node indices that have been altered for(std::size_t i=mIndexInBodyNode; i < nodes.size(); ++i) nodes[i]->mIndexInBodyNode = i; assert(std::find(nodes.begin(), nodes.end(), this) == nodes.end()); const SkeletonPtr& skel = mBodyNode->getSkeleton(); if(skel) skel->unregisterNode(this); mIndexInBodyNode = INVALID_INDEX; mAmAttached = false; }
//============================================================================== Node::Node(ConstructNode_t, BodyNode* _bn) : mBodyNode(_bn) { if(nullptr == mBodyNode) { REPORT_INVALID_NODE(Node); return; } attach(); }
//============================================================================== void Node::attach() { if(nullptr == mBodyNode) { REPORT_INVALID_NODE(attach); return; } if(mBodyNode->mNodeMap.end() == mBodyNode->mNodeMap.find(this)) mBodyNode->mNodeMap[this] = getOrCreateDestructor(); }
//============================================================================== void Node::attach() { if(nullptr == mBodyNode) { REPORT_INVALID_NODE(attach); return; } // If we are in release mode, and the Node believes it is attached, then we // can shortcut this procedure #ifdef NDEBUG if(mAmAttached) return; #endif using NodeMapPair = std::pair<std::type_index, std::vector<Node*>>; // Add empty list of Node pointers only when typeid(*this) doesn't exist. BodyNode::NodeMap::iterator it = mBodyNode->mNodeMap.insert( NodeMapPair(typeid(*this), std::vector<Node*>())).first; std::vector<Node*>& nodes = it->second; BodyNode::NodeDestructorSet& destructors = mBodyNode->mNodeDestructors; NodeDestructorPtr destructor = getOrCreateDestructor(); if(INVALID_INDEX == mIndexInBodyNode) { // If the Node was not in the map, then its destructor should not be in the set assert(destructors.find(destructor) == destructors.end()); // If this Node believes its index is invalid, then it should not exist // anywhere in the vector assert(std::find(nodes.begin(), nodes.end(), this) == nodes.end()); nodes.push_back(this); mIndexInBodyNode = nodes.size()-1; destructors.insert(destructor); } assert(std::find(nodes.begin(), nodes.end(), this) != nodes.end()); assert(destructors.find(destructor) != destructors.end()); const SkeletonPtr& skel = mBodyNode->getSkeleton(); if(skel) skel->registerNode(this); mAmAttached = true; }
//============================================================================== void Node::stageForRemoval() { if(nullptr == mBodyNode) { REPORT_INVALID_NODE(stageForRemoval); return; } const auto it = mBodyNode->mNodeMap.find(this); if(mBodyNode->mNodeMap.end() == it) return; mBodyNode->mNodeMap.erase(it); }
//============================================================================== Node::Node(BodyNode* _bn) : mBodyNode(_bn), mAmAttached(false), mIndexInBodyNode(INVALID_INDEX), mIndexInSkeleton(INVALID_INDEX), mIndexInTree(INVALID_INDEX) { if(nullptr == mBodyNode) { REPORT_INVALID_NODE(Node); return; } if(mBodyNode != this) setVersionDependentObject(mBodyNode); }