Fix undo-redo for JsonAssetReference in Editor

#2711
This commit is contained in:
Wojtek Figat
2024-08-28 23:42:59 +02:00
parent ca0fb8cf63
commit ec412d9be0
3 changed files with 49 additions and 1 deletions

View File

@@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@@ -671,6 +672,18 @@ namespace FlaxEditor.Scripting
/// <param name="value">The new member value.</param> /// <param name="value">The new member value.</param>
public void SetValue(object obj, object value) public void SetValue(object obj, object value)
{ {
// Perform automatic conversion if type supports it
var type = ValueType.Type;
var valueType = value?.GetType();
if (valueType != null && type != null && valueType != type)
{
var converter = TypeDescriptor.GetConverter(type);
if (converter.CanConvertTo(type))
value = converter.ConvertTo(value, type);
else if (converter.CanConvertFrom(valueType))
value = converter.ConvertFrom(null, null, value);
}
if (_managed is PropertyInfo propertyInfo) if (_managed is PropertyInfo propertyInfo)
propertyInfo.SetValue(obj, value); propertyInfo.SetValue(obj, value);
else if (_managed is FieldInfo fieldInfo) else if (_managed is FieldInfo fieldInfo)

View File

@@ -1,6 +1,10 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System; using System;
#if FLAX_EDITOR
using System.ComponentModel;
using System.Globalization;
#endif
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace FlaxEngine namespace FlaxEngine
@@ -11,6 +15,7 @@ namespace FlaxEngine
/// <typeparam name="T">Type of the asset instance type.</typeparam> /// <typeparam name="T">Type of the asset instance type.</typeparam>
#if FLAX_EDITOR #if FLAX_EDITOR
[CustomEditor(typeof(FlaxEditor.CustomEditors.Editors.AssetRefEditor))] [CustomEditor(typeof(FlaxEditor.CustomEditors.Editors.AssetRefEditor))]
[TypeConverter(typeof(TypeConverters.JsonAssetReferenceConverter))]
#endif #endif
[Newtonsoft.Json.JsonConverter(typeof(Json.JsonAssetReferenceConverter))] [Newtonsoft.Json.JsonConverter(typeof(Json.JsonAssetReferenceConverter))]
public struct JsonAssetReference<T> : IComparable, IComparable<JsonAssetReference<T>>, IEquatable<JsonAssetReference<T>> public struct JsonAssetReference<T> : IComparable, IComparable<JsonAssetReference<T>>, IEquatable<JsonAssetReference<T>>
@@ -141,3 +146,33 @@ namespace FlaxEngine
} }
} }
} }
#if FLAX_EDITOR
namespace FlaxEngine.TypeConverters
{
internal class JsonAssetReferenceConverter : TypeConverter
{
/// <inheritdoc />
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (value is string valueStr)
{
var result = Activator.CreateInstance(destinationType);
Json.JsonSerializer.ParseID(valueStr, out var id);
var asset = Content.LoadAsync<JsonAsset>(id);
destinationType.GetField("Asset").SetValue(result, asset);
return result;
}
return base.ConvertTo(context, culture, value, destinationType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType.Name.StartsWith("JsonAssetReference", StringComparison.Ordinal))
return true;
return base.CanConvertTo(context, destinationType);
}
}
}
#endif

View File

@@ -479,7 +479,7 @@ namespace FlaxEngine.Json
/// <inheritdoc /> /// <inheritdoc />
public override bool CanConvert(Type objectType) public override bool CanConvert(Type objectType)
{ {
return objectType.Name.StartsWith("JsonAssetReference"); return objectType.Name.StartsWith("JsonAssetReference", StringComparison.Ordinal);
} }
} }