List Serialization and Editor for Scripts #193
|
@ -41,7 +41,12 @@ namespace SHADE
|
||||||
|
|
||||||
bool ReflectionUtilities::FieldIsList(System::Reflection::FieldInfo^ fieldInfo)
|
bool ReflectionUtilities::FieldIsList(System::Reflection::FieldInfo^ fieldInfo)
|
||||||
{
|
{
|
||||||
return fieldInfo->FieldType->IsGenericType
|
return IsList(fieldInfo->FieldType);
|
||||||
&& fieldInfo->FieldType->GetGenericTypeDefinition() == System::Collections::Generic::List<int>::typeid->GetGenericTypeDefinition();
|
}
|
||||||
|
|
||||||
|
bool ReflectionUtilities::IsList(System::Type^ type)
|
||||||
|
{
|
||||||
|
return type->IsGenericType
|
||||||
|
&& type->GetGenericTypeDefinition() == System::Collections::Generic::List<int>::typeid->GetGenericTypeDefinition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,5 +45,11 @@ namespace SHADE
|
||||||
/// <param name="fieldInfo">The field to check.</param>
|
/// <param name="fieldInfo">The field to check.</param>
|
||||||
/// <returns>True if fieldInfo is describing a generic List.</returns>
|
/// <returns>True if fieldInfo is describing a generic List.</returns>
|
||||||
static bool FieldIsList(System::Reflection::FieldInfo^ fieldInfo);
|
static bool FieldIsList(System::Reflection::FieldInfo^ fieldInfo);
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the specified type is a generic List type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The type to check.</param>
|
||||||
|
/// <returns>True if type is a generic List.</returns>
|
||||||
|
static bool IsList(System::Type^ type);
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -173,79 +173,88 @@ namespace SHADE
|
||||||
varInsertYamlInternal<GameObject >(object, fieldNode);
|
varInsertYamlInternal<GameObject >(object, fieldNode);
|
||||||
return INSERTED;
|
return INSERTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialisationUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Deserialization Helper Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
bool SerialisationUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
|
||||||
{
|
{
|
||||||
if (fieldAssignYaml<System::Int16> (fieldInfo, object, node) ||
|
const bool ASSIGNED =
|
||||||
fieldAssignYaml<System::Int32> (fieldInfo, object, node) ||
|
fieldAssignYaml<System::Int16> (fieldInfo, object, node) ||
|
||||||
fieldAssignYaml<System::Int64> (fieldInfo, object, node) ||
|
fieldAssignYaml<System::Int32> (fieldInfo, object, node) ||
|
||||||
fieldAssignYaml<System::UInt16>(fieldInfo, object, node) ||
|
fieldAssignYaml<System::Int64> (fieldInfo, object, node) ||
|
||||||
fieldAssignYaml<System::UInt32>(fieldInfo, object, node) ||
|
fieldAssignYaml<System::UInt16>(fieldInfo, object, node) ||
|
||||||
fieldAssignYaml<System::UInt64>(fieldInfo, object, node) ||
|
fieldAssignYaml<System::UInt32>(fieldInfo, object, node) ||
|
||||||
fieldAssignYaml<System::Byte> (fieldInfo, object, node) ||
|
fieldAssignYaml<System::UInt64>(fieldInfo, object, node) ||
|
||||||
fieldAssignYaml<bool> (fieldInfo, object, node) ||
|
fieldAssignYaml<System::Byte> (fieldInfo, object, node) ||
|
||||||
fieldAssignYaml<float> (fieldInfo, object, node) ||
|
fieldAssignYaml<bool> (fieldInfo, object, node) ||
|
||||||
fieldAssignYaml<double> (fieldInfo, object, node))
|
fieldAssignYaml<float> (fieldInfo, object, node) ||
|
||||||
|
fieldAssignYaml<double> (fieldInfo, object, node) ||
|
||||||
|
fieldAssignYaml<System::Enum> (fieldInfo, object, node) ||
|
||||||
|
fieldAssignYaml<System::String>(fieldInfo, object, node) ||
|
||||||
|
fieldAssignYaml<Vector2> (fieldInfo, object, node) ||
|
||||||
|
fieldAssignYaml<Vector3> (fieldInfo, object, node) ||
|
||||||
|
fieldAssignYaml<GameObject> (fieldInfo, object, node);
|
||||||
|
if (!ASSIGNED)
|
||||||
{
|
{
|
||||||
return;
|
if (ReflectionUtilities::FieldIsList(fieldInfo))
|
||||||
}
|
|
||||||
else if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid))
|
|
||||||
{
|
|
||||||
fieldInfo->SetValue(object, node.as<int>());
|
|
||||||
}
|
|
||||||
else if (fieldInfo->FieldType == System::String::typeid)
|
|
||||||
{
|
|
||||||
fieldInfo->SetValue(object, Convert::ToCLI(node.as<std::string>()));
|
|
||||||
}
|
|
||||||
else if (fieldInfo->FieldType == Vector2::typeid)
|
|
||||||
{
|
|
||||||
if (node.IsSequence() && node.size() == 2)
|
|
||||||
{
|
{
|
||||||
Vector2 vec;
|
System::Type^ elemType = fieldInfo->FieldType->GenericTypeArguments[0];
|
||||||
vec.x = node[0].as<float>();
|
System::Collections::IList^ iList = safe_cast<System::Collections::IList^>(fieldInfo->GetValue(object));
|
||||||
vec.y = node[1].as<float>();
|
if (node.IsSequence())
|
||||||
fieldInfo->SetValue(object, vec);
|
{
|
||||||
}
|
// Get list size
|
||||||
else
|
const int LIST_SIZE = static_cast<int>(node.size());
|
||||||
{
|
if (LIST_SIZE > 0)
|
||||||
Debug::LogWarning
|
{
|
||||||
(
|
// Get list type
|
||||||
System::String::Format("[SerialisationUtilities] Invalid YAML Node provided for deserialization of a Vector2 \"{0}\" field in \"{1}\" script.",
|
array<System::Type^>^ typeList = gcnew array<System::Type^>{ elemType };
|
||||||
fieldInfo->Name, object->GetType()->FullName)
|
System::Type^ listType = System::Collections::Generic::List<int>::typeid->GetGenericTypeDefinition()->MakeGenericType(typeList);
|
||||||
);
|
// Create a list of the specified type
|
||||||
|
array<int>^ params = gcnew array<int>{ node.size() };
|
||||||
|
object = System::Activator::CreateInstance(listType, params);
|
||||||
|
System::Collections::IList^ list = safe_cast<System::Collections::IList^>(object);
|
||||||
|
|
||||||
|
// Populate the list
|
||||||
|
for (int i = 0; i < LIST_SIZE; ++i)
|
||||||
|
{
|
||||||
|
// Create the object
|
||||||
|
System::Object^ obj = System::Activator::CreateInstance(elemType);
|
||||||
|
|
||||||
|
// Set it's value
|
||||||
|
if (varAssignYaml(obj, node[i]))
|
||||||
|
{
|
||||||
|
list->Add(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fieldInfo->FieldType == Vector3::typeid)
|
|
||||||
{
|
return ASSIGNED;
|
||||||
if (node.IsSequence() && node.size() == 3)
|
}
|
||||||
{
|
|
||||||
Vector3 vec;
|
bool SerialisationUtilities::varAssignYaml(System::Object^% object, YAML::Node& node)
|
||||||
vec.x = node[0].as<float>();
|
{
|
||||||
vec.y = node[1].as<float>();
|
const bool DESERIALISED =
|
||||||
vec.z = node[2].as<float>();
|
varAssignYamlInternal<System::Int16> (object, node) ||
|
||||||
fieldInfo->SetValue(object, vec);
|
varAssignYamlInternal<System::Int32> (object, node) ||
|
||||||
}
|
varAssignYamlInternal<System::Int64> (object, node) ||
|
||||||
else
|
varAssignYamlInternal<System::UInt16>(object, node) ||
|
||||||
{
|
varAssignYamlInternal<System::UInt32>(object, node) ||
|
||||||
Debug::LogWarning
|
varAssignYamlInternal<System::UInt64>(object, node) ||
|
||||||
(
|
varAssignYamlInternal<System::Byte> (object, node) ||
|
||||||
System::String::Format("[SerialisationUtilities] Invalid YAML Node provided for deserialization of a Vector3 \"{0}\" field in \"{1}\" script.",
|
varAssignYamlInternal<bool> (object, node) ||
|
||||||
fieldInfo->Name, object->GetType()->FullName)
|
varAssignYamlInternal<float> (object, node) ||
|
||||||
);
|
varAssignYamlInternal<double> (object, node) ||
|
||||||
}
|
varAssignYamlInternal<System::Enum> (object, node) ||
|
||||||
}
|
varAssignYamlInternal<System::String>(object, node) ||
|
||||||
else if (fieldInfo->FieldType == GameObject::typeid)
|
varAssignYamlInternal<Vector2> (object, node) ||
|
||||||
{
|
varAssignYamlInternal<Vector3> (object, node) ||
|
||||||
const uint32_t EID = node.as<uint32_t>();
|
varAssignYamlInternal<GameObject> (object, node);
|
||||||
fieldInfo->SetValue(object, EID == MAX_EID ? GameObject() : GameObject(EID));
|
return DESERIALISED;
|
||||||
}
|
|
||||||
else // Not any of the supported types
|
|
||||||
{
|
|
||||||
Debug::LogWarning(Convert::ToNative(System::String::Format
|
|
||||||
(
|
|
||||||
"[SerialisationUtilities] Failed to parse \"{0}\" of \"{1}\" type for deserialisation.",
|
|
||||||
fieldInfo->Name, fieldInfo->FieldType)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,6 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if constexpr (std::is_same_v<FieldType, System::Enum>)
|
if constexpr (std::is_same_v<FieldType, System::Enum>)
|
||||||
{
|
{
|
||||||
Debug::Log("Enum Specialization");
|
|
||||||
if (object->GetType()->IsSubclassOf(System::Enum::typeid))
|
if (object->GetType()->IsSubclassOf(System::Enum::typeid))
|
||||||
{
|
{
|
||||||
fieldNode = std::to_string(safe_cast<int>(object));
|
fieldNode = std::to_string(safe_cast<int>(object));
|
||||||
|
@ -45,7 +44,6 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else if constexpr (std::is_same_v<FieldType, System::String>)
|
else if constexpr (std::is_same_v<FieldType, System::String>)
|
||||||
{
|
{
|
||||||
Debug::Log("String Specialization");
|
|
||||||
if (object->GetType() == System::String::typeid)
|
if (object->GetType() == System::String::typeid)
|
||||||
{
|
{
|
||||||
System::String^ str = safe_cast<System::String^>(object);
|
System::String^ str = safe_cast<System::String^>(object);
|
||||||
|
@ -55,7 +53,6 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else if constexpr (std::is_same_v<FieldType, Vector2>)
|
else if constexpr (std::is_same_v<FieldType, Vector2>)
|
||||||
{
|
{
|
||||||
Debug::Log("Vec2 Specialization");
|
|
||||||
if (object->GetType() == Vector2::typeid)
|
if (object->GetType() == Vector2::typeid)
|
||||||
{
|
{
|
||||||
Vector2 vec = safe_cast<Vector2>(object);
|
Vector2 vec = safe_cast<Vector2>(object);
|
||||||
|
@ -67,7 +64,6 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else if constexpr (std::is_same_v<FieldType, Vector3>)
|
else if constexpr (std::is_same_v<FieldType, Vector3>)
|
||||||
{
|
{
|
||||||
Debug::Log("Vec3 Specialization");
|
|
||||||
if (object->GetType() == Vector3::typeid)
|
if (object->GetType() == Vector3::typeid)
|
||||||
{
|
{
|
||||||
Vector3 vec = safe_cast<Vector3>(object);
|
Vector3 vec = safe_cast<Vector3>(object);
|
||||||
|
@ -80,7 +76,6 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else if constexpr (std::is_same_v<FieldType, GameObject>)
|
else if constexpr (std::is_same_v<FieldType, GameObject>)
|
||||||
{
|
{
|
||||||
Debug::Log("GameObject Specialization");
|
|
||||||
if (object->GetType() == GameObject::typeid)
|
if (object->GetType() == GameObject::typeid)
|
||||||
{
|
{
|
||||||
GameObject gameObj = safe_cast<GameObject>(object);
|
GameObject gameObj = safe_cast<GameObject>(object);
|
||||||
|
@ -90,7 +85,6 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug::Log("No Specialization");
|
|
||||||
if (object->GetType() == FieldType::typeid)
|
if (object->GetType() == FieldType::typeid)
|
||||||
{
|
{
|
||||||
FieldType value = safe_cast<FieldType>(object);
|
FieldType value = safe_cast<FieldType>(object);
|
||||||
|
@ -108,18 +102,87 @@ namespace SHADE
|
||||||
template<typename FieldType>
|
template<typename FieldType>
|
||||||
bool SerialisationUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
|
bool SerialisationUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
|
||||||
{
|
{
|
||||||
return fieldAssignYaml<FieldType, ToNativeType_T<FieldType>>(fieldInfo, object, node);
|
System::Object^ valueObj = fieldInfo->GetValue(object);
|
||||||
}
|
if (varAssignYamlInternal<FieldType>(valueObj, node))
|
||||||
|
|
||||||
template<typename FieldType, typename CastType>
|
|
||||||
bool SerialisationUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
|
|
||||||
{
|
|
||||||
if (fieldInfo->FieldType == FieldType::typeid)
|
|
||||||
{
|
{
|
||||||
fieldInfo->SetValue(object, node.as<CastType>());
|
fieldInfo->SetValue(object, valueObj);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename FieldType, typename CastType>
|
||||||
|
bool SerialisationUtilities::varAssignYamlInternal(System::Object^% object, YAML::Node& node)
|
||||||
|
{
|
||||||
|
if constexpr (std::is_same_v<FieldType, System::Enum>)
|
||||||
|
{
|
||||||
|
if (object->GetType()->IsSubclassOf(System::Enum::typeid))
|
||||||
|
{
|
||||||
|
object = node.as<int>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<FieldType, System::Collections::IList>)
|
||||||
|
{
|
||||||
|
if (ReflectionUtilities::FieldIsList(fieldInfo))
|
||||||
|
{
|
||||||
|
System::Collections::IList^ iList = safe_cast<System::Collections::IList^>(object);
|
||||||
|
object = gcnew
|
||||||
|
if (node.IsSequence() )
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (object->GetType() == FieldType::typeid)
|
||||||
|
{
|
||||||
|
if constexpr (std::is_same_v<FieldType, System::String>)
|
||||||
|
{
|
||||||
|
object = Convert::ToCLI(node.as<std::string>());
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<FieldType, Vector2>)
|
||||||
|
{
|
||||||
|
if (node.IsSequence() && node.size() == 2)
|
||||||
|
{
|
||||||
|
Vector2 vec;
|
||||||
|
vec.x = node[0].as<float>();
|
||||||
|
vec.y = node[1].as<float>();
|
||||||
|
object = vec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<FieldType, Vector3>)
|
||||||
|
{
|
||||||
|
if (node.IsSequence() && node.size() == 3)
|
||||||
|
{
|
||||||
|
Vector3 vec;
|
||||||
|
vec.x = node[0].as<float>();
|
||||||
|
vec.y = node[1].as<float>();
|
||||||
|
vec.z = node[2].as<float>();
|
||||||
|
object = vec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<FieldType, GameObject>)
|
||||||
|
{
|
||||||
|
const uint32_t EID = node.as<uint32_t>();
|
||||||
|
object = (EID == MAX_EID ? GameObject() : GameObject(EID));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
object = node.as<CastType>();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,11 +63,12 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Deserialization Helper Functions */
|
/* Deserialization Helper Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
static void writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node);
|
static bool writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node);
|
||||||
template<typename FieldType>
|
template<typename FieldType>
|
||||||
static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node);
|
static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node);
|
||||||
template<typename FieldType, typename CastType>
|
static bool varAssignYaml(System::Object^% object, YAML::Node& node);
|
||||||
static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node);
|
template<typename FieldType, typename CastType = ToNativeType_T<FieldType>>
|
||||||
|
static bool varAssignYamlInternal(System::Object^% object, YAML::Node& node);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue