Files
UnrealEngine/Engine/Source/Runtime/MovieScene/Public/EntitySystem/MovieSceneMaybeAtomic.h
2025-05-18 13:04:45 +08:00

118 lines
2.4 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "HAL/PlatformAtomics.h"
#include "Templates/UnrealTemplate.h"
namespace UE
{
namespace MovieScene
{
/**
* Enumeration that defines a threading model for this entity manager
*/
enum class EEntityThreadingModel : uint8
{
/** Specified when the data contained within an entity manager does not satisfy the requirements to justify using threaded evaluation */
NoThreading,
/** Specified when the data contained within an entity manager is large or complex enough to justify threaded evaluation */
TaskGraph,
};
/**
* A potentially atomic struct that will perform atomic operations if
* required on an underlying integer, depending on what
* `EEntityThreadingModel` was specified.
*/
struct FEntitySystemMaybeAtomicInt32 final
{
FEntitySystemMaybeAtomicInt32() = default;
FEntitySystemMaybeAtomicInt32(int32 Payload) : Payload(Payload) {}
int32 Load(EEntityThreadingModel ThreadingModel) const
{
if (EEntityThreadingModel::NoThreading == ThreadingModel)
{
return Payload;
}
else
{
return FPlatformAtomics::AtomicRead(&Payload);
}
}
int32 Add(EEntityThreadingModel ThreadingModel, const int32 Value)
{
if (EEntityThreadingModel::NoThreading == ThreadingModel)
{
const int32 Old = Payload;
Payload += Value;
return Old;
}
else
{
return FPlatformAtomics::InterlockedAdd(&Payload, Value);
}
}
int32 Sub(EEntityThreadingModel ThreadingModel, const int32 Value)
{
if (EEntityThreadingModel::NoThreading == ThreadingModel)
{
const int32 Old = Payload;
Payload -= Value;
return Old;
}
else
{
return FPlatformAtomics::InterlockedAdd(&Payload, -Value);
}
}
int32 Exchange(EEntityThreadingModel ThreadingModel, int32 Other)
{
if (EEntityThreadingModel::NoThreading == ThreadingModel)
{
Swap(Payload, Other);
return Other;
}
else
{
return FPlatformAtomics::InterlockedExchange(&Payload, Other);
}
}
int32 Increment(EEntityThreadingModel ThreadingModel)
{
if (EEntityThreadingModel::NoThreading == ThreadingModel)
{
return Payload++;
}
else
{
return FPlatformAtomics::InterlockedIncrement(&Payload);
}
}
int32 Decrement(EEntityThreadingModel ThreadingModel)
{
if (EEntityThreadingModel::NoThreading == ThreadingModel)
{
return Payload--;
}
else
{
return FPlatformAtomics::InterlockedDecrement(&Payload);
}
}
private:
int32 Payload = 0;
};
} // namespace MovieScene
} // namespace UE