forked from Mirrorlandia_minetest/irrlicht
Optimize scene node child removal to constant time (#275)
This commit is contained in:
parent
73e62f8676
commit
3983c29645
@ -15,6 +15,7 @@
|
|||||||
#include "matrix4.h"
|
#include "matrix4.h"
|
||||||
#include "IAttributes.h"
|
#include "IAttributes.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
@ -275,31 +276,31 @@ namespace scene
|
|||||||
|
|
||||||
child->grab();
|
child->grab();
|
||||||
child->remove(); // remove from old parent
|
child->remove(); // remove from old parent
|
||||||
Children.push_back(child);
|
// Note: This iterator is not invalidated until we erase it.
|
||||||
|
child->ThisIterator = Children.insert(Children.end(), child);
|
||||||
child->Parent = this;
|
child->Parent = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Removes a child from this scene node.
|
//! Removes a child from this scene node.
|
||||||
/** If found in the children list, the child pointer is also
|
/**
|
||||||
dropped and might be deleted if no other grab exists.
|
|
||||||
\param child A pointer to the child which shall be removed.
|
\param child A pointer to the child which shall be removed.
|
||||||
\return True if the child was removed, and false if not,
|
\return True if the child was removed, and false if not,
|
||||||
e.g. because it couldn't be found in the children list. */
|
e.g. because it belongs to a different parent or no parent. */
|
||||||
virtual bool removeChild(ISceneNode* child)
|
virtual bool removeChild(ISceneNode* child)
|
||||||
{
|
{
|
||||||
ISceneNodeList::iterator it = Children.begin();
|
if (child->Parent != this)
|
||||||
for (; it != Children.end(); ++it)
|
return false;
|
||||||
if ((*it) == child)
|
|
||||||
{
|
|
||||||
(*it)->Parent = 0;
|
|
||||||
(*it)->drop();
|
|
||||||
Children.erase(it);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
// The iterator must be set since the parent is not null.
|
||||||
|
_IRR_DEBUG_BREAK_IF(!child->ThisIterator.has_value());
|
||||||
|
auto it = *child->ThisIterator;
|
||||||
|
child->ThisIterator = std::nullopt;
|
||||||
|
child->Parent = nullptr;
|
||||||
|
child->drop();
|
||||||
|
Children.erase(it);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -309,13 +310,11 @@ namespace scene
|
|||||||
*/
|
*/
|
||||||
virtual void removeAll()
|
virtual void removeAll()
|
||||||
{
|
{
|
||||||
ISceneNodeList::iterator it = Children.begin();
|
for (auto &child : Children) {
|
||||||
for (; it != Children.end(); ++it)
|
child->Parent = nullptr;
|
||||||
{
|
child->ThisIterator = std::nullopt;
|
||||||
(*it)->Parent = 0;
|
child->drop();
|
||||||
(*it)->drop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Children.clear();
|
Children.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,10 +507,8 @@ namespace scene
|
|||||||
grab();
|
grab();
|
||||||
remove();
|
remove();
|
||||||
|
|
||||||
Parent = newParent;
|
if (newParent)
|
||||||
|
newParent->addChild(this);
|
||||||
if (Parent)
|
|
||||||
Parent->addChild(this);
|
|
||||||
|
|
||||||
drop();
|
drop();
|
||||||
}
|
}
|
||||||
@ -618,12 +615,15 @@ namespace scene
|
|||||||
//! Relative scale of the scene node.
|
//! Relative scale of the scene node.
|
||||||
core::vector3df RelativeScale;
|
core::vector3df RelativeScale;
|
||||||
|
|
||||||
//! Pointer to the parent
|
|
||||||
ISceneNode* Parent;
|
|
||||||
|
|
||||||
//! List of all children of this node
|
//! List of all children of this node
|
||||||
std::list<ISceneNode*> Children;
|
std::list<ISceneNode*> Children;
|
||||||
|
|
||||||
|
//! Iterator pointing to this node in the parent's child list.
|
||||||
|
std::optional<ISceneNodeList::iterator> ThisIterator;
|
||||||
|
|
||||||
|
//! Pointer to the parent
|
||||||
|
ISceneNode* Parent;
|
||||||
|
|
||||||
//! Pointer to the scene manager
|
//! Pointer to the scene manager
|
||||||
ISceneManager* SceneManager;
|
ISceneManager* SceneManager;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user