#pragma once #include #include #include #include #include struct Entity final { DECLARE_CLASS() EntityID ID = 0; const Class* derived_kind = nullptr; DerivedType derived = nullptr; Vector4 position = {}; bool is_dirty = false; }; // Can reinterpret cast to this to have the offset of Base and Kind for any entity struct EntityTemplate { DECLARE_ENTITY(); }; // template concept EntityConcept = requires(EntityType entity) { { EntityType::kind } -> std::convertible_to; requires std::same_as; }; inline constexpr EntityID make_entity_id(uint8 user_id, uint64 local_counter) { Assert(user_id != kInvalid_user_id); Assert((local_counter & kEntityID_user_id_mask) == kInvalid_entity_id); EntityID result = kInvalid_user_id; result = ((EntityID)user_id << kEntityID_user_id_shift) | (local_counter & kEntityID_user_id_mask); return result; } inline constexpr uint8 get_user_id(EntityID entity_id) { return (((uint8)entity_id & kEntityID_user_id_mask) << kEntityID_user_id_shift); } inline constexpr uint64 get_local_counter(EntityID entity_id) { return (uint64)entity_id & kEntityID_user_id_mask; } inline constexpr bool is_entity_id_valid(EntityID entity_id) { bool result = entity_id != kInvalid_entity_id; return result; } template requires EntityConcept [[nodiscard]] bool IsA(const Entity* entity) { Assert(entity != nullptr); return entity->derived_kind == EntityType::kind; } template requires EntityConcept [[nodiscard]] EntityType* MakeEntity(EntityManager& manager, float x, float y, float z) { Entity* base_ptr = allocate_entity(manager, EntityType::kind); Assert(base_ptr); base_ptr->ID = EntityManager::ID++; base_ptr->position.x = x; base_ptr->position.y = y; base_ptr->position.z = z; base_ptr->position.w = 1.0f; return (EntityType*)base_ptr->derived; } template requires EntityConcept [[nodiscard]] EntityType* DownCast(Entity* entity) { Assert(entity != nullptr); Assert(IsA(entity)); return static_cast(entity->derived); } void serialize(Archive& ar, NonNullPtr entity); JULIET_API uint8 get_local_user_id(); JULIET_API String format_entity_id(NonNullPtr arena, EntityID id); JULIET_API bool parse_entity_id(String str, EntityID& outId); [[nodiscard]] const Class* find_class_by_name(String name); [[nodiscard]] const Class* resolve_entity_class(uint8 kind, uint32 crc);