Skip to content

Commit

Permalink
Started improving handling of mono types for serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
ChunkTreasure1 committed Sep 20, 2023
1 parent 05ef02a commit 7dd3a68
Show file tree
Hide file tree
Showing 12 changed files with 345 additions and 338 deletions.
57 changes: 56 additions & 1 deletion Volt/Volt/src/Volt/Asset/Importers/SceneImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1678,13 +1678,22 @@ namespace Volt
}

const IComponentTypeDesc* componentDesc = reinterpret_cast<const IComponentTypeDesc*>(Volt::ComponentRegistry::GetTypeDescFromName(storage.type().name()));
if (!componentDesc)
{
continue;
}

const uint8_t* componentPtr = reinterpret_cast<const uint8_t*>(storage.get(id));

SerializeClass(componentPtr, 0, componentDesc, streamWriter, false);
}
}
streamWriter.EndSequence();

if (registry.any_of<MonoScriptComponent>(id))
{
SerializeMono(id, scene, streamWriter);
}

streamWriter.EndMap();
streamWriter.EndMap();
}
Expand All @@ -1701,6 +1710,11 @@ namespace Volt

for (const auto& member : compDesc->GetMembers())
{
if ((member.flags & ComponentMemberFlag::NoSerialize) != ComponentMemberFlag::None)
{
continue;
}

streamWriter.BeginMap();
streamWriter.SetKey("name", member.name);

Expand Down Expand Up @@ -1794,6 +1808,47 @@ namespace Volt
streamWriter.EndSequence();
}

void SceneImporter::SerializeMono(entt::entity id, const Ref<Scene>& scene, YAMLStreamWriter& streamWriter) const
{
const auto& scriptFieldCache = scene->GetScriptFieldCache();

streamWriter.BeginSequence("MonoScripts");
{
MonoScriptComponent& monoScriptComp = scene->GetRegistry().get<MonoScriptComponent>(id);
for (size_t i = 0; i < monoScriptComp.scriptIds.size(); ++i)
{
const auto& scriptId = monoScriptComp.scriptIds.at(i);
const auto& scriptName = monoScriptComp.scriptNames.at(i);

streamWriter.BeginMap();
streamWriter.BeginMapNamned("ScriptEntry");

streamWriter.SetKey("name", scriptName);
streamWriter.SetKey("id", scriptId);

if (scriptFieldCache.GetCache().contains(scriptId))
{
streamWriter.BeginSequence("members");
const auto& fieldMap = scriptFieldCache.GetCache().at(scriptId);
for (const auto& [name, value] : fieldMap)
{
streamWriter.BeginMap();

// #TODO_Ivar: Finish implementation

streamWriter.EndMap();
}

streamWriter.EndSequence();
}

streamWriter.EndMap();
streamWriter.EndMap();
}
}
streamWriter.EndSequence();
}

void SceneImporter::DeserializeEntity(const Ref<Scene>& scene, const AssetMetadata& metadata, YAMLStreamReader& streamReader) const
{
streamReader.EnterScope("Entity");
Expand Down
1 change: 1 addition & 0 deletions Volt/Volt/src/Volt/Asset/Importers/SceneImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace Volt
void SerializeEntity(entt::entity id, const Ref<Scene>& scene, YAMLStreamWriter& streamWriter) const;
void SerializeClass(const uint8_t* data, const size_t offset, const IComponentTypeDesc* compDesc, YAMLStreamWriter& streamWriter, bool isSubComponent) const;
void SerializeArray(const uint8_t* data, const size_t offset, const IArrayTypeDesc* arrayDesc, YAMLStreamWriter& streamWriter) const;
void SerializeMono(entt::entity id, const Ref<Scene>& scene, YAMLStreamWriter& streamWriter) const;

void DeserializeEntity(const Ref<Scene>& scene, const AssetMetadata& metadata, YAMLStreamReader& streamReader) const;
void DeserializeClass(uint8_t* data, const size_t offset, const IComponentTypeDesc* compDesc, YAMLStreamReader& streamReader) const;
Expand Down
81 changes: 81 additions & 0 deletions Volt/Volt/src/Volt/Scene/Entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,4 +454,85 @@ namespace Volt
{
return {};
}

void Entity::Copy(Entity srcEntity, Entity dstEntity)
{
// #TODO_Ivar: Implement MonoComponent copying

auto srcScene = srcEntity.GetScene();
auto& srcRegistry = srcScene->GetRegistry();

auto dstScene = dstEntity.GetScene();
auto& dstRegistry = dstScene->GetRegistry();

for (auto&& curr : srcRegistry.storage())
{
auto& storage = curr.second;

if (!storage.contains(srcEntity.GetID()))
{
continue;
}

const IComponentTypeDesc* componentDesc = reinterpret_cast<const IComponentTypeDesc*>(Volt::ComponentRegistry::GetTypeDescFromName(storage.type().name()));
if (!componentDesc)
{
continue;
}

if (componentDesc->GetValueType() != ValueType::Component)
{
continue;
}

ComponentRegistry::Helpers::AddComponentWithGUID(componentDesc->GetGUID(), dstRegistry, dstEntity.GetID());
void* voidCompPtr = Volt::ComponentRegistry::Helpers::GetComponentWithGUID(componentDesc->GetGUID(), dstRegistry, dstEntity.GetID());
uint8_t* componentData = reinterpret_cast<uint8_t*>(voidCompPtr);

CopyComponent(reinterpret_cast<const uint8_t*>(storage.get(srcEntity.GetID())), componentData, 0, componentDesc);
}

// Clear the relationship component, as this is a standalone entity
{
RelationshipComponent& relComp = dstEntity.GetComponent<RelationshipComponent>();
relComp.children.clear();
relComp.parent = entt::null;
}
}

void Entity::CopyComponent(const uint8_t* srcData, uint8_t* dstData, const size_t offset, const IComponentTypeDesc* compDesc)
{
for (const auto& member : compDesc->GetMembers())
{
if ((member.flags & ComponentMemberFlag::NoCopy) != ComponentMemberFlag::None)
{
continue;
}

if (member.typeDesc != nullptr)
{
switch (member.typeDesc->GetValueType())
{
case ValueType::Component:
{
const IComponentTypeDesc* memberCompDesc = reinterpret_cast<const IComponentTypeDesc*>(member.typeDesc);
CopyComponent(srcData, dstData, offset + member.offset, memberCompDesc);
break;
}

case ValueType::Enum:
*reinterpret_cast<int32_t*>(&dstData[offset + member.offset]) = *(reinterpret_cast<const int32_t*>(&srcData[offset + member.offset]));
break;

case ValueType::Array:
member.copyFunction(&dstData[offset + member.offset], &srcData[offset + member.offset]);
break;
}
}
else
{
member.copyFunction(&dstData[offset + member.offset], &srcData[offset + member.offset]);
}
}
}
}
7 changes: 7 additions & 0 deletions Volt/Volt/src/Volt/Scene/Entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

namespace Volt
{
class IComponentTypeDesc;

template<class T>
concept EntityId = std::is_same<T, uint32_t>::value || std::is_same<T, entt::entity>::value;

Expand Down Expand Up @@ -95,7 +97,12 @@ namespace Volt

static Entity Null();

// Copies a single entity
static void Copy(Entity srcEntity, Entity dstEntity);

private:
static void CopyComponent(const uint8_t* srcData, uint8_t* dstData, const size_t offset, const IComponentTypeDesc* compDesc);

Weak<Scene> m_scene;
entt::entity m_id = entt::null;
};
Expand Down
16 changes: 13 additions & 3 deletions Volt/Volt/src/Volt/Scene/Reflection/ComponentReflection.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ namespace Volt
{
None = 0,
Color3 = BIT(0),
Color4 = BIT(1)
Color4 = BIT(1),

NoCopy = BIT(2),
NoSerialize = BIT(3)
};

VT_SETUP_ENUM_CLASS_OPERATORS(ComponentMemberFlag);
Expand All @@ -116,6 +119,8 @@ namespace Volt
const ICommonTypeDesc* typeDesc = nullptr;
std::type_index typeIndex = typeid(void);
Scope<IDefaultValueType> defaultValue;

std::function<void(void* lhs, const void* rhs)> copyFunction;
};

struct EnumConstant
Expand Down Expand Up @@ -304,13 +309,18 @@ namespace Volt
return *nullMember;
}

auto copyFunction = [](void* lhs, const void* rhs)
{
*reinterpret_cast<Type*>(lhs) = *reinterpret_cast<const Type*>(rhs);
};

if constexpr (IsArrayType<Type>() || IsReflectedType<Type>())
{
m_members.emplace_back(offset, name, label, description, assetType, flags, GetTypeDesc<Type>(), typeid(Type), CreateScope<DefaultValueType<DefaultValueT>>(defaultValue));
m_members.emplace_back(offset, name, label, description, assetType, flags, GetTypeDesc<Type>(), typeid(Type), CreateScope<DefaultValueType<DefaultValueT>>(defaultValue), copyFunction);
}
else
{
m_members.emplace_back(offset, name, label, description, assetType, flags, nullptr, typeid(Type), CreateScope<DefaultValueType<DefaultValueT>>(defaultValue));
m_members.emplace_back(offset, name, label, description, assetType, flags, nullptr, typeid(Type), CreateScope<DefaultValueType<DefaultValueT>>(defaultValue), copyFunction);
}


Expand Down
12 changes: 6 additions & 6 deletions Volt/Volt/src/Volt/Scripting/Mono/MonoEnum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
namespace Volt
{
MonoEnum::MonoEnum(MonoImage* assemblyImage, const std::string& classNamespace, const std::string& enumName)
: myNamespace(classNamespace), myEnumName(enumName)
: m_namespace(classNamespace), m_enumName(enumName)
{
myMonoClass = mono_class_from_name(assemblyImage, classNamespace.c_str(), enumName.c_str());
m_monoClass = mono_class_from_name(assemblyImage, classNamespace.c_str(), enumName.c_str());

LoadEnumValues();
}
Expand All @@ -21,8 +21,8 @@ namespace Volt
void* iterator = nullptr;
uint32_t count = 0;

MonoObject* tempObject = mono_object_new(MonoScriptEngine::GetAppDomain(), myMonoClass);
while (MonoClassField* field = mono_class_get_fields(myMonoClass, &iterator))
MonoObject* tempObject = mono_object_new(MonoScriptEngine::GetAppDomain(), m_monoClass);
while (MonoClassField* field = mono_class_get_fields(m_monoClass, &iterator))
{
if (count == 0)
{
Expand All @@ -38,13 +38,13 @@ namespace Volt
uint32_t value;
mono_field_get_value(tempObject, field, &value);

myEnumValues.emplace_back(fieldName, value);
m_enumValues.emplace_back(fieldName, value);
continue;
}

MonoObject* valueObject = mono_field_get_value_object(MonoScriptEngine::GetAppDomain(), field, tempObject);
uint32_t value = *(uint32_t*)mono_object_unbox(valueObject);
myEnumValues.emplace_back(fieldName, value);
m_enumValues.emplace_back(fieldName, value);
}
}
}
10 changes: 5 additions & 5 deletions Volt/Volt/src/Volt/Scripting/Mono/MonoEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ namespace Volt
MonoEnum() = default;
MonoEnum(MonoImage* assemblyImage, const std::string& classNamespace, const std::string& enumName);

inline const std::vector<std::pair<std::string, uint32_t>>& GetValues() const { return myEnumValues; }
inline const std::vector<std::pair<std::string, uint32_t>>& GetValues() const { return m_enumValues; }

private:
void LoadEnumValues();

std::vector<std::pair<std::string, uint32_t>> myEnumValues;
std::vector<std::pair<std::string, uint32_t>> m_enumValues;

std::string myNamespace;
std::string myEnumName;
std::string m_namespace;
std::string m_enumName;

MonoClass* myMonoClass = nullptr;
MonoClass* m_monoClass = nullptr;
};
}
Loading

0 comments on commit 7dd3a68

Please sign in to comment.