// Copyright (c) Wojciech Figat. All rights reserved.
using System;
#if FLAX_EDITOR
using System.ComponentModel;
using System.Globalization;
#endif
using System.Runtime.CompilerServices;
namespace FlaxEngine
{
///
/// Json asset reference utility. References resource with a typed data type.
///
/// Type of the asset instance type.
#if FLAX_EDITOR
[CustomEditor(typeof(FlaxEditor.CustomEditors.Editors.AssetRefEditor))]
[TypeConverter(typeof(TypeConverters.JsonAssetReferenceConverter))]
#endif
[Newtonsoft.Json.JsonConverter(typeof(Json.JsonAssetReferenceConverter))]
public struct JsonAssetReference : IComparable, IComparable>, IEquatable>
{
///
/// Gets or sets the referenced asset.
///
public JsonAsset Asset;
///
/// Gets the instance of the serialized object from the json asset data. Cached internally.
///
public T Instance => (T)Asset?.Instance;
///
/// Initializes a new instance of the structure.
///
/// The Json Asset.
public JsonAssetReference(JsonAsset asset)
{
Asset = asset;
}
///
/// Gets the deserialized native object instance of the given type. Returns null if asset is not loaded or loaded object has different type.
///
/// The asset instance object or null.
public U GetInstance()
{
return Asset ? Asset.GetInstance() : default(U);
}
///
/// Implicit cast operator.
///
public static implicit operator JsonAsset(JsonAssetReference value)
{
return value.Asset;
}
///
/// Implicit cast operator.
///
public static implicit operator IntPtr(JsonAssetReference value)
{
return Object.GetUnmanagedPtr(value.Asset);
}
///
/// Implicit cast operator.
///
public static implicit operator JsonAssetReference(JsonAsset value)
{
return new JsonAssetReference(value);
}
///
/// Implicit cast operator.
///
public static implicit operator JsonAssetReference(IntPtr valuePtr)
{
return new JsonAssetReference(Object.FromUnmanagedPtr(valuePtr) as JsonAsset);
}
///
/// Checks if the object exists (reference is not null and the unmanaged object pointer is valid).
///
/// The object to check.
/// True if object is valid, otherwise false.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator bool(JsonAssetReference obj)
{
return obj.Asset;
}
///
/// Checks whether the two objects are equal.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(JsonAssetReference left, JsonAssetReference right)
{
return left.Asset == right.Asset;
}
///
/// Checks whether the two objects are not equal.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(JsonAssetReference left, JsonAssetReference right)
{
return left.Asset != right.Asset;
}
///
public bool Equals(JsonAssetReference other)
{
return Asset == other.Asset;
}
///
public int CompareTo(JsonAssetReference other)
{
return Object.GetUnmanagedPtr(Asset).CompareTo(Object.GetUnmanagedPtr(other.Asset));
}
///
public override bool Equals(object obj)
{
return obj is JsonAssetReference other && Asset == other.Asset;
}
///
public override string ToString()
{
return Asset?.ToString() ?? "null";
}
///
public int CompareTo(object obj)
{
return obj is JsonAssetReference other ? CompareTo(other) : 1;
}
///
public override int GetHashCode()
{
return (Asset != null ? Asset.GetHashCode() : 0);
}
}
}
#if FLAX_EDITOR
namespace FlaxEngine.TypeConverters
{
internal class JsonAssetReferenceConverter : TypeConverter
{
///
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(id);
destinationType.GetField("Asset").SetValue(result, asset);
return result;
}
return base.ConvertTo(context, culture, value, destinationType);
}
///
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType.Name.StartsWith("JsonAssetReference", StringComparison.Ordinal))
return true;
return base.CanConvertTo(context, destinationType);
}
}
}
#endif