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 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;
#if UNITY_EDITOR && !DISABLE_SERIALIZE_REFERENCE_RECOVERY
using DCFApixels.DragonECS.Unity.Internal;
using System.Collections.Generic;
using UnityEditor;
#endif
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>
#if UNITY_EDITOR
#if UNITY_EDITOR && !DISABLE_SERIALIZE_REFERENCE_RECOVERY
: ISerializationCallbackReceiver
#endif
{
#if UNITY_EDITOR
#if UNITY_EDITOR && !DISABLE_SERIALIZE_REFERENCE_RECOVERY
[SerializeReference]
private T _value;
[SerializeField]
@ -21,41 +49,69 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set { _value = value; }
}
#else
#else
[SerializeField]
public T Value;
#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()
{
if (_metaIDTypePairs == null) { return; }
_metaIDTypePairs = new System.Collections.Generic.Dictionary<string, System.Type>();
if (_metaIDTypePairs != null) { return; }
_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)
{
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;
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (_value == null)
if (_value == null && ReferenceUtility._recompileAfterInitializationScope && string.IsNullOrEmpty(_json) == false)
{
int indexof = _json.IndexOf(',');
_value = TryRecoverReference(_json.Substring(0, indexof));
if (_value == null) { return; }
JsonUtility.FromJsonOverwrite(_json.Substring(indexof + 1), _value);
_json = null;
}
_json = null;
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
_json = $"{_value.GetMeta().MetaID},{JsonUtility.ToJson(_value)}";
if (_value != null && EditorApplication.isPlaying == false)
{
_json = $"{_value.GetMeta().MetaID},{JsonUtility.ToJson(_value)}";
}
}
#endif
}
}
}