108 lines
3.2 KiB
C++
108 lines
3.2 KiB
C++
#pragma once
|
|
|
|
#include <Core/Common/CoreUtils.h>
|
|
#include <Core/Common/EnumUtils.h>
|
|
#include <Core/Memory/Allocator.h>
|
|
#include <Core/Memory/MemoryArena.h>
|
|
#include <Engine/Class.h>
|
|
|
|
#define DECLARE_ENTITY() \
|
|
Entity* Base; \
|
|
static const Class* Kind;
|
|
|
|
// Will register the class globally at launch
|
|
#define DEFINE_ENTITY(entity) \
|
|
constexpr Class entityKind##entity = \
|
|
MakeClass(ConstString(#entity), (uint8)Entity_Type::entity, sizeof(entity), alignof(entity), nullptr); \
|
|
const Class* entity::Kind = &entityKind##entity;
|
|
|
|
#define DEFINE_ENTITY_SERIALIZED(entity, serialize_fct) \
|
|
constexpr Class entityKind##entity = \
|
|
MakeClass(ConstString(#entity), (uint8)Entity_Type::entity, sizeof(entity), alignof(entity), serialize_fct); \
|
|
const Class* entity::Kind = &entityKind##entity;
|
|
|
|
struct EntityManager;
|
|
using DerivedType = void*;
|
|
using EntityID = uint64_t;
|
|
|
|
// clang-format off
|
|
#define ENTITY_TYPE_LIST(X) X(Inert),
|
|
|
|
#define AS_ENUM(name) name
|
|
enum class Entity_Type : uint8
|
|
{
|
|
ENTITY_TYPE_LIST(AS_ENUM)
|
|
Count
|
|
};
|
|
#undef AS_ENUM
|
|
|
|
#define AS_STR(name) #name
|
|
inline const char* kEntity_type_names[] = {
|
|
ENTITY_TYPE_LIST(AS_STR)
|
|
"Count"
|
|
};
|
|
|
|
#define ENTITY(kind) ToUnderlying(Entity_Type::kind)
|
|
// clang-format on
|
|
|
|
struct Entity final
|
|
{
|
|
EntityID ID = 0;
|
|
const Class* Kind = nullptr;
|
|
DerivedType Derived = nullptr;
|
|
float X = 0.0f;
|
|
float Y = 0.0f;
|
|
float Z = 0.0f;
|
|
};
|
|
|
|
// Can reinterpret cast to this to have the offset of Base and Kind for any entity
|
|
struct entity_template
|
|
{
|
|
DECLARE_ENTITY();
|
|
};
|
|
|
|
struct Inert
|
|
{
|
|
DECLARE_ENTITY()
|
|
|
|
index_t MeshInstance = indexMax;
|
|
};
|
|
|
|
//
|
|
template <typename EntityType>
|
|
concept EntityConcept = requires(EntityType entity) {
|
|
{ EntityType::Kind } -> std::convertible_to<const Class*>;
|
|
requires std::same_as<decltype(entity.Base), Entity*>;
|
|
};
|
|
|
|
template <typename EntityType>
|
|
requires EntityConcept<EntityType>
|
|
[[nodiscard]] bool IsA(const Entity* entity)
|
|
{
|
|
Assert(entity != nullptr);
|
|
return entity->Kind == EntityType::Kind;
|
|
}
|
|
|
|
template <typename EntityType>
|
|
requires EntityConcept<EntityType>
|
|
[[nodiscard]] EntityType* MakeEntity(EntityManager& manager, float x, float y, float z)
|
|
{
|
|
EntityType result;
|
|
Entity base;
|
|
base.X = x;
|
|
base.Y = y;
|
|
base.Z = z;
|
|
base.Kind = EntityType::Kind;
|
|
|
|
return (EntityType*)RegisterEntity(manager, &base, &result);
|
|
}
|
|
|
|
template <typename EntityType>
|
|
requires EntityConcept<EntityType>
|
|
[[nodiscard]] EntityType* DownCast(Entity* entity)
|
|
{
|
|
Assert(entity != nullptr);
|
|
Assert(IsA<EntityType>(entity));
|
|
return static_cast<EntityType*>(entity->Derived);
|
|
}
|