mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-14 12:36:34 +02:00
add EntityTree::_pendingDelete for delayed deletes
for case where EntitySimuation needs time to remove pointers
This commit is contained in:
parent
4cb469dd79
commit
31ca5b9eef
2 changed files with 26 additions and 8 deletions
|
@ -350,10 +350,12 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_simulation && theEntity->getSimulation()) {
|
if (_simulation && theEntity->getSimulation()) {
|
||||||
// delegate entity destruction to the simulation so it can clean up its own pointers
|
_simulation->removeEntity(theEntity);
|
||||||
_simulation->deleteEntity(theEntity);
|
// we need to give the simulation time to cleanup its own pointers
|
||||||
|
// so we push theEntity onto the _pendingDeletes and check again later.
|
||||||
|
_pendingDeletes.insert(theEntity);
|
||||||
} else {
|
} else {
|
||||||
delete theEntity; // we can delete the entity directly now
|
delete theEntity; // we can delete the entity immediately
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_simulation) {
|
if (_simulation) {
|
||||||
|
@ -754,16 +756,30 @@ void EntityTree::update() {
|
||||||
lockForWrite();
|
lockForWrite();
|
||||||
_simulation->lock();
|
_simulation->lock();
|
||||||
_simulation->updateEntities();
|
_simulation->updateEntities();
|
||||||
SetOfEntities entitiesToDelete;
|
_simulation->getEntitiesToDelete(_pendingDeletes);
|
||||||
_simulation->getEntitiesToDelete(entitiesToDelete);
|
|
||||||
_simulation->unlock();
|
_simulation->unlock();
|
||||||
|
|
||||||
if (entitiesToDelete.size() > 0) {
|
if (_pendingDeletes.size() > 0) {
|
||||||
// translate into list of ID's
|
// translate into list of ID's
|
||||||
QSet<EntityItemID> idsToDelete;
|
QSet<EntityItemID> idsToDelete;
|
||||||
foreach (EntityItem* entity, entitiesToDelete) {
|
SetOfEntities::iterator entityItr = _pendingDeletes.begin();
|
||||||
|
while (entityItr != _pendingDeletes.end()) {
|
||||||
|
EntityItem* entity = *entityItr;
|
||||||
|
if (entity->getElement()) {
|
||||||
|
// this entity is still in an element so we push it's ID on a list (and delete the roundabout way)
|
||||||
idsToDelete.insert(entity->getEntityItemID());
|
idsToDelete.insert(entity->getEntityItemID());
|
||||||
|
entityItr = _pendingDeletes.erase(entityItr);
|
||||||
|
} else if (!entity->getSimulation()) {
|
||||||
|
// the entity is not in any simulation so we can delete immediately
|
||||||
|
delete entity;
|
||||||
|
entityItr = _pendingDeletes.erase(entityItr);
|
||||||
|
} else {
|
||||||
|
// we're waiting for the simulation to cleanup its own data structure
|
||||||
|
// so we leave it on the _pendingDeletes and will try again later
|
||||||
|
++entityItr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// delete these things the roundabout way
|
||||||
deleteEntities(idsToDelete, true);
|
deleteEntities(idsToDelete, true);
|
||||||
}
|
}
|
||||||
unlock();
|
unlock();
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "EntityTreeElement.h"
|
#include "EntityTreeElement.h"
|
||||||
#include "DeleteEntityOperator.h"
|
#include "DeleteEntityOperator.h"
|
||||||
|
|
||||||
|
typedef QSet<EntityItem*> SetOfEntities;
|
||||||
|
|
||||||
class Model;
|
class Model;
|
||||||
class EntitySimulation;
|
class EntitySimulation;
|
||||||
|
@ -197,6 +198,7 @@ private:
|
||||||
QHash<EntityItemID, EntityItemID> _changedEntityIDs;
|
QHash<EntityItemID, EntityItemID> _changedEntityIDs;
|
||||||
|
|
||||||
EntitySimulation* _simulation;
|
EntitySimulation* _simulation;
|
||||||
|
SetOfEntities _pendingDeletes;
|
||||||
|
|
||||||
bool _wantEditLogging = false;
|
bool _wantEditLogging = false;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue