fix/refactoring RefRepairer

This commit is contained in:
DCFApixels 2025-03-20 14:15:38 +08:00
parent 98190ae382
commit e4d53c7825
9 changed files with 189 additions and 77 deletions

View File

@ -224,13 +224,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
//private static Type[] _noHiddenSerializableTypes; //private static Type[] _noHiddenSerializableTypes;
private static GUIContent _singletonIconContent = null; private static GUIContent _singletonIconContent = null;
private static GUIContent _singletonContent = null; private static GUIContent _singletonContent = null;
private static GUIStyle _inputFieldCenterAnhor = null; private static GUIStyle _inputFieldCenterAnhor = null;
private static Dictionary<Type, MonoScript> _scriptsAssets = new Dictionary<Type, MonoScript>(256); private static Dictionary<Type, MonoScript> _scriptsAssets = new Dictionary<Type, MonoScript>(256);
internal static void ResetValues(this SerializedProperty property, bool isExpand = false) internal static void ResetValues(this SerializedProperty property, bool isExpand = false)
{ {
ResetValues_Internal(property.Copy(), isExpand, property.depth); ResetValues_Internal(property.Copy(), isExpand, property.depth);

View File

@ -1,4 +1,5 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEditor; using UnityEditor;
@ -50,11 +51,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
private static List<string> _removedScriptGuids = new List<string>(); private static List<string> _removedScriptGuids = new List<string>();
private static List<string> _newScriptIDs = new List<string>(); private static List<string> _newScriptIDs = new List<string>();
public static IReadOnlyCollection<string> RemovedScriptPaths public static ReadOnlyList<string> RemovedScriptPaths
{ {
get { return _removedScriptGuids; } get { return _removedScriptGuids; }
} }
public static IReadOnlyCollection<string> NewScriptPaths public static ReadOnlyList<string> NewScriptPaths
{ {
get { return _newScriptIDs; } get { return _newScriptIDs; }
} }

View File

@ -61,19 +61,13 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
if (MonoScriptsAssetProcessor.Version <= _version) { return; } if (MonoScriptsAssetProcessor.Version <= _version) { return; }
if (MonoScriptsAssetProcessor.RemovedScriptPaths.Count > 0) var paths = MonoScriptsAssetProcessor.RemovedScriptPaths;
if (paths.Count > 0)
{ {
List<string> removedKeys = new List<string>(); List<string> removedKeys = new List<string>();
uint pathsLength = (uint)MonoScriptsAssetProcessor.RemovedScriptPaths.Count;
string[] paths = new string[pathsLength];
int i = 0;
foreach (var path in MonoScriptsAssetProcessor.RemovedScriptPaths)
{
paths[i++] = path;
}
foreach (var metaIDScriptPathPair in _metaIDScriptPathPairs) foreach (var metaIDScriptPathPair in _metaIDScriptPathPairs)
{ {
for (uint j = 0; j < pathsLength; j++) for (int j = 0; j < paths.Count; j++)
{ {
if (paths[j] == metaIDScriptPathPair.Value) if (paths[j] == metaIDScriptPathPair.Value)
{ {
@ -88,10 +82,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
} }
if (MonoScriptsAssetProcessor.NewScriptPaths.Count > 0) paths = MonoScriptsAssetProcessor.NewScriptPaths;
if (paths.Count > 0)
{ {
List<string> metaIDs = new List<string>(); List<string> metaIDs = new List<string>();
foreach (var assetPath in MonoScriptsAssetProcessor.NewScriptPaths) foreach (var assetPath in paths)
{ {
ExtractMetaIDs(AssetDatabase.LoadAssetAtPath<MonoScript>(assetPath).text, metaIDs); ExtractMetaIDs(AssetDatabase.LoadAssetAtPath<MonoScript>(assetPath).text, metaIDs);
foreach (var metaID in metaIDs) foreach (var metaID in metaIDs)

View File

@ -0,0 +1,40 @@
using System.Collections;
using System.Collections.Generic;
namespace DCFApixels.DragonECS.Unity.Internal
{
internal readonly struct ReadOnlyList<T> : IEnumerable<T>, IReadOnlyList<T>
{
private readonly List<T> _list;
public ReadOnlyList(List<T> list)
{
_list = list;
}
public int Count
{
get { return _list.Count; }
}
public T this[int index]
{
get { return _list[index]; }
set { _list[index] = value; }
}
public bool Contains(T item)
{
return _list.Contains(item);
}
public List<T>.Enumerator GetEnumerator()
{
return _list.GetEnumerator();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _list.GetEnumerator();
}
public static implicit operator ReadOnlyList<T>(List<T> a) { return new ReadOnlyList<T>(a); }
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d6be8f1171a60d646b862ec8472c55ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,7 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal; using DCFApixels.DragonECS.Unity.Internal;
using DCFApixels.DragonECS.Unity.RefRepairer.Editors;
using DCFApixels.DragonECS.Unity.RefRepairer.Internal;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
@ -20,18 +22,36 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
#endif #endif
public enum Page
{
ScriptsCache,
MetaIDRegistry,
}
private Page _page;
private Vector2 pos; private Vector2 pos;
private void OnGUI() private void OnGUI()
{ {
var dicst = ScriptsCache.MetaIDScriptPathPairs; _page = (Page)EditorGUILayout.EnumPopup(_page);
pos = GUILayout.BeginScrollView(pos); switch (_page)
{
case Page.ScriptsCache:
DrawScriptsCache();
break;
case Page.MetaIDRegistry:
DrawMetaIDRegistry();
break;
}
}
private void DrawScriptsCache()
{
if (GUILayout.Button("Reset")) if (GUILayout.Button("Reset"))
{ {
ScriptsCache.Reinit(); ScriptsCache.Reinit();
} }
var dicst = ScriptsCache.MetaIDScriptPathPairs;
pos = GUILayout.BeginScrollView(pos);
foreach (var (metaID, scriptPath) in dicst) foreach (var (metaID, scriptPath) in dicst)
{ {
GUILayout.Label("", GUILayout.ExpandWidth(true)); GUILayout.Label("", GUILayout.ExpandWidth(true));
@ -42,6 +62,28 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
GUILayout.EndScrollView(); GUILayout.EndScrollView();
} }
private void DrawMetaIDRegistry()
{
if (GUILayout.Button("Reset"))
{
MetaIDRegistry.instance.Reinit();
}
var dicst = MetaIDRegistry.instance.TypeKeyMetaIDPairs;
pos = GUILayout.BeginScrollView(pos);
foreach (var (typeData, scriptPath) in dicst)
{
GUILayout.Label("", GUILayout.ExpandWidth(true));
Rect rect = GUILayoutUtility.GetLastRect();
var (leftRect, rightRect) = rect.HorizontalSliceLerp(0.5f);
Rect preLeftRect = default;
(preLeftRect, leftRect) = rect.HorizontalSliceLeft(18f);
GUI.Label(preLeftRect, typeData.ToType() == null ? "-" : "+");
GUI.Label(leftRect, typeData.ToString());
GUI.Label(rightRect, scriptPath);
}
GUILayout.EndScrollView();
}
} }
} }
#endif #endif

View File

@ -28,11 +28,18 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
private Pair[] _typeKeyMetaIDPairsSerializable; private Pair[] _typeKeyMetaIDPairsSerializable;
#endregion #endregion
private Dictionary<TypeData, string> _typeKeyMetaIDPairs = new Dictionary<TypeData, string>(); private Dictionary<TypeData, string> _typeKeyMetaIDPairs = new Dictionary<TypeData, string>();
internal IReadOnlyDictionary<TypeData, string> TypeKeyMetaIDPairs => _typeKeyMetaIDPairs;
private bool _isChanged = false; private bool _isChanged = false;
public bool TryGetMetaID(TypeData key, out string metaID) public bool TryGetMetaID(TypeData key, out string metaID)
{ {
return _typeKeyMetaIDPairs.TryGetValue(key, out metaID); bool result = _typeKeyMetaIDPairs.TryGetValue(key, out metaID);
if(result && string.IsNullOrEmpty(metaID))
{
result = false;
_typeKeyMetaIDPairs.Remove(key);
}
return result;
} }
@ -43,7 +50,7 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
private static void BeforeCompilation() private static void BeforeCompilation()
{ {
EditorApplication.update -= BeforeCompilation; EditorApplication.update -= BeforeCompilation;
instance.TryGetMetaID(default, out _); instance.TryGetMetaID(TypeData.Empty, out _);
instance.Update(); instance.Update();
} }
@ -55,25 +62,26 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
} }
private void Update() private void Update()
{ {
var typeMetas = UnityEditorUtility._serializableTypeWithMetaIDMetas; if (UnityEditorUtility.IsHasAnyMetaIDCollision) { return; }
var typeMetas = UnityEditorUtility._typeWithMetaIDMetas;
foreach (var meta in typeMetas) foreach (var meta in typeMetas)
{ {
var key = new TypeData(meta.Type); var typeKey = new TypeData(meta.Type);
var metaID = meta.MetaID; var metaID = meta.MetaID;
//Debug.LogWarning(type + " " + metaID); //Debug.LogWarning(type + " " + metaID);
if (_typeKeyMetaIDPairs.TryGetValue(key, out string keyMetaID)) if (_typeKeyMetaIDPairs.TryGetValue(typeKey, out string storedMetaID))
{ {
if (keyMetaID != metaID) if (storedMetaID != metaID)
{ {
_typeKeyMetaIDPairs[key] = null; //Таким образом помечаются моменты когда не однозначно какой идентификатор принадлежит этому имени _typeKeyMetaIDPairs[typeKey] = string.Empty; //Таким образом помечаются моменты когда не однозначно какой идентификатор принадлежит этому имени
_isChanged = true; _isChanged = true;
} }
} }
else else
{ {
_typeKeyMetaIDPairs[key] = metaID; _typeKeyMetaIDPairs[typeKey] = metaID;
_isChanged = true; _isChanged = true;
} }
} }
@ -92,12 +100,11 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
_typeKeyMetaIDPairs.Clear(); _typeKeyMetaIDPairs.Clear();
foreach (var pair in _typeKeyMetaIDPairsSerializable) foreach (var pair in _typeKeyMetaIDPairsSerializable)
{ {
if (string.IsNullOrEmpty(pair.value) == false) if (string.IsNullOrEmpty(pair.value) || pair.key.IsEmpty) { continue; }
{
_typeKeyMetaIDPairs[pair.key] = pair.value; _typeKeyMetaIDPairs[pair.key] = pair.value;
} }
} }
}
void ISerializationCallbackReceiver.OnBeforeSerialize() void ISerializationCallbackReceiver.OnBeforeSerialize()
{ {
int i = 0; int i = 0;

View File

@ -1,7 +1,6 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.RefRepairer.Internal; using DCFApixels.DragonECS.Unity.RefRepairer.Internal;
using System; using System;
using System.Reflection;
namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
{ {
@ -9,8 +8,13 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
{ {
public readonly TypeData OldTypeData; public readonly TypeData OldTypeData;
public readonly string OldSerializedInfoLine; public readonly string OldSerializedInfoLine;
private TypeData _newTypeData; private TypeData _newTypeData;
private string _newSerializedInfoLine; private string _newSerializedInfoLine;
private Type _chachedNewType = null;
private bool _chachedNewTypeInited = false;
public MissingsResolvingData(TypeData oldTypeData) public MissingsResolvingData(TypeData oldTypeData)
{ {
OldTypeData = oldTypeData; OldTypeData = oldTypeData;
@ -18,13 +22,7 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
} }
public bool IsResolved public bool IsResolved
{ {
get get { return FindNewType() != null; }
{
//return
// string.IsNullOrEmpty(_newTypeData.ClassName) == false &&
// string.IsNullOrEmpty(_newTypeData.AssemblyName) == false;
return FindNewType() != null;
}
} }
public bool IsEmpty public bool IsEmpty
{ {
@ -35,34 +33,6 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
string.IsNullOrEmpty(_newTypeData.AssemblyName); string.IsNullOrEmpty(_newTypeData.AssemblyName);
} }
} }
private Type _chachedNewType = null;
private bool _chachedNewTypeInited = false;
public Type FindNewType()
{
if (_chachedNewTypeInited == false)
{
if (string.IsNullOrEmpty(_newTypeData.AssemblyName) == false)
{
Assembly assembly = null;
try
{
assembly = Assembly.Load(_newTypeData.AssemblyName);
}
catch { }
if (assembly == null)
{
_chachedNewType = null;
}
else
{
string fullTypeName = $"{_newTypeData.NamespaceName}.{_newTypeData.ClassName}";
_chachedNewType = assembly.GetType(fullTypeName);
}
_chachedNewTypeInited = true;
}
}
return _chachedNewType;
}
public TypeData NewTypeData public TypeData NewTypeData
{ {
get { return _newTypeData; } get { return _newTypeData; }
@ -85,6 +55,15 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
return _newSerializedInfoLine; return _newSerializedInfoLine;
} }
} }
public Type FindNewType()
{
if (_chachedNewTypeInited == false)
{
_chachedNewType = _newTypeData.ToType();
}
return _chachedNewType;
}
} }
} }
#endif #endif

View File

@ -1,5 +1,6 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using System; using System;
using System.Reflection;
using System.Text; using System.Text;
using UnityEditor; using UnityEditor;
@ -11,6 +12,7 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Internal
public string ClassName; public string ClassName;
public string NamespaceName; public string NamespaceName;
public string AssemblyName; public string AssemblyName;
public bool IsEmpty { get { return string.IsNullOrWhiteSpace(ClassName); } }
public TypeDataSerializable(string typeName, string namespaceName, string assemblyName) public TypeDataSerializable(string typeName, string namespaceName, string assemblyName)
{ {
ClassName = typeName; ClassName = typeName;
@ -19,17 +21,19 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Internal
} }
public static implicit operator TypeDataSerializable(TypeData type) { return new TypeDataSerializable(type.ClassName, type.NamespaceName, type.AssemblyName); } public static implicit operator TypeDataSerializable(TypeData type) { return new TypeDataSerializable(type.ClassName, type.NamespaceName, type.AssemblyName); }
public static implicit operator TypeData(TypeDataSerializable type) { return new TypeData(type.ClassName, type.NamespaceName, type.AssemblyName); } public static implicit operator TypeData(TypeDataSerializable type) { return new TypeData(type.ClassName, type.NamespaceName, type.AssemblyName); }
public override string ToString() { return $"{{{AssemblyName}, {NamespaceName}, {ClassName}}}"; }
} }
internal readonly struct TypeData : IEquatable<TypeData> internal readonly struct TypeData : IEquatable<TypeData>
{ {
public static readonly TypeData Empty = new TypeData(string.Empty, string.Empty, string.Empty);
public readonly string ClassName; public readonly string ClassName;
public readonly string NamespaceName; public readonly string NamespaceName;
public readonly string AssemblyName; public readonly string AssemblyName;
public TypeData(ManagedReferenceMissingType managedReferenceMissingType) public TypeData(ManagedReferenceMissingType managedReferenceMissingType)
{ {
ClassName = managedReferenceMissingType.className; ClassName = managedReferenceMissingType.className ?? string.Empty;
NamespaceName = managedReferenceMissingType.namespaceName; NamespaceName = managedReferenceMissingType.namespaceName ?? string.Empty;
AssemblyName = managedReferenceMissingType.assemblyName; AssemblyName = managedReferenceMissingType.assemblyName ?? string.Empty;
} }
public TypeData(string typeName, string namespaceName, string assemblyName) public TypeData(string typeName, string namespaceName, string assemblyName)
{ {
@ -37,12 +41,12 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Internal
NamespaceName = namespaceName; NamespaceName = namespaceName;
AssemblyName = assemblyName; AssemblyName = assemblyName;
} }
public bool IsEmpty { get { return string.IsNullOrWhiteSpace(ClassName); } }
[ThreadStatic] [ThreadStatic]
private static StringBuilder sb; private static StringBuilder sb;
public TypeData(Type type) public TypeData(Type type)
{ {
string name = null; string name = string.Empty;
if (type.DeclaringType == null) if (type.DeclaringType == null)
{ {
name = type.Name; name = type.Name;
@ -65,7 +69,7 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Internal
} }
ClassName = name; ClassName = name;
NamespaceName = type.Namespace; NamespaceName = type.Namespace ?? string.Empty;
AssemblyName = type.Assembly.GetName().Name; AssemblyName = type.Assembly.GetName().Name;
} }
public bool Equals(TypeData other) public bool Equals(TypeData other)
@ -74,13 +78,48 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Internal
NamespaceName == other.NamespaceName && NamespaceName == other.NamespaceName &&
AssemblyName == other.AssemblyName; AssemblyName == other.AssemblyName;
} }
public override bool Equals(object obj) public override bool Equals(object obj) { return Equals((TypeData)obj); }
{
return Equals((TypeData)obj);
}
public override int GetHashCode() public override int GetHashCode()
{ {
return HashCode.Combine(ClassName, NamespaceName, AssemblyName); int hash1 = ClassName.GetHashCode();
int hash2 = NamespaceName.GetHashCode();
int hash3 = AssemblyName.GetHashCode();
return hash1 ^ hash2 ^ hash3;
}
public override string ToString() { return $"{{{AssemblyName}, {NamespaceName}, {ClassName}}}"; }
}
internal static class TypeDataExtensions
{
public static Type ToType(this TypeData sefl)
{
return ToType(sefl.AssemblyName, sefl.NamespaceName, sefl.ClassName);
}
public static Type ToType(this TypeDataSerializable sefl)
{
return ToType(sefl.AssemblyName, sefl.NamespaceName, sefl.ClassName);
}
private static Type ToType(string AssemblyName, string NamespaceName, string ClassName)
{
Type result = null;
if (string.IsNullOrEmpty(AssemblyName) == false)
{
Assembly assembly = null;
try
{
assembly = Assembly.Load(AssemblyName);
}
catch { }
if (assembly == null)
{
result = null;
}
else
{
string fullTypeName = $"{NamespaceName}.{ClassName}";
result = assembly.GetType(fullTypeName);
}
}
return result;
} }
} }
} }