mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-19 14:03:20 +02:00
Remove DeleteHooks
This commit is contained in:
parent
cd2e610e17
commit
a364e85e1d
8 changed files with 18 additions and 124 deletions
|
@ -59,7 +59,6 @@ OctreeQueryNode::~OctreeQueryNode() {
|
|||
|
||||
void OctreeQueryNode::nodeKilled() {
|
||||
_isShuttingDown = true;
|
||||
elementBag.unhookNotifications(); // if our node is shutting down, then we no longer need octree element notifications
|
||||
if (_octreeSendThread) {
|
||||
// just tell our thread we want to shutdown, this is asynchronous, and fast, we don't need or want it to block
|
||||
// while the thread actually shuts down
|
||||
|
@ -69,7 +68,6 @@ void OctreeQueryNode::nodeKilled() {
|
|||
|
||||
void OctreeQueryNode::forceNodeShutdown() {
|
||||
_isShuttingDown = true;
|
||||
elementBag.unhookNotifications(); // if our node is shutting down, then we no longer need octree element notifications
|
||||
if (_octreeSendThread) {
|
||||
// we really need to force our thread to shutdown, this is synchronous, we will block while the thread actually
|
||||
// shuts down because we really need it to shutdown, and it's ok if we wait for it to complete
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include <atomic>
|
||||
|
||||
#include <GenericThread.h>
|
||||
#include <OctreeElementBag.h>
|
||||
|
||||
#include "OctreeQueryNode.h"
|
||||
|
||||
|
|
|
@ -44,12 +44,7 @@ void EntityTree::createRootElement() {
|
|||
}
|
||||
|
||||
OctreeElementPointer EntityTree::createNewElement(unsigned char* octalCode) {
|
||||
EntityTreeElementPointer newElement = EntityTreeElementPointer(new EntityTreeElement(octalCode),
|
||||
// see comment int EntityTreeElement::createNewElement
|
||||
[=](EntityTreeElement* dyingElement) {
|
||||
EntityTreeElementPointer tmpSharedPointer(dyingElement);
|
||||
dyingElement->notifyDeleteHooks();
|
||||
});
|
||||
auto newElement = EntityTreeElementPointer(new EntityTreeElement(octalCode));
|
||||
newElement->setTree(std::static_pointer_cast<EntityTree>(shared_from_this()));
|
||||
return std::static_pointer_cast<OctreeElement>(newElement);
|
||||
}
|
||||
|
|
|
@ -28,29 +28,8 @@ EntityTreeElement::~EntityTreeElement() {
|
|||
_octreeMemoryUsage -= sizeof(EntityTreeElement);
|
||||
}
|
||||
|
||||
// This will be called primarily on addChildAt(), which means we're adding a child of our
|
||||
// own type to our own tree. This means we should initialize that child with any tree and type
|
||||
// specific settings that our children must have.
|
||||
OctreeElementPointer EntityTreeElement::createNewElement(unsigned char* octalCode) {
|
||||
EntityTreeElementPointer newChild =
|
||||
EntityTreeElementPointer(new EntityTreeElement(octalCode),
|
||||
// This is a little bit horrible, but I haven't found a better way. The OctreeElement
|
||||
// destructor used to call notifyDeleteHooks(), which calls zero or more of
|
||||
// OctreeElementDeleteHook::elementDeleted
|
||||
// which (now) expects an OctreeElementPointer argument. The destructor doesn't have
|
||||
// access to the shared pointer (which has had its reference count drop to zero,
|
||||
// or the destructor wouldn't have been called). The destructor also can't
|
||||
// make a new shared pointer -- shared_from_this() is forbidden in a destructor, and
|
||||
// using OctreeElementPointer(this) also fails. So, I've installed a custom deleter:
|
||||
[=](EntityTreeElement* dyingElement) {
|
||||
// make a new shared pointer with a reference count of 1 (and no custom deleter)
|
||||
EntityTreeElementPointer tmpSharedPointer(dyingElement);
|
||||
// call notifyDeleteHooks which will use shared_from_this() to get this same
|
||||
// shared pointer, for use with the elementDeleted calls.
|
||||
dyingElement->notifyDeleteHooks();
|
||||
// And now tmpSharedPointer's reference count drops to zero and the
|
||||
// normal destructors are called.
|
||||
});
|
||||
auto newChild = EntityTreeElementPointer(new EntityTreeElement(octalCode));
|
||||
newChild->setTree(_myTree);
|
||||
return newChild;
|
||||
}
|
||||
|
|
|
@ -95,10 +95,6 @@ void OctreeElement::init(unsigned char * octalCode) {
|
|||
}
|
||||
|
||||
OctreeElement::~OctreeElement() {
|
||||
// We can't call notifyDeleteHooks from here:
|
||||
// notifyDeleteHooks();
|
||||
// see comment in EntityTreeElement::createNewElement.
|
||||
assert(_deleteHooksNotified);
|
||||
_voxelNodeCount--;
|
||||
if (isLeaf()) {
|
||||
_voxelNodeLeafCount--;
|
||||
|
@ -521,35 +517,6 @@ float OctreeElement::distanceToPoint(const glm::vec3& point) const {
|
|||
return distance;
|
||||
}
|
||||
|
||||
QReadWriteLock OctreeElement::_deleteHooksLock;
|
||||
std::vector<OctreeElementDeleteHook*> OctreeElement::_deleteHooks;
|
||||
|
||||
void OctreeElement::addDeleteHook(OctreeElementDeleteHook* hook) {
|
||||
_deleteHooksLock.lockForWrite();
|
||||
_deleteHooks.push_back(hook);
|
||||
_deleteHooksLock.unlock();
|
||||
}
|
||||
|
||||
void OctreeElement::removeDeleteHook(OctreeElementDeleteHook* hook) {
|
||||
_deleteHooksLock.lockForWrite();
|
||||
for (unsigned int i = 0; i < _deleteHooks.size(); i++) {
|
||||
if (_deleteHooks[i] == hook) {
|
||||
_deleteHooks.erase(_deleteHooks.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
_deleteHooksLock.unlock();
|
||||
}
|
||||
|
||||
void OctreeElement::notifyDeleteHooks() {
|
||||
_deleteHooksLock.lockForRead();
|
||||
for (unsigned int i = 0; i < _deleteHooks.size(); i++) {
|
||||
_deleteHooks[i]->elementDeleted(shared_from_this());
|
||||
}
|
||||
_deleteHooksLock.unlock();
|
||||
_deleteHooksNotified = true;
|
||||
}
|
||||
|
||||
bool OctreeElement::findSpherePenetration(const glm::vec3& center, float radius,
|
||||
glm::vec3& penetration, void** penetratedObject) const {
|
||||
// center and radius are in meters, so we have to scale the _cube into world-frame
|
||||
|
|
|
@ -33,20 +33,15 @@ class EncodeBitstreamParams;
|
|||
class Octree;
|
||||
class OctreeElement;
|
||||
class OctreeElementBag;
|
||||
class OctreeElementDeleteHook;
|
||||
class OctreePacketData;
|
||||
class ReadBitstreamToTreeParams;
|
||||
class Shape;
|
||||
class VoxelSystem;
|
||||
typedef std::shared_ptr<OctreeElement> OctreeElementPointer;
|
||||
typedef std::shared_ptr<const OctreeElement> ConstOctreeElementPointer;
|
||||
typedef std::shared_ptr<Octree> OctreePointer;
|
||||
|
||||
// Callers who want delete hook callbacks should implement this class
|
||||
class OctreeElementDeleteHook {
|
||||
public:
|
||||
virtual void elementDeleted(OctreeElementPointer element) = 0;
|
||||
};
|
||||
using OctreeElementPointer = std::shared_ptr<OctreeElement>;
|
||||
using OctreeElementWeakPointer = std::weak_ptr<OctreeElement>;
|
||||
using ConstOctreeElementPointer = std::shared_ptr<const OctreeElement>;
|
||||
using OctreePointer = std::shared_ptr<Octree>;
|
||||
|
||||
class OctreeElement: public std::enable_shared_from_this<OctreeElement> {
|
||||
|
||||
|
@ -174,9 +169,6 @@ public:
|
|||
bool matchesSourceUUID(const QUuid& sourceUUID) const;
|
||||
static uint16_t getSourceNodeUUIDKey(const QUuid& sourceUUID);
|
||||
|
||||
static void addDeleteHook(OctreeElementDeleteHook* hook);
|
||||
static void removeDeleteHook(OctreeElementDeleteHook* hook);
|
||||
|
||||
static void resetPopulationStatistics();
|
||||
static unsigned long getNodeCount() { return _voxelNodeCount; }
|
||||
static unsigned long getInternalNodeCount() { return _voxelNodeCount - _voxelNodeLeafCount; }
|
||||
|
@ -234,7 +226,6 @@ protected:
|
|||
void setChildAtIndex(int childIndex, OctreeElementPointer child);
|
||||
|
||||
void calculateAACube();
|
||||
void notifyDeleteHooks();
|
||||
|
||||
AACube _cube; /// Client and server, axis aligned box for bounds of this voxel, 48 bytes
|
||||
|
||||
|
@ -276,11 +267,6 @@ protected:
|
|||
_unknownBufferIndex : 1,
|
||||
_childrenExternal : 1; /// Client only, is this voxel's VBO buffer the unknown buffer index, 1 bit
|
||||
|
||||
bool _deleteHooksNotified = false;
|
||||
|
||||
static QReadWriteLock _deleteHooksLock;
|
||||
static std::vector<OctreeElementDeleteHook*> _deleteHooks;
|
||||
|
||||
static AtomicUIntStat _voxelNodeCount;
|
||||
static AtomicUIntStat _voxelNodeLeafCount;
|
||||
|
||||
|
|
|
@ -12,54 +12,30 @@
|
|||
#include "OctreeElementBag.h"
|
||||
#include <OctalCode.h>
|
||||
|
||||
OctreeElementBag::OctreeElementBag() :
|
||||
_bagElements()
|
||||
{
|
||||
OctreeElement::addDeleteHook(this);
|
||||
_hooked = true;
|
||||
}
|
||||
|
||||
OctreeElementBag::~OctreeElementBag() {
|
||||
unhookNotifications();
|
||||
deleteAll();
|
||||
}
|
||||
|
||||
void OctreeElementBag::unhookNotifications() {
|
||||
if (_hooked) {
|
||||
OctreeElement::removeDeleteHook(this);
|
||||
_hooked = false;
|
||||
}
|
||||
}
|
||||
|
||||
void OctreeElementBag::elementDeleted(OctreeElementPointer element) {
|
||||
remove(element); // note: remove can safely handle nodes that aren't in it, so we don't need to check contains()
|
||||
}
|
||||
|
||||
|
||||
void OctreeElementBag::deleteAll() {
|
||||
_bagElements.clear();
|
||||
}
|
||||
|
||||
|
||||
void OctreeElementBag::insert(OctreeElementPointer element) {
|
||||
_bagElements.insert(element);
|
||||
_bagElements.insert(element.get(), element);
|
||||
}
|
||||
|
||||
OctreeElementPointer OctreeElementBag::extract() {
|
||||
OctreeElementPointer result = NULL;
|
||||
OctreeElementPointer result;
|
||||
|
||||
if (_bagElements.size() > 0) {
|
||||
QSet<OctreeElementPointer>::iterator front = _bagElements.begin();
|
||||
result = *front;
|
||||
_bagElements.erase(front);
|
||||
// Find the first element still alive
|
||||
while (!_bagElements.empty() && !result) {
|
||||
auto it = _bagElements.begin();
|
||||
result = it->lock();
|
||||
_bagElements.erase(it);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool OctreeElementBag::contains(OctreeElementPointer element) {
|
||||
return _bagElements.contains(element);
|
||||
return _bagElements.contains(element.get());
|
||||
}
|
||||
|
||||
void OctreeElementBag::remove(OctreeElementPointer element) {
|
||||
_bagElements.remove(element);
|
||||
_bagElements.remove(element.get());
|
||||
}
|
||||
|
|
|
@ -17,12 +17,10 @@
|
|||
#define hifi_OctreeElementBag_h
|
||||
|
||||
#include "OctreeElement.h"
|
||||
#include <sharedUtil.h>
|
||||
|
||||
class OctreeElementBag : public OctreeElementDeleteHook {
|
||||
|
||||
class OctreeElementBag {
|
||||
public:
|
||||
OctreeElementBag();
|
||||
~OctreeElementBag();
|
||||
|
||||
void insert(OctreeElementPointer element); // put a element into the bag
|
||||
OctreeElementPointer extract(); // pull a element out of the bag (could come in any order)
|
||||
|
@ -32,13 +30,9 @@ public:
|
|||
int count() const { return _bagElements.size(); }
|
||||
|
||||
void deleteAll();
|
||||
virtual void elementDeleted(OctreeElementPointer element);
|
||||
|
||||
void unhookNotifications();
|
||||
|
||||
private:
|
||||
QSet<OctreeElementPointer> _bagElements;
|
||||
bool _hooked;
|
||||
QHash<OctreeElement*, OctreeElementWeakPointer> _bagElements;
|
||||
};
|
||||
|
||||
typedef QMap<const OctreeElement*, void*> OctreeElementExtraEncodeData;
|
||||
|
|
Loading…
Reference in a new issue