Browse Source

Fix an issue when event was being deleted from its own callback
Revert MeshHeap weak_ptr as it didn't fix the problem.
Automatically complete all queries when query manager gets shut down

Marko Pintera 11 năm trước cách đây
mục cha
commit
e7ed1249c1

+ 4 - 4
BansheeCore/Include/BsMeshHeap.h

@@ -210,11 +210,13 @@ namespace BansheeEngine
 		UINT32 mNumVertices; // Core thread
 		UINT32 mNumIndices; // Core thread
 
+		Vector<UINT8*> mCPUVertexData; // Core thread
+		UINT8* mCPUIndexData; // Core thread
+
 		std::shared_ptr<VertexData> mVertexData; // Core thread
 		IndexBufferPtr mIndexBuffer; // Core thread
 
-		Vector<UINT8*> mCPUVertexData; // Core thread
-		UINT8* mCPUIndexData; // Core thread
+		Map<UINT32, AllocatedData> mMeshAllocData; // Core thread
 
 		VertexDataDescPtr mVertexDesc; // Immutable
 		IndexBuffer::IndexType mIndexType; // Immutable
@@ -222,8 +224,6 @@ namespace BansheeEngine
 		Map<UINT32, TransientMeshPtr> mMeshes; // Sim thread
 		UINT32 mNextFreeId; // Sim thread
 
-		Map<UINT32, AllocatedData> mMeshAllocData; // Core thread
-
 		Vector<ChunkData> mVertChunks; // Core thread
 		Vector<ChunkData> mIdxChunks; // Core thread
 

+ 1 - 0
BansheeCore/Include/BsQueryManager.h

@@ -15,6 +15,7 @@ namespace BansheeEngine
 	{
 	public:
 		QueryManager();
+		~QueryManager();
 
 		/**
 		 * @brief	Creates a new event query that allows you to get notified

+ 1 - 1
BansheeCore/Include/BsTransientMesh.h

@@ -87,7 +87,7 @@ namespace BansheeEngine
 
 	protected:
 		bool mIsDestroyed;
-		std::weak_ptr<MeshHeap> mParentHeap;
+		MeshHeapPtr mParentHeap;
 		UINT32 mId;
 	};
 }

+ 23 - 0
BansheeCore/Source/BsQueryManager.cpp

@@ -10,6 +10,29 @@ namespace BansheeEngine
 
 	}
 
+	QueryManager::~QueryManager()
+	{
+		// Trigger all remaining queries, whether they completed or not
+
+		for (auto& query : mEventQueries)
+		{
+			if (query->isActive())
+				query->onTriggered();
+		}
+
+		for (auto& query : mTimerQueries)
+		{
+			if (query->isActive())
+				query->onTriggered(query->getTimeMs());
+		}
+
+		for (auto& query : mOcclusionQueries)
+		{
+			if (query->isActive())
+				query->onComplete(query->getNumSamples());
+		}
+	}
+
 	void QueryManager::_update()
 	{
 		for(auto& query : mEventQueries)

+ 7 - 34
BansheeCore/Source/BsTransientMesh.cpp

@@ -13,14 +13,10 @@ namespace BansheeEngine
 
 	TransientMesh::~TransientMesh()
 	{
-		if(!mIsDestroyed)
+		if (!mIsDestroyed)
 		{
 			TransientMeshPtr meshPtr = std::static_pointer_cast<TransientMesh>(getThisPtr());
-
-			MeshHeapPtr parentHeap = mParentHeap.lock();
-
-			if (parentHeap != nullptr)
-				parentHeap->dealloc(meshPtr);
+			mParentHeap->dealloc(meshPtr);
 		}
 	}
 
@@ -36,50 +32,27 @@ namespace BansheeEngine
 
 	std::shared_ptr<VertexData> TransientMesh::_getVertexData() const
 	{
-		MeshHeapPtr parentHeap = mParentHeap.lock();
-
-		if (parentHeap != nullptr)
-			return parentHeap->_getVertexData();
-		else
-			return nullptr;
+		return mParentHeap->_getVertexData();
 	}
 
 	IndexBufferPtr TransientMesh::_getIndexBuffer() const
 	{
-		MeshHeapPtr parentHeap = mParentHeap.lock();
-
-		if (parentHeap != nullptr)
-			return parentHeap->_getIndexBuffer();
-		else
-			return nullptr;
+		return mParentHeap->_getIndexBuffer();
 	}
 
 	UINT32 TransientMesh::_getVertexOffset() const
 	{
-		MeshHeapPtr parentHeap = mParentHeap.lock();
-
-		if (parentHeap != nullptr)
-			return parentHeap->getVertexOffset(mId);
-		else
-			return 0;
+		return mParentHeap->getVertexOffset(mId);
 	}
 
 	UINT32 TransientMesh::_getIndexOffset() const
 	{
-		MeshHeapPtr parentHeap = mParentHeap.lock();
-
-		if (parentHeap != nullptr)
-			return parentHeap->getIndexOffset(mId);
-		else
-			return 0;
+		return mParentHeap->getIndexOffset(mId);
 	}
 
 	void TransientMesh::_notifyUsedOnGPU()
 	{
-		MeshHeapPtr parentHeap = mParentHeap.lock();
-
-		if (parentHeap != nullptr)
-			parentHeap->notifyUsedOnGPU(mId);
+		mParentHeap->notifyUsedOnGPU(mId);
 	}
 
 	MeshProxyPtr TransientMesh::_createProxy(UINT32 subMeshIdx)

+ 6 - 0
BansheeEngine/Source/BsGUIManager.cpp

@@ -173,6 +173,12 @@ namespace BansheeEngine
 
 		if(renderData.widgets.size() == 0)
 		{
+			for (auto& mesh : renderData.cachedMeshes)
+			{
+				if (mesh != nullptr)
+					mMeshHeap->dealloc(mesh);
+			}
+
 			mCachedGUIData.erase(renderTarget);
 		}
 		else

+ 36 - 23
BansheeUtility/Include/BsEvent.h

@@ -65,9 +65,20 @@ namespace BansheeEngine
 			std::function<RetType(Args...)> func;
 		};
 
+		struct InternalData
+		{
+			InternalData()
+				:mHasDisconnectedCallbacks(false)
+			{ }
+
+			Vector<std::shared_ptr<ConnectionData>> mConnections;
+			bool mHasDisconnectedCallbacks;
+			BS_RECURSIVE_MUTEX(mMutex);
+		};
+
 	public:
 		TEvent()
-			:mHasDisconnectedCallbacks(false)
+			:mInternalData(bs_shared_ptr<InternalData>())
 		{ }
 
 		~TEvent()
@@ -85,8 +96,8 @@ namespace BansheeEngine
 			connData->isValid = true;
 
 			{
-				BS_LOCK_RECURSIVE_MUTEX(mMutex);
-				mConnections.push_back(connData);
+				BS_LOCK_RECURSIVE_MUTEX(mInternalData->mMutex);
+				mInternalData->mConnections.push_back(connData);
 			}
 			
 			return HEvent(connData, this, &TEvent::disconnectCallback);
@@ -97,29 +108,33 @@ namespace BansheeEngine
 		 */
 		void operator() (Args... args)
 		{
-			BS_LOCK_RECURSIVE_MUTEX(mMutex);
+			// Increase ref count to ensure this event data isn't destroyed if one of the callbacks
+			// deletes the event itself.
+			std::shared_ptr<InternalData> internalData = mInternalData;
+
+			BS_LOCK_RECURSIVE_MUTEX(internalData->mMutex);
 
 			// Here is the only place we remove connections, in order to allow disconnect() and clear() to be called
 			// recursively from the notify callbacks
-			if (mHasDisconnectedCallbacks)
+			if (internalData->mHasDisconnectedCallbacks)
 			{
-				for (UINT32 i = 0; i < mConnections.size(); i++)
+				for (UINT32 i = 0; i < internalData->mConnections.size(); i++)
 				{
-					if (!mConnections[i]->isValid)
+					if (!internalData->mConnections[i]->isValid)
 					{
-						mConnections.erase(mConnections.begin() + i);
+						internalData->mConnections.erase(internalData->mConnections.begin() + i);
 						i--;
 					}
 				}
 
-				mHasDisconnectedCallbacks = false;
+				internalData->mHasDisconnectedCallbacks = false;
 			}
 
 			// Do not use an iterator here, as new connections might be added during iteration from
 			// the notify callback
-			UINT32 numConnections = (UINT32)mConnections.size(); // Remember current num. connections as we don't want to notify new ones
+			UINT32 numConnections = (UINT32)internalData->mConnections.size(); // Remember current num. connections as we don't want to notify new ones
 			for (UINT32 i = 0; i < numConnections; i++)
-				mConnections[i]->func(args...);
+				internalData->mConnections[i]->func(args...);
 		}
 
 		/**
@@ -127,13 +142,13 @@ namespace BansheeEngine
 		 */
 		void clear()
 		{
-			BS_LOCK_RECURSIVE_MUTEX(mMutex);
+			BS_LOCK_RECURSIVE_MUTEX(mInternalData->mMutex);
 
-			for(auto& connection : mConnections)
+			for (auto& connection : mInternalData->mConnections)
 				connection->isValid = false;
 
-			if (mConnections.size() > 0)
-				mHasDisconnectedCallbacks = true;
+			if (mInternalData->mConnections.size() > 0)
+				mInternalData->mHasDisconnectedCallbacks = true;
 		}
 
 		/**
@@ -143,15 +158,13 @@ namespace BansheeEngine
 		 */
 		bool empty()
 		{
-			BS_LOCK_RECURSIVE_MUTEX(mMutex);
+			BS_LOCK_RECURSIVE_MUTEX(mInternalData->mMutex);
 
-			return mConnections.size() == 0;
+			return mInternalData->mConnections.size() == 0;
 		}
 
 	private:
-		Vector<std::shared_ptr<ConnectionData>> mConnections;
-		bool mHasDisconnectedCallbacks;
-		BS_RECURSIVE_MUTEX(mMutex);
+		std::shared_ptr<InternalData> mInternalData;
 
 		/**
 		 * @brief	Callback triggered by event handles when they want to disconnect from
@@ -169,14 +182,14 @@ namespace BansheeEngine
 		 */
 		void disconnect(const std::shared_ptr<BaseConnectionData>& connData)
 		{
-			BS_LOCK_RECURSIVE_MUTEX(mMutex);
+			BS_LOCK_RECURSIVE_MUTEX(mInternalData->mMutex);
 
-			for(auto& iter = mConnections.begin(); iter != mConnections.end(); ++iter)
+			for (auto& iter = mInternalData->mConnections.begin(); iter != mInternalData->mConnections.end(); ++iter)
 			{
 				if((*iter) == connData)
 				{
 					connData->isValid = false;
-					mHasDisconnectedCallbacks = true;
+					mInternalData->mHasDisconnectedCallbacks = true;
 					return;
 				}
 			}

+ 1 - 1
BansheeUtility/Include/BsMemStack.h

@@ -311,7 +311,7 @@ namespace BansheeEngine
 	public:
 		static inline void* allocate(size_t bytes)
 		{
-			stackAlloc((UINT32)bytes);
+			return stackAlloc((UINT32)bytes);
 		}
 
 		static inline void* allocateArray(size_t bytes, UINT32 count)