mirror of
https://github.com/lubosz/overte.git
synced 2025-04-16 15:30:11 +02:00
avoid mem-leaked entities when clearing tree
This commit is contained in:
parent
ed9ebf84c9
commit
33d6e2ce3b
1 changed files with 29 additions and 11 deletions
|
@ -52,7 +52,15 @@ EntityTree::EntityTree(bool shouldReaverage) :
|
|||
}
|
||||
|
||||
EntityTree::~EntityTree() {
|
||||
eraseAllOctreeElements(false);
|
||||
// NOTE: to eraseAllOctreeElements() in this context is useless because
|
||||
// any OctreeElements in the tree still have shared backpointers to this Tree
|
||||
// which means the dtor never would have been called in the first place!
|
||||
//
|
||||
// I'm keeping this useless commented-out line to remind us:
|
||||
// we don't need shared pointer overhead for EntityTrees.
|
||||
// TODO: EntityTreeElement::_tree should be raw back pointer.
|
||||
// AND: EntityItem::_element should be a raw back pointer.
|
||||
//eraseAllOctreeElements(false); // KEEP THIS
|
||||
}
|
||||
|
||||
void EntityTree::setEntityScriptSourceWhitelist(const QString& entityScriptSourceWhitelist) {
|
||||
|
@ -74,16 +82,15 @@ void EntityTree::eraseNonLocalEntities() {
|
|||
emit clearingEntities();
|
||||
|
||||
if (_simulation) {
|
||||
// This will clear all entities host types including local entities, because local entities
|
||||
// are not in the physics simulation
|
||||
// local entities are not in the simulation, so we clear ALL
|
||||
_simulation->clearEntities();
|
||||
}
|
||||
_staleProxies.clear();
|
||||
QHash<EntityItemID, EntityItemPointer> localMap;
|
||||
localMap.swap(_entityMap);
|
||||
QHash<EntityItemID, EntityItemPointer> savedEntities;
|
||||
this->withWriteLock([&] {
|
||||
foreach(EntityItemPointer entity, localMap) {
|
||||
QHash<EntityItemID, EntityItemPointer> savedEntities;
|
||||
// NOTE: lock the Tree first, then lock the _entityMap.
|
||||
// It should never be done the other way around.
|
||||
QReadLocker locker(&_entityMapLock);
|
||||
foreach(EntityItemPointer entity, _entityMap) {
|
||||
EntityTreeElementPointer element = entity->getElement();
|
||||
if (element) {
|
||||
element->cleanupNonLocalEntities();
|
||||
|
@ -91,11 +98,16 @@ void EntityTree::eraseNonLocalEntities() {
|
|||
|
||||
if (entity->isLocalEntity()) {
|
||||
savedEntities[entity->getEntityItemID()] = entity;
|
||||
} else {
|
||||
int32_t spaceIndex = entity->getSpaceIndex();
|
||||
if (spaceIndex != -1) {
|
||||
// stale spaceIndices will be freed later
|
||||
_staleProxies.push_back(spaceIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
_entityMap.swap(savedEntities);
|
||||
});
|
||||
localMap.clear();
|
||||
_entityMap = savedEntities;
|
||||
|
||||
resetClientEditStats();
|
||||
clearDeletedEntities();
|
||||
|
@ -113,13 +125,13 @@ void EntityTree::eraseNonLocalEntities() {
|
|||
_needsParentFixup = localEntitiesNeedsParentFixup;
|
||||
}
|
||||
}
|
||||
|
||||
void EntityTree::eraseAllOctreeElements(bool createNewRoot) {
|
||||
emit clearingEntities();
|
||||
|
||||
if (_simulation) {
|
||||
_simulation->clearEntities();
|
||||
}
|
||||
_staleProxies.clear();
|
||||
QHash<EntityItemID, EntityItemPointer> localMap;
|
||||
localMap.swap(_entityMap);
|
||||
this->withWriteLock([&] {
|
||||
|
@ -128,6 +140,11 @@ void EntityTree::eraseAllOctreeElements(bool createNewRoot) {
|
|||
if (element) {
|
||||
element->cleanupEntities();
|
||||
}
|
||||
int32_t spaceIndex = entity->getSpaceIndex();
|
||||
if (spaceIndex != -1) {
|
||||
// assume stale spaceIndices will be freed later
|
||||
_staleProxies.push_back(spaceIndex);
|
||||
}
|
||||
}
|
||||
});
|
||||
localMap.clear();
|
||||
|
@ -767,6 +784,7 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator)
|
|||
// keep a record of valid stale spaceIndices so they can be removed from the Space
|
||||
int32_t spaceIndex = theEntity->getSpaceIndex();
|
||||
if (spaceIndex != -1) {
|
||||
// stale spaceIndices will be freed later
|
||||
_staleProxies.push_back(spaceIndex);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue