#include #include #include #include void serialize_entity(Archive* ar, Entity* entity) { Assert(ar != NULL); Assert(entity != NULL); // Entity fields serialize_class(ar, ClassKind(Entity), entity); // Derived fields if (entity->derived_kind != NULL && entity->derived != NULL) { serialize_class(ar, entity->derived_kind, entity->derived); } } internal void init_Entity(void* payload) { Assert(payload != NULL); Entity* entity = (Entity*)payload; MemZeroStruct(entity); } internal void serialize_Entity(Archive* ar, uint16 version, void* payload) { (void)version; Assert(ar != NULL); Assert(payload != NULL); Entity* entity = (Entity*)payload; SERIALIZE_U64(ar, id, &entity->ID); SERIALIZE_VEC4(ar, position, &entity->position); } DEFINE_CLASS_VERSIONED(Entity, 1, NULL) String format_entity_id(Arena* arena, EntityID entity_id) { Assert(arena != NULL); // Format: // U = UserID // LC = Local Entity Counter // UU_LCLCLCLCLCLCLC uint8 user_id = get_user_id(entity_id); uint64 counter = get_local_counter(entity_id); const size_t kBufferSize = 18; char* buffer = ArenaPushArray(arena, char, kBufferSize); Assert(buffer != NULL); juliet_snprintf(buffer, kBufferSize, "%02X_%014llX", (unsigned int)user_id, (unsigned long long)counter); String result = { .Str = buffer, .Size = kBufferSize - 1 }; return result; } bool8 parse_entity_id(String str, EntityID* out_id) { Assert(out_id != NULL); bool8 result = false; *out_id = kInvalid_entity_id; if (!(str.Size != 17 || str.Str == NULL || str.Str[2] != '_')) { char user_hex[3] = { str.Str[0], str.Str[1], '\0' }; char* end = user_hex; uint8 user_id = (uint8)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)); const Class* class_ptr = kEntity_type_class_ptr[kind]; Assert(class_ptr != NULL); Assert(class_get_crc(class_ptr) == crc); return class_ptr; } const Class* find_class_by_name(String name) { Assert(IsValidString(name)); const Class* result = NULL; const uint32 name_crc = crc32_bytes(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 != NULL) { result = class_ptr; break; } } return result; }