71 lines
2.3 KiB
C++
71 lines
2.3 KiB
C++
#pragma once
|
|
|
|
#include <concepts>
|
|
#include <Core/Common/CoreUtils.h>
|
|
#include <Core/Memory/Allocator.h>
|
|
#include <Engine/Class.h>
|
|
#include <Entity/EntityManager.h>
|
|
#include <type_traits>
|
|
|
|
// Add any new fields into the concept below
|
|
#define DECLARE_ENTITY(entity) \
|
|
Entity* Base; \
|
|
static const Juliet::Class* Kind;
|
|
|
|
// Will register the class globally at launch
|
|
#define DEFINE_ENTITY(entity) \
|
|
constexpr Juliet::Class entityKind##entity(#entity, sizeof(#entity) / sizeof(char)); \
|
|
const Juliet::Class* entity::Kind = &entityKind##entity;
|
|
|
|
namespace Game
|
|
{
|
|
using DerivedType = void*;
|
|
|
|
struct Entity final
|
|
{
|
|
EntityID ID;
|
|
const Juliet::Class* Kind;
|
|
DerivedType Derived;
|
|
float X, Y;
|
|
};
|
|
|
|
template <typename EntityType>
|
|
concept EntityConcept = requires(EntityType entity)
|
|
{
|
|
requires std::same_as<decltype(entity.Kind), const Juliet::Class*>;
|
|
requires std::same_as<decltype(entity.Base), Entity*>;
|
|
};
|
|
|
|
template <typename EntityType>
|
|
requires EntityConcept<EntityType>
|
|
bool IsA(const Entity* entity)
|
|
{
|
|
return entity->Kind == EntityType::Kind;
|
|
}
|
|
|
|
template <typename EntityType>
|
|
requires EntityConcept<EntityType>
|
|
EntityType* MakeEntity(EntityManager& manager, float x, float y)
|
|
{
|
|
EntityType* result = static_cast<EntityType*>(Juliet::Calloc(1, sizeof(EntityType)));
|
|
Entity* base = result->Base = static_cast<Entity*>(Juliet::Calloc(1, sizeof(Entity)));
|
|
base->X = x;
|
|
base->Y = y;
|
|
base->Derived = result;
|
|
base->Kind = EntityType::Kind;
|
|
|
|
RegisterEntity(manager, base);
|
|
|
|
return result;
|
|
}
|
|
|
|
template <typename EntityType>
|
|
requires EntityConcept<EntityType>
|
|
EntityType* DownCast(Entity* entity)
|
|
{
|
|
Assert(IsA<EntityType>(entity));
|
|
return static_cast<EntityType*>(entity->Derived);
|
|
}
|
|
|
|
} // namespace Game
|