// 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