mirror of
https://github.com/overte-org/overte.git
synced 2025-07-10 18:58:37 +02:00
Merge pull request #3372 from ZappoMan/entitiesCrashes
Fixes the several entity crashes
This commit is contained in:
commit
68cc49f19e
4 changed files with 39 additions and 3 deletions
|
@ -125,6 +125,12 @@ bool DeleteEntityOperator::postRecursion(OctreeElement* element) {
|
||||||
if ((subTreeContainsSomeEntitiesToDelete(element))) {
|
if ((subTreeContainsSomeEntitiesToDelete(element))) {
|
||||||
element->markWithChangedTime();
|
element->markWithChangedTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It should always be ok to prune children. Because we are only in this PostRecursion function if
|
||||||
|
// we've already finished processing all of the children of this current element. If any of those
|
||||||
|
// children are the containing element for any entity in our lists of entities to delete, then they
|
||||||
|
// must have already deleted the entity, and they are safe to prune. Since this operation doesn't
|
||||||
|
// ever add any elements we don't have to worry about memory being reused within this recursion pass.
|
||||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||||
entityTreeElement->pruneChildren(); // take this opportunity to prune any empty leaves
|
entityTreeElement->pruneChildren(); // take this opportunity to prune any empty leaves
|
||||||
return keepSearching; // if we haven't yet found it, keep looking
|
return keepSearching; // if we haven't yet found it, keep looking
|
||||||
|
|
|
@ -39,6 +39,9 @@ void EntityTree::eraseAllOctreeElements(bool createNewRoot) {
|
||||||
}
|
}
|
||||||
_entityToElementMap.clear();
|
_entityToElementMap.clear();
|
||||||
Octree::eraseAllOctreeElements(createNewRoot);
|
Octree::eraseAllOctreeElements(createNewRoot);
|
||||||
|
_movingEntities.clear();
|
||||||
|
_changingEntities.clear();
|
||||||
|
_mortalEntities.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTree::handlesEditPacketType(PacketType packetType) const {
|
bool EntityTree::handlesEditPacketType(PacketType packetType) const {
|
||||||
|
@ -859,6 +862,7 @@ void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) {
|
||||||
|
|
||||||
// TODO: consider consolidating processEraseMessageDetails() and processEraseMessage()
|
// TODO: consider consolidating processEraseMessageDetails() and processEraseMessage()
|
||||||
int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
||||||
|
lockForWrite();
|
||||||
const unsigned char* packetData = (const unsigned char*)dataByteArray.constData();
|
const unsigned char* packetData = (const unsigned char*)dataByteArray.constData();
|
||||||
const unsigned char* dataAt = packetData;
|
const unsigned char* dataAt = packetData;
|
||||||
size_t packetLength = dataByteArray.size();
|
size_t packetLength = dataByteArray.size();
|
||||||
|
@ -901,10 +905,13 @@ int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const Share
|
||||||
}
|
}
|
||||||
deleteEntities(entityItemIDsToDelete);
|
deleteEntities(entityItemIDsToDelete);
|
||||||
}
|
}
|
||||||
|
unlock();
|
||||||
|
|
||||||
return processedBytes;
|
return processedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This version skips over the header
|
// This version skips over the header
|
||||||
|
// NOTE: Caller must lock the tree before calling this.
|
||||||
// TODO: consider consolidating processEraseMessageDetails() and processEraseMessage()
|
// TODO: consider consolidating processEraseMessageDetails() and processEraseMessage()
|
||||||
int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) {
|
||||||
const unsigned char* packetData = (const unsigned char*)dataByteArray.constData();
|
const unsigned char* packetData = (const unsigned char*)dataByteArray.constData();
|
||||||
|
@ -938,7 +945,6 @@ int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, cons
|
||||||
}
|
}
|
||||||
deleteEntities(entityItemIDsToDelete);
|
deleteEntities(entityItemIDsToDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
return processedBytes;
|
return processedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ void MovingEntitiesOperator::addEntityToMoveList(EntityItem* entity, const AACub
|
||||||
// check our tree, to determine if this entity is known
|
// check our tree, to determine if this entity is known
|
||||||
EntityToMoveDetails details;
|
EntityToMoveDetails details;
|
||||||
details.oldContainingElement = oldContainingElement;
|
details.oldContainingElement = oldContainingElement;
|
||||||
|
details.oldContainingElementCube = oldContainingElement->getAACube();
|
||||||
details.entity = entity;
|
details.entity = entity;
|
||||||
details.oldFound = false;
|
details.oldFound = false;
|
||||||
details.newFound = false;
|
details.newFound = false;
|
||||||
|
@ -123,8 +124,30 @@ bool MovingEntitiesOperator::postRecursion(OctreeElement* element) {
|
||||||
element->markWithChangedTime();
|
element->markWithChangedTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
|
||||||
entityTreeElement->pruneChildren(); // take this opportunity to prune any empty leaves
|
|
||||||
|
// It's not OK to prune if we have the potential of deleting the original containig element.
|
||||||
|
// because if we prune the containing element then new might end up reallocating the same memory later
|
||||||
|
// and that will confuse our logic.
|
||||||
|
//
|
||||||
|
// it's ok to prune if:
|
||||||
|
// 2) this subtree doesn't contain any old elements
|
||||||
|
// 3) this subtree contains an old element, but this element isn't a direct parent of any old containing element
|
||||||
|
|
||||||
|
bool elementSubTreeContainsOldElements = false;
|
||||||
|
bool elementIsDirectParentOfOldElment = false;
|
||||||
|
foreach(const EntityToMoveDetails& details, _entitiesToMove) {
|
||||||
|
if (element->getAACube().contains(details.oldContainingElementCube)) {
|
||||||
|
elementSubTreeContainsOldElements = true;
|
||||||
|
}
|
||||||
|
if (element->isParentOf(details.oldContainingElement)) {
|
||||||
|
elementIsDirectParentOfOldElment = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!elementSubTreeContainsOldElements || !elementIsDirectParentOfOldElment) {
|
||||||
|
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||||
|
entityTreeElement->pruneChildren(); // take this opportunity to prune any empty leaves
|
||||||
|
}
|
||||||
|
|
||||||
return keepSearching; // if we haven't yet found it, keep looking
|
return keepSearching; // if we haven't yet found it, keep looking
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
AACube newCube;
|
AACube newCube;
|
||||||
AABox newBox;
|
AABox newBox;
|
||||||
EntityTreeElement* oldContainingElement;
|
EntityTreeElement* oldContainingElement;
|
||||||
|
AACube oldContainingElementCube;
|
||||||
bool oldFound;
|
bool oldFound;
|
||||||
bool newFound;
|
bool newFound;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue