93 lines
2.5 KiB
C++
93 lines
2.5 KiB
C++
#include <Entity/Entity.h>
|
|
|
|
#include <Core/Common/serialization.h>
|
|
|
|
void serialize(Archive& ar, NonNullPtr<Entity> entity)
|
|
{
|
|
// Entity fields
|
|
serialize(ar, Entity::kind, entity.Get());
|
|
|
|
// Derived fields
|
|
if (entity->derived_kind != nullptr && entity->derived != nullptr)
|
|
{
|
|
serialize(ar, entity->derived_kind, entity->derived);
|
|
}
|
|
}
|
|
|
|
DEFINE_CLASS_VERSIONED(Entity, 1, nullptr)
|
|
internal void serialize(Archive& ar, uint16 /*version*/, Entity& entity)
|
|
{
|
|
SERIALIZE(ar, id, entity.ID);
|
|
SERIALIZE(ar, position, entity.position);
|
|
}
|
|
|
|
String format_entity_id(NonNullPtr<Arena> arena, EntityID entity_id)
|
|
{
|
|
// Format:
|
|
// U = UserID
|
|
// LC = Local Entity Counter
|
|
// UU_LCLCLCLCLCLCLC
|
|
uint8 user_id = get_user_id(entity_id);
|
|
uint64 counter = get_local_counter(entity_id);
|
|
|
|
constexpr size_t kBufferSize = 18;
|
|
char* buffer = ArenaPushArray<char>(arena, kBufferSize);
|
|
Assert(buffer);
|
|
|
|
juliet_snprintf(buffer, kBufferSize, "%02X_%014llX", (unsigned int)user_id, counter);
|
|
return { buffer, kBufferSize - 1 };
|
|
}
|
|
|
|
bool parse_entity_id(String str, EntityID& out_id)
|
|
{
|
|
bool result = false;
|
|
out_id = kInvalid_entity_id;
|
|
|
|
if (!(str.Size != 17 || str.Str == nullptr || str.Str[2] != '_'))
|
|
{
|
|
char user_hex[3]{ str.Str[0], str.Str[1], '\0' };
|
|
char* end = user_hex;
|
|
uint8 user_id = strtoul(user_hex, &end, 16);
|
|
if (end != user_hex && user_id != kInvalid_user_id)
|
|
{
|
|
char* counter_hex = str.Str + 3;
|
|
end = counter_hex;
|
|
uint64 counter = strtoull(counter_hex, &end, 16);
|
|
if (end != counter_hex && counter < kEntityID_user_id_mask)
|
|
{
|
|
out_id = make_entity_id(user_id, counter);
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
const Class* resolve_entity_class(uint8 kind, uint32 crc)
|
|
{
|
|
Assert(kind <= ENTITY(Count));
|
|
|
|
NonNullPtr<const Class> class_ptr = kEntity_type_class_ptr[kind];
|
|
Assert(class_ptr->CRC == crc);
|
|
|
|
return class_ptr.Get();
|
|
}
|
|
|
|
const Class* find_class_by_name(String name)
|
|
{
|
|
Assert(IsValid(name));
|
|
|
|
const Class* result = nullptr;
|
|
const uint32 name_crc = crc32(name.Str, name.Size);
|
|
for (uint8 kind = 0; kind < ENTITY(Count); ++kind)
|
|
{
|
|
const Class* class_ptr = resolve_entity_class(kind, name_crc);
|
|
if (class_ptr != nullptr)
|
|
{
|
|
result = class_ptr;
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
}
|