mirror of
https://github.com/overte-org/overte.git
synced 2025-04-24 05:53:29 +02:00
correct cleanup of Models/geometry and all EntityItems for various cases
This commit is contained in:
parent
ed6363ca02
commit
2f90df04ee
17 changed files with 65 additions and 78 deletions
|
@ -1619,14 +1619,23 @@ function handeMenuEvent(menuItem){
|
|||
print(" Delete Entity.... leftController.entityID="+ leftController.entityID);
|
||||
Entities.deleteEntity(leftController.entityID);
|
||||
leftController.grabbing = false;
|
||||
if (glowedEntityID.id == leftController.entityID.id) {
|
||||
glowedEntityID = { id: -1, isKnownID: false };
|
||||
}
|
||||
} else if (rightController.grabbing) {
|
||||
print(" Delete Entity.... rightController.entityID="+ rightController.entityID);
|
||||
Entities.deleteEntity(rightController.entityID);
|
||||
rightController.grabbing = false;
|
||||
if (glowedEntityID.id == rightController.entityID.id) {
|
||||
glowedEntityID = { id: -1, isKnownID: false };
|
||||
}
|
||||
} else if (entitySelected) {
|
||||
print(" Delete Entity.... selectedEntityID="+ selectedEntityID);
|
||||
Entities.deleteEntity(selectedEntityID);
|
||||
entitySelected = false;
|
||||
if (glowedEntityID.id == selectedEntityID.id) {
|
||||
glowedEntityID = { id: -1, isKnownID: false };
|
||||
}
|
||||
} else {
|
||||
print(" Delete Entity.... not holding...");
|
||||
}
|
||||
|
|
|
@ -42,17 +42,10 @@ EntityTreeRenderer::EntityTreeRenderer() :
|
|||
}
|
||||
|
||||
EntityTreeRenderer::~EntityTreeRenderer() {
|
||||
clearModelsCache();
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::clear() {
|
||||
OctreeRenderer::clear();
|
||||
clearModelsCache();
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::clearModelsCache() {
|
||||
// TODO: we need to implement this.... how do we want to handle this?
|
||||
qDebug() << "EntityTreeRenderer::clearModelsCache()...";
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::init() {
|
||||
|
|
|
@ -63,9 +63,6 @@ public:
|
|||
void renderEntityTypeModel(EntityItem* entity, RenderArgs* args);
|
||||
|
||||
static QThread* getMainThread();
|
||||
|
||||
protected:
|
||||
void clearModelsCache();
|
||||
};
|
||||
|
||||
#endif // hifi_EntityTreeRenderer_h
|
||||
|
|
|
@ -28,6 +28,11 @@ EntityItem* RenderableModelEntityItem::factory(const EntityItemID& entityID, con
|
|||
return new RenderableModelEntityItem(entityID, properties);
|
||||
}
|
||||
|
||||
RenderableModelEntityItem::~RenderableModelEntityItem() {
|
||||
delete _model;
|
||||
_model = NULL;
|
||||
};
|
||||
|
||||
bool RenderableModelEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
|
||||
QString oldModelURL = getModelURL();
|
||||
bool somethingChanged = ModelEntityItem::setProperties(properties, forceCopy);
|
||||
|
|
|
@ -36,15 +36,9 @@ public:
|
|||
ModelEntityItem(entityItemID, properties),
|
||||
_model(NULL),
|
||||
_needsSimulation(true),
|
||||
_needsModelReload(true) {
|
||||
|
||||
qDebug() << "*********** RenderableModelEntityItem -- ENTITY ITEM BEING CREATED ************* this=" << this;
|
||||
|
||||
};
|
||||
_needsModelReload(true) { };
|
||||
|
||||
virtual ~RenderableModelEntityItem() {
|
||||
qDebug() << "*********** RenderableModelEntityItem -- ENTITY ITEM BEING DELETED ************* this=" << this;
|
||||
};
|
||||
virtual ~RenderableModelEntityItem();
|
||||
|
||||
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy);
|
||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
|
|
|
@ -95,27 +95,14 @@ bool DeleteEntityOperator::PreRecursion(OctreeElement* element) {
|
|||
// and we can stop searching.
|
||||
if (entityTreeElement == details.containingElement) {
|
||||
|
||||
qDebug() << "DeleteEntityOperator::PreRecursion().... details.entity->getEntityItemID()=" << details.entity->getEntityItemID();
|
||||
EntityTreeElement* containingElement = _tree->getContainingElement(details.entity->getEntityItemID());
|
||||
qDebug() << "DeleteEntityOperator::PreRecursion().... BEFORE delete... containingElement=" << containingElement;
|
||||
qDebug() << "DeleteEntityOperator::PreRecursion().... BEFORE delete... details.containingElement=" << details.containingElement;
|
||||
|
||||
// This is a good place to delete it!!!
|
||||
EntityItemID entityItemID = details.entity->getEntityItemID();
|
||||
|
||||
qDebug() << "DeleteEntityOperator::PreRecursion().... calling... entityTreeElement->getEntityWithEntityItemID(entityItemID);";
|
||||
EntityItem* theEntity = entityTreeElement->getEntityWithEntityItemID(entityItemID);
|
||||
qDebug() << " theEntity=" << theEntity;
|
||||
qDebug() << "DeleteEntityOperator::PreRecursion().... calling... removeEntityItem(theEntity)";
|
||||
bool removed = entityTreeElement->removeEntityItem(theEntity);
|
||||
qDebug() << " removed=" << removed;
|
||||
|
||||
qDebug() << "DeleteEntityOperator::PreRecursion().... calling... _tree->setContainingElement(entityItemID, NULL);";
|
||||
entityTreeElement->removeEntityItem(theEntity);
|
||||
_tree->setContainingElement(entityItemID, NULL);
|
||||
|
||||
qDebug() << "DeleteEntityOperator::PreRecursion().... calling... delete theEntity";
|
||||
delete theEntity; // now actually delete it!
|
||||
|
||||
_foundCount++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,21 +57,12 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) {
|
|||
_lifetime = DEFAULT_LIFETIME;
|
||||
}
|
||||
|
||||
static int totalLiveEntities = 0;
|
||||
EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) {
|
||||
_type = EntityTypes::Unknown;
|
||||
_lastEdited = 0;
|
||||
_lastUpdated = 0;
|
||||
initFromEntityItemID(entityItemID);
|
||||
setProperties(properties, true); // force copy
|
||||
|
||||
totalLiveEntities++;
|
||||
qDebug() << "*********** ENTITY ITEM BEING CREATED ************* this=" << this << " totalLiveEntities=" << totalLiveEntities;
|
||||
}
|
||||
|
||||
EntityItem::~EntityItem() {
|
||||
totalLiveEntities--;
|
||||
qDebug() << "*********** ENTITY ITEM BEING DELETED ************* this=" << this << " totalLiveEntities=" << totalLiveEntities;
|
||||
}
|
||||
|
||||
EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
|
||||
|
|
|
@ -40,8 +40,7 @@ public:
|
|||
DONT_ALLOW_INSTANTIATION // This class can not be instantiated directly
|
||||
|
||||
EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
|
||||
virtual ~EntityItem();
|
||||
virtual ~EntityItem() { }
|
||||
|
||||
// ID and EntityItemID related methods
|
||||
QUuid getID() const { return _id; }
|
||||
|
|
|
@ -20,15 +20,23 @@ EntityTree::EntityTree(bool shouldReaverage) : Octree(shouldReaverage) {
|
|||
_rootElement = createNewElement();
|
||||
}
|
||||
|
||||
EntityTree::~EntityTree() {
|
||||
eraseAllOctreeElements(false);
|
||||
}
|
||||
|
||||
EntityTreeElement* EntityTree::createNewElement(unsigned char * octalCode) {
|
||||
EntityTreeElement* newElement = new EntityTreeElement(octalCode);
|
||||
newElement->setTree(this);
|
||||
return newElement;
|
||||
}
|
||||
|
||||
void EntityTree::eraseAllOctreeElements() {
|
||||
void EntityTree::eraseAllOctreeElements(bool createNewRoot) {
|
||||
// this would be a good place to clean up our entities...
|
||||
foreach (EntityTreeElement* element, _entityToElementMap) {
|
||||
element->cleanupEntities();
|
||||
}
|
||||
_entityToElementMap.clear();
|
||||
Octree::eraseAllOctreeElements();
|
||||
Octree::eraseAllOctreeElements(createNewRoot);
|
||||
}
|
||||
|
||||
bool EntityTree::handlesEditPacketType(PacketType packetType) const {
|
||||
|
|
|
@ -42,6 +42,7 @@ class EntityTree : public Octree {
|
|||
Q_OBJECT
|
||||
public:
|
||||
EntityTree(bool shouldReaverage = false);
|
||||
virtual ~EntityTree();
|
||||
|
||||
/// Implements our type specific root element factory
|
||||
virtual EntityTreeElement* createNewElement(unsigned char * octalCode = NULL);
|
||||
|
@ -49,7 +50,7 @@ public:
|
|||
/// Type safe version of getRoot()
|
||||
EntityTreeElement* getRoot() { return static_cast<EntityTreeElement*>(_rootElement); }
|
||||
|
||||
virtual void eraseAllOctreeElements();
|
||||
virtual void eraseAllOctreeElements(bool createNewRoot = true);
|
||||
|
||||
// These methods will allow the OctreeServer to send your tree inbound edit packets of your
|
||||
// own definition. Implement these to allow your octree based server to support editing
|
||||
|
|
|
@ -578,6 +578,15 @@ EntityItem* EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id)
|
|||
return foundEntity;
|
||||
}
|
||||
|
||||
void EntityTreeElement::cleanupEntities() {
|
||||
uint16_t numberOfEntities = _entityItems->size();
|
||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||
EntityItem* entity = (*_entityItems)[i];
|
||||
delete entity;
|
||||
}
|
||||
_entityItems->clear();
|
||||
}
|
||||
|
||||
bool EntityTreeElement::removeEntityWithEntityItemID(const EntityItemID& id) {
|
||||
bool foundEntity = false;
|
||||
uint16_t numberOfEntities = _entityItems->size();
|
||||
|
|
|
@ -141,6 +141,7 @@ public:
|
|||
|
||||
EntityItem* getEntityWithEntityItemID(const EntityItemID& id);
|
||||
|
||||
void cleanupEntities(); /// called by EntityTree on cleanup this will free all entities
|
||||
bool removeEntityWithEntityItemID(const EntityItemID& id);
|
||||
bool removeEntityItem(const EntityItem* entity);
|
||||
|
||||
|
|
|
@ -28,9 +28,6 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityI
|
|||
_type = EntityTypes::Model;
|
||||
setProperties(properties, true);
|
||||
_animationFrameIndex = 0.0f;
|
||||
|
||||
qDebug() << "*********** ModelEntityItem -- ENTITY ITEM BEING CREATED ************* this=" << this;
|
||||
|
||||
}
|
||||
|
||||
EntityItemProperties ModelEntityItem::getProperties() const {
|
||||
|
|
|
@ -19,10 +19,6 @@ public:
|
|||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
ModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
virtual ~ModelEntityItem() {
|
||||
qDebug() << "*********** ModelEntityItem -- ENTITY ITEM BEING DELETED ************* this=" << this;
|
||||
};
|
||||
|
||||
|
||||
ALLOW_INSTANTIATION // This class can be instantiated
|
||||
|
||||
|
|
|
@ -1,23 +1,7 @@
|
|||
// REQUIRED:
|
||||
|
||||
|
||||
8) Make sure EntityItems are deleted...
|
||||
delete all owned entity items on the deletion of the EntityTreeElement?
|
||||
delete all entity items on deletion of the tree?
|
||||
|
||||
cases:
|
||||
PASSED -- 1) test UI delete entity (on client)
|
||||
PASSED -- 2) test UI delete entity (on server)
|
||||
PASSED --- 7) test UI delete on other client
|
||||
|
||||
3) test client shutdown
|
||||
4) test server shutdown (on server) - aka domain restart
|
||||
5) test server shutdown (on client)
|
||||
6) test change domains
|
||||
|
||||
|
||||
|
||||
9) EntityTreeRenderer::clearModelsCache()
|
||||
10) Lifetime??
|
||||
|
||||
|
||||
7) Test file save load for case where two siblings have more than MTU amount of data. I wonder if the fact that file save
|
||||
|
@ -231,7 +215,7 @@
|
|||
// SOLVED -- 2) verify shadows work
|
||||
// SOLVED -- 9) Handle the ID -> UUID swap in old files to new files - verify old files read correctly
|
||||
// SOLVED -- 2) Test models -> attachments logic --- TESTED/WORKS
|
||||
// SOLVED -- 1) Import/Export Models - verify it works. /copy/paste??
|
||||
// SOLVED -- 1) Import/Export Models - verify it works. /copy/paste??
|
||||
// DONE -- 22d) void ModelTree::findModelsInCube(const AACube& cube, QVector<ModelItem*>& foundModels)...
|
||||
// DONE -- 22e) void ModelTreeElement::getModelsInside(const AACube& box, QVector<ModelItem*>& foundModels)...
|
||||
// DONE -- 22f) Application::exportEntities() tested/works
|
||||
|
@ -243,6 +227,19 @@
|
|||
// Note: there's a bug in production related to the overlay correctly rendering when
|
||||
// the original (non-translated positions) of the models are out of view. This is a bug
|
||||
// not introduced byt this PR.
|
||||
// SOLVED -- 8) Make sure EntityItems are deleted...
|
||||
// delete all entity items on deletion of the tree?
|
||||
// cases:
|
||||
// PASSED -- 1) test UI delete entity (on client)
|
||||
// PASSED -- 2) test UI delete entity (on server)
|
||||
// PASSED --- 7) test UI delete on other client
|
||||
// PASSED --- 3) test client shutdown
|
||||
// PASSED --- 4) test server shutdown (on server)
|
||||
// PASSED --- a) click X on domain page
|
||||
// PASSED --- b) shutdown domain server
|
||||
// PASSED --- 6) test change domains
|
||||
// SAME AS PRODUCTION - 5) test server shutdown (on client) - models aren't deleted when model server goes away
|
||||
// SOLVED -- 9) EntityTreeRenderer::clearModelsCache() - Model instance cleanup handled in ~RenderableModelEntityItem
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -51,9 +51,8 @@ Octree::Octree(bool shouldReaverage) :
|
|||
}
|
||||
|
||||
Octree::~Octree() {
|
||||
// delete the children of the root element
|
||||
// this recursively deletes the tree
|
||||
delete _rootElement;
|
||||
// This will delete all children, don't create a new root in this case.
|
||||
eraseAllOctreeElements(false);
|
||||
}
|
||||
|
||||
// Recurses voxel tree calling the RecurseOctreeOperation function for each element.
|
||||
|
@ -488,9 +487,13 @@ void Octree::deleteOctalCodeFromTreeRecursion(OctreeElement* element, void* extr
|
|||
}
|
||||
}
|
||||
|
||||
void Octree::eraseAllOctreeElements() {
|
||||
void Octree::eraseAllOctreeElements(bool createNewRoot) {
|
||||
delete _rootElement; // this will recurse and delete all children
|
||||
_rootElement = createNewElement();
|
||||
if (createNewRoot) {
|
||||
_rootElement = createNewElement();
|
||||
} else {
|
||||
_rootElement = NULL;
|
||||
}
|
||||
_isDirty = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ class Octree : public QObject {
|
|||
Q_OBJECT
|
||||
public:
|
||||
Octree(bool shouldReaverage = false);
|
||||
~Octree();
|
||||
virtual ~Octree();
|
||||
|
||||
/// Your tree class must implement this to create the correct element type
|
||||
virtual OctreeElement* createNewElement(unsigned char * octalCode = NULL) = 0;
|
||||
|
@ -243,7 +243,7 @@ public:
|
|||
|
||||
OctreeElement* getRoot() { return _rootElement; }
|
||||
|
||||
virtual void eraseAllOctreeElements();
|
||||
virtual void eraseAllOctreeElements(bool createNewRoot = true);
|
||||
|
||||
void processRemoveOctreeElementsBitstream(const unsigned char* bitstream, int bufferSizeBytes);
|
||||
void readBitstreamToTree(const unsigned char* bitstream, unsigned long int bufferSizeBytes, ReadBitstreamToTreeParams& args);
|
||||
|
|
Loading…
Reference in a new issue