Add support for using structures as Visual Script and Anim Graph parameters

This commit is contained in:
Wojtek Figat
2021-07-29 23:35:30 +02:00
parent 24782bdd2f
commit d8f555e8dc
5 changed files with 32 additions and 44 deletions

View File

@@ -29,8 +29,8 @@ namespace FlaxEditor.Modules.SourceCodeEditing
{ {
if (scriptType.IsStatic || scriptType.IsGenericType || !scriptType.IsPublic || scriptType.HasAttribute(typeof(HideInEditorAttribute), true)) if (scriptType.IsStatic || scriptType.IsGenericType || !scriptType.IsPublic || scriptType.HasAttribute(typeof(HideInEditorAttribute), true))
return false; return false;
var objectType = new ScriptType(typeof(FlaxEngine.Object)); var managedType = TypeUtils.GetType(scriptType);
return scriptType.IsEnum || objectType.IsAssignableFrom(scriptType); return !TypeUtils.IsDelegate(managedType);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -414,15 +414,6 @@ namespace FlaxEditor.Utilities
var id = stream.ReadGuid(); var id = stream.ReadGuid();
return FlaxEngine.Object.Find(ref id, type ?? typeof(FlaxEngine.Object)); return FlaxEngine.Object.Find(ref id, type ?? typeof(FlaxEngine.Object));
} }
case VariantType.Structure:
{
if (type == null)
throw new Exception("Missing structure type of the Variant.");
if (!type.IsStructure())
throw new Exception($"Invalid type {type.FullName} used as a structure.");
var data = stream.ReadBytes(stream.ReadInt32());
return Utils.ByteArrayToStructure(data, type);
}
case VariantType.Asset: case VariantType.Asset:
{ {
var id = stream.ReadGuid(); var id = stream.ReadGuid();
@@ -479,6 +470,7 @@ namespace FlaxEditor.Utilities
return TypeUtils.GetType(typeName); return TypeUtils.GetType(typeName);
} }
case VariantType.ManagedObject: case VariantType.ManagedObject:
case VariantType.Structure:
{ {
if (type == null) if (type == null)
throw new Exception("Missing type of the Variant typename " + typeName); throw new Exception("Missing type of the Variant typename " + typeName);
@@ -580,13 +572,6 @@ namespace FlaxEditor.Utilities
id = ((FlaxEngine.Object)value).ID; id = ((FlaxEngine.Object)value).ID;
stream.WriteGuid(ref id); stream.WriteGuid(ref id);
break; break;
case VariantType.Structure:
{
var data = Utils.StructureToByteArray(value, type);
stream.Write(data.Length);
stream.Write(data);
break;
}
case VariantType.Asset: case VariantType.Asset:
id = ((Asset)value).ID; id = ((Asset)value).ID;
stream.WriteGuid(ref id); stream.WriteGuid(ref id);
@@ -664,6 +649,7 @@ namespace FlaxEditor.Utilities
stream.WriteStrAnsi(((ScriptType)value).TypeName, -14); stream.WriteStrAnsi(((ScriptType)value).TypeName, -14);
break; break;
case VariantType.ManagedObject: case VariantType.ManagedObject:
case VariantType.Structure:
{ {
stream.Write((byte)1); stream.Write((byte)1);
var json = FlaxEngine.Json.JsonSerializer.Serialize(value, type); var json = FlaxEngine.Json.JsonSerializer.Serialize(value, type);
@@ -690,6 +676,7 @@ namespace FlaxEditor.Utilities
break; break;
case VariantType.Enum: case VariantType.Enum:
case VariantType.Structure: case VariantType.Structure:
case VariantType.ManagedObject:
withoutTypeName = false; withoutTypeName = false;
break; break;
} }
@@ -1115,6 +1102,7 @@ namespace FlaxEditor.Utilities
stream.WriteValue(((ScriptType)value).TypeName); stream.WriteValue(((ScriptType)value).TypeName);
break; break;
case VariantType.ManagedObject: case VariantType.ManagedObject:
case VariantType.Structure:
{ {
var json = FlaxEngine.Json.JsonSerializer.Serialize(value, type); var json = FlaxEngine.Json.JsonSerializer.Serialize(value, type);
stream.WriteRaw(json); stream.WriteRaw(json);

View File

@@ -1501,7 +1501,7 @@ Variant::operator ScriptingObject*() const
Variant::operator _MonoObject*() const Variant::operator _MonoObject*() const
{ {
return AsUint ? mono_gchandle_get_target(AsUint) : nullptr; return Type.Type == VariantType::ManagedObject && AsUint ? mono_gchandle_get_target(AsUint) : nullptr;
} }
Variant::operator Asset*() const Variant::operator Asset*() const

View File

@@ -139,7 +139,6 @@ void Serialization::Serialize(ISerializable::SerializeStream& stream, const Vari
else else
stream.String("", 0); stream.String("", 0);
break; break;
case VariantType::Structure:
case VariantType::Blob: case VariantType::Blob:
stream.Blob(v.AsBlob.Data, v.AsBlob.Length); stream.Blob(v.AsBlob.Data, v.AsBlob.Length);
break; break;
@@ -207,8 +206,16 @@ void Serialization::Serialize(ISerializable::SerializeStream& stream, const Vari
stream.String("", 0); stream.String("", 0);
break; break;
case VariantType::ManagedObject: case VariantType::ManagedObject:
ManagedSerialization::Serialize(stream, (MonoObject*)v); case VariantType::Structure:
{
MonoObject* obj;
if (v.Type.Type == VariantType::Structure)
obj = MUtils::BoxVariant(v);
else
obj = (MonoObject*)v;
ManagedSerialization::Serialize(stream, obj);
break; break;
}
default: default:
Platform::CheckFailed("", __FILE__, __LINE__); Platform::CheckFailed("", __FILE__, __LINE__);
stream.StartObject(); stream.StartObject();
@@ -275,7 +282,6 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian
Deserialize(value, id, modifier); Deserialize(value, id, modifier);
v.SetAsset(LoadAsset(id, Asset::TypeInitializer)); v.SetAsset(LoadAsset(id, Asset::TypeInitializer));
break; break;
case VariantType::Structure:
case VariantType::Blob: case VariantType::Blob:
CHECK(value.IsString()); CHECK(value.IsString());
id.A = value.GetStringLength(); id.A = value.GetStringLength();
@@ -338,6 +344,7 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian
v.SetTypename(value.GetStringAnsiView()); v.SetTypename(value.GetStringAnsiView());
break; break;
case VariantType::ManagedObject: case VariantType::ManagedObject:
case VariantType::Structure:
{ {
auto obj = (MonoObject*)v; auto obj = (MonoObject*)v;
if (!obj && v.Type.TypeName) if (!obj && v.Type.TypeName)
@@ -356,9 +363,12 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian
} }
if (!mono_class_is_valuetype(klass)) if (!mono_class_is_valuetype(klass))
mono_runtime_object_init(obj); mono_runtime_object_init(obj);
v.SetManagedObject(obj); if (v.Type.Type == VariantType::ManagedObject)
v.SetManagedObject(obj);
} }
ManagedSerialization::Deserialize(value, obj); ManagedSerialization::Deserialize(value, obj);
if (v.Type.Type == VariantType::Structure)
v = MUtils::UnboxVariant(obj);
break; break;
} }
default: default:

View File

@@ -340,6 +340,7 @@ void ReadStream::ReadVariant(Variant* data)
break; break;
} }
case VariantType::ManagedObject: case VariantType::ManagedObject:
case VariantType::Structure:
{ {
const byte format = ReadByte(); const byte format = ReadByte();
if (format == 0) if (format == 0)
@@ -367,7 +368,10 @@ void ReadStream::ReadVariant(Variant* data)
if (!mono_class_is_valuetype(klass)) if (!mono_class_is_valuetype(klass))
mono_runtime_object_init(obj); mono_runtime_object_init(obj);
ManagedSerialization::Deserialize(json, obj); ManagedSerialization::Deserialize(json, obj);
data->SetManagedObject(obj); if (data->Type.Type == VariantType::ManagedObject)
data->SetManagedObject(obj);
else
*data = MUtils::UnboxVariant(obj);
} }
else else
{ {
@@ -375,23 +379,6 @@ void ReadStream::ReadVariant(Variant* data)
} }
break; break;
} }
case VariantType::Structure:
{
int32 length;
ReadInt32(&length);
if (data->AsBlob.Length == length)
{
ReadBytes(data->AsBlob.Data, length);
}
else
{
LOG(Error, "Invalid Variant {2} data length {0}. Expected {1} bytes from stream.", data->AsBlob.Length, length, data->Type.ToString());
// Skip those bytes
SetPosition(GetPosition() + length);
}
break;
}
case VariantType::Blob: case VariantType::Blob:
{ {
int32 length; int32 length;
@@ -651,7 +638,6 @@ void WriteStream::WriteVariant(const Variant& data)
id = data.AsObject ? data.AsObject->GetID() : Guid::Empty; id = data.AsObject ? data.AsObject->GetID() : Guid::Empty;
Write(&id); Write(&id);
break; break;
case VariantType::Structure:
case VariantType::Blob: case VariantType::Blob:
WriteInt32(data.AsBlob.Length); WriteInt32(data.AsBlob.Length);
WriteBytes(data.AsBlob.Data, data.AsBlob.Length); WriteBytes(data.AsBlob.Data, data.AsBlob.Length);
@@ -714,8 +700,13 @@ void WriteStream::WriteVariant(const Variant& data)
WriteStringAnsi((StringAnsiView)data, -14); WriteStringAnsi((StringAnsiView)data, -14);
break; break;
case VariantType::ManagedObject: case VariantType::ManagedObject:
case VariantType::Structure:
{ {
MonoObject* obj = (MonoObject*)data; MonoObject* obj;
if (data.Type.Type == VariantType::Structure)
obj = MUtils::BoxVariant(data);
else
obj = (MonoObject*)data;
if (obj) if (obj)
{ {
WriteByte(1); WriteByte(1);
@@ -731,7 +722,6 @@ void WriteStream::WriteVariant(const Variant& data)
} }
break; break;
} }
break;
default: default:
CRASH; CRASH;
} }