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 "Engine/Engine/Time.h"
#include "Engine/Engine/EngineService.h"
#include "Engine/Threading/Threading.h"
#include "Engine/Profiler/ProfilerCPU.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::HertzSizes(HertzSizesData, ARRAY_COUNT(HertzSizesData));
namespace ObjectsRemovalServiceImpl
namespace
{
CriticalSection PoolLocker;
DateTime LastUpdate;
float LastUpdateGameTime;
Dictionary<Object*, float> Pool(8192);
uint64 PoolCounter = 0;
}
using namespace ObjectsRemovalServiceImpl;
class ObjectsRemoval : public EngineService
{
public:
@@ -64,6 +62,7 @@ void ObjectsRemovalService::Add(Object* obj, float timeToLive, bool useGameTime)
PoolLocker.Lock();
Pool[obj] = timeToLive;
PoolCounter++;
PoolLocker.Unlock();
}
@@ -72,6 +71,7 @@ void ObjectsRemovalService::Flush(float dt, float gameDelta)
PROFILE_CPU();
PoolLocker.Lock();
PoolCounter = 0;
// Update timeouts and delete objects that timed out
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();
}
@@ -121,7 +139,7 @@ void ObjectsRemoval::Dispose()
// Delete all remaining objects
{
ScopeLock lock(PoolLocker);
PoolLocker.Lock();
for (auto i = Pool.Begin(); i.IsNotEnd(); ++i)
{
Object* obj = i->Key;
@@ -129,6 +147,7 @@ void ObjectsRemoval::Dispose()
obj->OnDeleteObject();
}
Pool.Clear();
PoolLocker.Unlock();
}
}

View File

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