Files
Project-Reboot-3.0/Project Reboot 3.0/UObjectArray.h
Milxnor 701d3ad0d0 a bit of stuff
toys, ammo in bottom right kinda, fix lootin speeds, being inaccurate, playlist looting kindof, or some things just not working.
2023-04-01 15:54:47 -04:00

167 lines
3.9 KiB
C++

#pragma once
#include "inc.h"
#include "Object.h"
#include "ObjectMacros.h"
struct FUObjectItem
{
UObject* Object;
int32 Flags;
int32 ClusterRootIndex;
int32 SerialNumber;
FORCEINLINE void SetFlag(EInternalObjectFlags FlagToSet)
{
// static_assert(sizeof(int32) == sizeof(Flags), "Flags must be 32-bit for atomics.");
int32 StartValue = int32(Flags);
if ((StartValue & int32(FlagToSet)) == int32(FlagToSet))
{
return;
}
int32 NewValue = StartValue | int32(FlagToSet);
}
FORCEINLINE void SetRootSet()
{
SetFlag(EInternalObjectFlags::RootSet);
}
};
class FFixedUObjectArray
{
FUObjectItem* Objects;
int32 MaxElements;
int32 NumElements;
public:
FORCEINLINE int32 Num() const { return NumElements; }
FORCEINLINE int32 Capacity() const { return MaxElements; }
FORCEINLINE bool IsValidIndex(int32 Index) const { return Index < Num() && Index >= 0; }
FORCEINLINE FUObjectItem* GetItemByIndex(int32 Index)
{
if (!IsValidIndex(Index)) return nullptr;
return &Objects[Index];
}
bool IsValid(UObject* Object)
{
int32 Index = Object->InternalIndex;
if (Index == -1)
{
// UE_LOG(LogUObjectArray, Warning, TEXT("Object is not in global object array"));
return false;
}
if (!IsValidIndex(Index))
{
// UE_LOG(LogUObjectArray, Warning, TEXT("Invalid object index %i"), Index);
return false;
}
FUObjectItem* Slot = GetItemByIndex(Index);
if (!Slot || Slot->Object == nullptr)
{
// UE_LOG(LogUObjectArray, Warning, TEXT("Empty slot"));
return false;
}
if (Slot->Object != Object)
{
// UE_LOG(LogUObjectArray, Warning, TEXT("Other object in slot"));
return false;
}
return true;
}
FORCEINLINE UObject* GetObjectByIndex(int32 Index)
{
if (auto Item = GetItemByIndex(Index))
return Item->Object;
return nullptr;
}
};
class FChunkedFixedUObjectArray
{
enum { NumElementsPerChunk = 64 * 1024, };
FUObjectItem** Objects;
FUObjectItem* PreAllocatedObjects;
int32 MaxElements;
int32 NumElements;
int32 MaxChunks;
int32 NumChunks;
public:
FORCEINLINE int32 Num() const { return NumElements; }
FORCEINLINE int32 Capacity() const { return MaxElements; }
FORCEINLINE bool IsValidIndex(int32 Index) const { return Index < Num() && Index >= 0; }
FORCEINLINE FUObjectItem* GetItemByIndex(int32 Index)
{
if (!IsValidIndex(Index)) return nullptr;
const int32 ChunkIndex = Index / NumElementsPerChunk;
const int32 WithinChunkIndex = Index % NumElementsPerChunk;
// checkf(ChunkIndex < NumChunks, TEXT("ChunkIndex (%d) < NumChunks (%d)"), ChunkIndex, NumChunks);
// checkf(Index < MaxElements, TEXT("Index (%d) < MaxElements (%d)"), Index, MaxElements);
FUObjectItem* Chunk = Objects[ChunkIndex];
if (!Chunk)
return nullptr;
return Chunk + WithinChunkIndex;
}
bool IsValid(UObject* Object)
{
int32 Index = Object->InternalIndex;
if (Index == -1)
{
// UE_LOG(LogUObjectArray, Warning, TEXT("Object is not in global object array"));
return false;
}
if (!IsValidIndex(Index))
{
// UE_LOG(LogUObjectArray, Warning, TEXT("Invalid object index %i"), Index);
return false;
}
FUObjectItem* Slot = GetItemByIndex(Index);
if (!Slot || Slot->Object == nullptr)
{
// UE_LOG(LogUObjectArray, Warning, TEXT("Empty slot"));
return false;
}
if (Slot->Object != Object)
{
// UE_LOG(LogUObjectArray, Warning, TEXT("Other object in slot"));
return false;
}
return true;
}
FORCEINLINE UObject* GetObjectByIndex(int32 Index)
{
if (auto Item = GetItemByIndex(Index))
return Item->Object;
return nullptr;
}
};
extern inline FChunkedFixedUObjectArray* ChunkedObjects = 0;
extern inline FFixedUObjectArray* UnchunkedObjects = 0;
FORCEINLINE UObject* GetObjectByIndex(int32 Index)
{
return ChunkedObjects ? ChunkedObjects->GetObjectByIndex(Index) : UnchunkedObjects->GetObjectByIndex(Index);
}
FORCEINLINE FUObjectItem* GetItemByIndex(int32 Index)
{
return ChunkedObjects ? ChunkedObjects->GetItemByIndex(Index) : UnchunkedObjects->GetItemByIndex(Index);
}