update Reference type

This commit is contained in:
Mikhail 2024-09-18 20:05:30 +08:00
parent 19d968d8c0
commit 18fde18a74
2 changed files with 81 additions and 15 deletions

View File

@ -7,4 +7,14 @@
public const string DEBUG_LAYER = EcsConsts.NAME_SPACE + "Unity." + nameof(DEBUG_LAYER); public const string DEBUG_LAYER = EcsConsts.NAME_SPACE + "Unity." + nameof(DEBUG_LAYER);
} }
public class EcsUnityDefines
{
public const bool DISABLE_SERIALIZE_REFERENCE_RECOVERY =
#if DISABLE_SERIALIZE_REFERENCE_RECOVERY
true;
#else
false;
#endif
}
} }

View File

@ -1,15 +1,43 @@
using System.Runtime.CompilerServices; //#define DISABLE_SERIALIZE_REFERENCE_RECOVERY
using System;
using System.Runtime.CompilerServices;
using UnityEngine; using UnityEngine;
#if UNITY_EDITOR && !DISABLE_SERIALIZE_REFERENCE_RECOVERY
using DCFApixels.DragonECS.Unity.Internal;
using System.Collections.Generic;
using UnityEditor;
#endif
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
[System.Serializable] #if UNITY_EDITOR && !DISABLE_SERIALIZE_REFERENCE_RECOVERY
[InitializeOnLoad]
internal static class ReferenceUtility
{
static ReferenceUtility()
{
_recompileAfterInitializationScope = true;
EditorApplication.update += BeforeCompilation;
}
private static void BeforeCompilation()
{
_recompileAfterInitializationScope = false;
EditorApplication.update -= BeforeCompilation;
}
internal static bool _recompileAfterInitializationScope = false;
}
#endif
[Serializable]
public struct Reference<T> public struct Reference<T>
#if UNITY_EDITOR #if UNITY_EDITOR && !DISABLE_SERIALIZE_REFERENCE_RECOVERY
: ISerializationCallbackReceiver : ISerializationCallbackReceiver
#endif #endif
{ {
#if UNITY_EDITOR #if UNITY_EDITOR && !DISABLE_SERIALIZE_REFERENCE_RECOVERY
[SerializeReference] [SerializeReference]
private T _value; private T _value;
[SerializeField] [SerializeField]
@ -22,40 +50,68 @@ namespace DCFApixels.DragonECS
set { _value = value; } set { _value = value; }
} }
#else #else
[SerializeField]
public T Value; public T Value;
#endif #endif
public bool IsNull
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return Value == null; }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator T(Reference<T> a) { return a.Value; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Reference<T>(T a) { return new Reference<T>() { Value = a }; }
#if UNITY_EDITOR && !DISABLE_SERIALIZE_REFERENCE_RECOVERY
private static Dictionary<string, Type> _metaIDTypePairs;
#if UNITY_EDITOR
private static System.Collections.Generic.Dictionary<string, System.Type> _metaIDTypePairs;
private static void InitRecoverCache() private static void InitRecoverCache()
{ {
if (_metaIDTypePairs == null) { return; } if (_metaIDTypePairs != null) { return; }
_metaIDTypePairs = new System.Collections.Generic.Dictionary<string, System.Type>(); _metaIDTypePairs = new Dictionary<string, Type>();
List<Type> types = new List<Type>();
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (var type in assembly.GetTypes())
{
if (type.TryGetAttribute(out MetaIDAttribute atr))
{
_metaIDTypePairs.Add(atr.ID, type);
}
}
}
} }
private static T TryRecoverReference(string metaID) private static T TryRecoverReference(string metaID)
{ {
InitRecoverCache(); InitRecoverCache();
if (_metaIDTypePairs.TryGetValue(metaID, out System.Type type)) if (_metaIDTypePairs.TryGetValue(metaID, out Type type))
{ {
return (T)System.Activator.CreateInstance(type); return (T)Activator.CreateInstance(type);
} }
return default; return default;
} }
void ISerializationCallbackReceiver.OnAfterDeserialize() void ISerializationCallbackReceiver.OnAfterDeserialize()
{ {
if (_value == null) if (_value == null && ReferenceUtility._recompileAfterInitializationScope && string.IsNullOrEmpty(_json) == false)
{ {
int indexof = _json.IndexOf(','); int indexof = _json.IndexOf(',');
_value = TryRecoverReference(_json.Substring(0, indexof)); _value = TryRecoverReference(_json.Substring(0, indexof));
if (_value == null) { return; } if (_value == null) { return; }
JsonUtility.FromJsonOverwrite(_json.Substring(indexof + 1), _value); JsonUtility.FromJsonOverwrite(_json.Substring(indexof + 1), _value);
_json = null;
} }
_json = null;
} }
void ISerializationCallbackReceiver.OnBeforeSerialize() void ISerializationCallbackReceiver.OnBeforeSerialize()
{
if (_value != null && EditorApplication.isPlaying == false)
{ {
_json = $"{_value.GetMeta().MetaID},{JsonUtility.ToJson(_value)}"; _json = $"{_value.GetMeta().MetaID},{JsonUtility.ToJson(_value)}";
} }
}
#endif #endif
} }
} }