Improve ObjectsRemovalService to handle newly added objects removing

This commit is contained in:
Wojtek Figat
2023-10-11 17:41:35 +02:00
parent 6dd9f0f036
commit 8f3a5bd74a
2 changed files with 24 additions and 6 deletions

View File

@@ -5,7 +5,6 @@
#include "Collections/Dictionary.h" #include "Collections/Dictionary.h"
#include "Engine/Engine/Time.h" #include "Engine/Engine/Time.h"
#include "Engine/Engine/EngineService.h" #include "Engine/Engine/EngineService.h"
#include "Engine/Threading/Threading.h"
#include "Engine/Profiler/ProfilerCPU.h" #include "Engine/Profiler/ProfilerCPU.h"
#include "Engine/Scripting/ScriptingObject.h" #include "Engine/Scripting/ScriptingObject.h"
@@ -14,16 +13,15 @@ const Char* HertzSizesData[] = { TEXT("Hz"), TEXT("KHz"), TEXT("MHz"), TEXT("GHz
Span<const Char*> Utilities::Private::BytesSizes(BytesSizesData, ARRAY_COUNT(BytesSizesData)); Span<const Char*> Utilities::Private::BytesSizes(BytesSizesData, ARRAY_COUNT(BytesSizesData));
Span<const Char*> Utilities::Private::HertzSizes(HertzSizesData, ARRAY_COUNT(HertzSizesData)); Span<const Char*> Utilities::Private::HertzSizes(HertzSizesData, ARRAY_COUNT(HertzSizesData));
namespace ObjectsRemovalServiceImpl namespace
{ {
CriticalSection PoolLocker; CriticalSection PoolLocker;
DateTime LastUpdate; DateTime LastUpdate;
float LastUpdateGameTime; float LastUpdateGameTime;
Dictionary<Object*, float> Pool(8192); Dictionary<Object*, float> Pool(8192);
uint64 PoolCounter = 0;
} }
using namespace ObjectsRemovalServiceImpl;
class ObjectsRemoval : public EngineService class ObjectsRemoval : public EngineService
{ {
public: public:
@@ -64,6 +62,7 @@ void ObjectsRemovalService::Add(Object* obj, float timeToLive, bool useGameTime)
PoolLocker.Lock(); PoolLocker.Lock();
Pool[obj] = timeToLive; Pool[obj] = timeToLive;
PoolCounter++;
PoolLocker.Unlock(); PoolLocker.Unlock();
} }
@@ -72,6 +71,7 @@ void ObjectsRemovalService::Flush(float dt, float gameDelta)
PROFILE_CPU(); PROFILE_CPU();
PoolLocker.Lock(); PoolLocker.Lock();
PoolCounter = 0;
// Update timeouts and delete objects that timed out // Update timeouts and delete objects that timed out
for (auto i = Pool.Begin(); i.IsNotEnd(); ++i) for (auto i = Pool.Begin(); i.IsNotEnd(); ++i)
@@ -90,6 +90,24 @@ void ObjectsRemovalService::Flush(float dt, float gameDelta)
} }
} }
// If any object was added to the pool while removing objects (by this thread) then retry removing any nested objects (but without delta time)
if (PoolCounter != 0)
{
RETRY:
PoolCounter = 0;
for (auto i = Pool.Begin(); i.IsNotEnd(); ++i)
{
if (i->Value <= 0.0f)
{
Object* obj = i->Key;
Pool.Remove(i);
obj->OnDeleteObject();
}
}
if (PoolCounter != 0)
goto RETRY;
}
PoolLocker.Unlock(); PoolLocker.Unlock();
} }
@@ -121,7 +139,7 @@ void ObjectsRemoval::Dispose()
// Delete all remaining objects // Delete all remaining objects
{ {
ScopeLock lock(PoolLocker); PoolLocker.Lock();
for (auto i = Pool.Begin(); i.IsNotEnd(); ++i) for (auto i = Pool.Begin(); i.IsNotEnd(); ++i)
{ {
Object* obj = i->Key; Object* obj = i->Key;
@@ -129,6 +147,7 @@ void ObjectsRemoval::Dispose()
obj->OnDeleteObject(); obj->OnDeleteObject();
} }
Pool.Clear(); Pool.Clear();
PoolLocker.Unlock();
} }
} }

View File

@@ -190,7 +190,6 @@ DEFINE_INTERNAL_CALL(bool) ScriptingInternal_IsTypeFromGameScripts(MTypeObject*
DEFINE_INTERNAL_CALL(void) ScriptingInternal_FlushRemovedObjects() DEFINE_INTERNAL_CALL(void) ScriptingInternal_FlushRemovedObjects()
{ {
ASSERT(IsInMainThread());
ObjectsRemovalService::Flush(); ObjectsRemovalService::Flush();
} }