This commit is contained in:
Mikhail 2024-09-30 19:40:50 +08:00
parent 3c3fb1891d
commit 776648a993
7 changed files with 120 additions and 82 deletions

View File

@ -20,7 +20,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
wnd.Show(); wnd.Show();
} }
private List<ContainerMissingTypes> _missingTypes; private List<ContainerMissingRefs> _missingTypes;
//private readonly CollectorMissingTypes _collectorMissingTypes = new CollectorMissingTypes(); //private readonly CollectorMissingTypes _collectorMissingTypes = new CollectorMissingTypes();
private bool TryInit() private bool TryInit()

View File

@ -3,6 +3,7 @@ using DCFApixels.DragonECS.Unity.Editors;
using DCFApixels.DragonECS.Unity.RefRepairer.Internal; using DCFApixels.DragonECS.Unity.RefRepairer.Internal;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
@ -56,14 +57,38 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
private void Update() private void Update()
{ {
var typeMetas = UnityEditorUtility._serializableTypeWithMetaIDMetas; var typeMetas = UnityEditorUtility._serializableTypeWithMetaIDMetas;
StringBuilder sb = null;
foreach (var meta in typeMetas) foreach (var meta in typeMetas)
{ {
var type = meta.Type; var type = meta.Type;
var key = new TypeData(type.Name, type.Namespace, type.Assembly.FullName); string name = null;
if (type.DeclaringType == null)
{
name = type.Name;
}
else
{
Type iteratorType = type;
if (sb == null)
{
sb = new StringBuilder();
}
sb.Clear();
sb.Append(iteratorType.Name);
while ((iteratorType = iteratorType.DeclaringType) != null)
{
sb.Insert(0, '/');
sb.Insert(0, iteratorType.Name);
}
name = sb.ToString();
}
var key = new TypeData(name, type.Namespace, type.Assembly.GetName().Name);
var metaID = meta.MetaID; var metaID = meta.MetaID;
if (_typeKeyMetaIDPairs.TryGetValue(key, out string keyMetaID) == false) //Debug.LogWarning(type + " " + metaID);
if (_typeKeyMetaIDPairs.TryGetValue(key, out string keyMetaID))
{ {
if (keyMetaID != metaID) if (keyMetaID != metaID)
{ {
@ -77,11 +102,10 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
_isChanged = true; _isChanged = true;
} }
} }
if (_isChanged) if (_isChanged)
{ {
EditorUtility.SetDirty(this);
_isChanged = false; _isChanged = false;
EditorUtility.SetDirty(this);
Save(true); Save(true);
} }
} }

View File

@ -1,4 +1,4 @@
using DCFApixels.DragonECS.Unity.RefRepairer.Internal; #if UNITY_EDITOR
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -10,7 +10,7 @@ using UnityObject = UnityEngine.Object;
namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
{ {
public static class UnityObjectExtensions internal static class UnityObjectExtensions
{ {
public static int GetLocalIdentifierInFile(this UnityObject unityObject) public static int GetLocalIdentifierInFile(this UnityObject unityObject)
{ {
@ -22,111 +22,111 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
} }
} }
internal class MissingRefUtility internal class ContainerMissingTypes
{ {
private readonly Dictionary<TypeData, ContainerMissingTypes> _missingTypes = new Dictionary<TypeData, ContainerMissingTypes>(); public readonly GUID AssetGUID;
public readonly List<ContainerMissingRefs> Recirds = new List<ContainerMissingRefs>();
public ContainerMissingTypes(GUID assetGUID)
{
AssetGUID = assetGUID;
}
}
internal class MissingRefCollectUtility
{
//private readonly Dictionary<TypeData, ContainerMissingRefs> _manualRepairedMissingRefs = new Dictionary<TypeData, ContainerMissingRefs>();
//private readonly List<ContainerMissingTypes> _autoRepariedMissingTypes = new List<ContainerMissingTypes>();
private readonly List<Record> _collectedMissingTypes = new List<Record>();
#region Collect #region Collect
public List<ContainerMissingTypes> Collect() public List<Record> Collect()
{ {
_missingTypes.Clear(); //_manualRepairedMissingRefs.Clear();
CollectByPrefabs(); _collectedMissingTypes.Clear();
CollectByScriptableObjects();
CollectByScenes();
List<ContainerMissingTypes> result = new List<ContainerMissingTypes>(_missingTypes.Select((typeAndContainer) => typeAndContainer.Value)); CollectByPrefabs(_collectedMissingTypes);
_missingTypes.Clear(); CollectByScriptableObjects(_collectedMissingTypes);
return result; CollectByScenes(_collectedMissingTypes);
//ContainerMissingRefs[] result = _manualRepairedMissingRefs.Values.ToArray();
//_manualRepairedMissingRefs.Clear();
return _collectedMissingTypes;
} }
private void CollectByPrefabs() public readonly struct Record
{
public readonly UnityObjectDataBase UnityObject;
public readonly ManagedReferenceMissingType[] missingTypes;
public Record(UnityObjectDataBase unityObject, ManagedReferenceMissingType[] missingTypes)
{
UnityObject = unityObject;
this.missingTypes = missingTypes;
}
}
private void CollectByPrefabs(List<Record> list)
{ {
Scene previewScene = EditorSceneManager.NewPreviewScene(); Scene previewScene = EditorSceneManager.NewPreviewScene();
foreach (var pathToPrefab in AssetDatabase.GetAllAssetPaths().Where(path => path.StartsWith("Assets/") && path.EndsWith(".prefab"))) foreach (var pathToPrefab in AssetDatabase.GetAllAssetPaths().Where(path => path.StartsWith("Assets/") && path.EndsWith(".prefab")))
{ {
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(pathToPrefab); var prefabAsset = AssetDatabase.LoadAssetAtPath<GameObject>(pathToPrefab);
var unityObjectData = new UnityObjectData(prefabAsset, pathToPrefab);
PrefabUtility.LoadPrefabContentsIntoPreviewScene(pathToPrefab, previewScene); PrefabUtility.LoadPrefabContentsIntoPreviewScene(pathToPrefab, previewScene);
var copyPrefab = previewScene.GetRootGameObjects()[0]; var prefabLoaded = previewScene.GetRootGameObjects()[0];
var componentsPrefab = prefab.GetComponentsInChildren<MonoBehaviour>(); foreach (var component in prefabLoaded.GetComponentsInChildren<MonoBehaviour>())
var componentsCopyPrefab = copyPrefab.GetComponentsInChildren<MonoBehaviour>();
for (int i = 0; i < componentsCopyPrefab.Length; ++i)
{ {
var monoBehaviour = componentsCopyPrefab[i]; if (SerializationUtility.HasManagedReferencesWithMissingTypes(component) == false) { continue; }
if (SerializationUtility.HasManagedReferencesWithMissingTypes(monoBehaviour) == false)
{
continue;
}
foreach (var missingType in SerializationUtility.GetManagedReferencesWithMissingTypes(monoBehaviour)) var missings = SerializationUtility.GetManagedReferencesWithMissingTypes(component);
{ list.Add(new Record(unityObjectData, missings));
var prefabObject = new UnityObjectData(componentsPrefab[i].gameObject, pathToPrefab);
AddMissingType(missingType, prefabObject);
}
} }
UnityObject.DestroyImmediate(copyPrefab); UnityObject.DestroyImmediate(prefabLoaded);
} }
EditorSceneManager.ClosePreviewScene(previewScene); EditorSceneManager.ClosePreviewScene(previewScene);
} }
private void CollectByScriptableObjects() private void CollectByScriptableObjects(List<Record> list)
{ {
foreach (var pathToPrefab in AssetDatabase.GetAllAssetPaths().Where(path => path.StartsWith("Assets/") && path.EndsWith(".asset"))) foreach (var pathToPrefab in AssetDatabase.GetAllAssetPaths().Where(path => path.StartsWith("Assets/") && path.EndsWith(".asset")))
{ {
var scriptableObject = AssetDatabase.LoadAssetAtPath<ScriptableObject>(pathToPrefab); var scriptableObject = AssetDatabase.LoadAssetAtPath<ScriptableObject>(pathToPrefab);
var unityObjectData = new UnityObjectData(scriptableObject, pathToPrefab);
if (SerializationUtility.HasManagedReferencesWithMissingTypes(scriptableObject) == false) if (SerializationUtility.HasManagedReferencesWithMissingTypes(scriptableObject) == false) { continue; }
{
continue;
}
foreach (var missingType in SerializationUtility.GetManagedReferencesWithMissingTypes(scriptableObject)) var missings = SerializationUtility.GetManagedReferencesWithMissingTypes(scriptableObject);
{ list.Add(new Record(unityObjectData, missings));
var prefabObject = new UnityObjectData(scriptableObject, pathToPrefab);
AddMissingType(missingType, prefabObject);
}
} }
} }
private void CollectByScenes() private void CollectByScenes(List<Record> list)
{ {
try try
{ {
foreach (var scene in GetAllScenesInAssets()) foreach (var scene in GetAllScenesInAssets())
{ {
var unityObjectData = new SceneObjectData(scene);
var gameObjects = scene.GetRootGameObjects(); var gameObjects = scene.GetRootGameObjects();
foreach (var objectOnScene in gameObjects) foreach (var objectOnScene in gameObjects)
{ {
foreach (var monoBehaviour in objectOnScene.GetComponentsInChildren<MonoBehaviour>()) foreach (var monoBehaviour in objectOnScene.GetComponentsInChildren<MonoBehaviour>())
{ {
if (SerializationUtility.HasManagedReferencesWithMissingTypes(monoBehaviour) == false) if (SerializationUtility.HasManagedReferencesWithMissingTypes(monoBehaviour) == false) { continue; }
{
continue;
}
foreach (var missingType in SerializationUtility.GetManagedReferencesWithMissingTypes(monoBehaviour)) var missings = SerializationUtility.GetManagedReferencesWithMissingTypes(monoBehaviour);
{ list.Add(new Record(unityObjectData, missings));
var sceneObject = new SceneObjectData(scene);
AddMissingType(missingType, sceneObject);
}
} }
} }
} }
} }
catch (System.Exception e) catch (System.Exception e)
{ {
Debug.LogException(e); Debug.LogException(e);
} }
// SerializationUtility.
} }
#endregion #endregion
@ -164,19 +164,20 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
} }
} }
private void AddMissingType(ManagedReferenceMissingType missingType, UnityObjectDataBase unityObject) //private void AddMissingType(ManagedReferenceMissingType missingType, UnityObjectDataBase unityObject)
{ //{
var typeData = new TypeData(missingType); // var typeData = new TypeData(missingType);
var missingTypeData = new MissingTypeData(missingType, unityObject); // var missingTypeData = new MissingTypeData(missingType, unityObject);
if (_missingTypes.TryGetValue(typeData, out var containerMissingTypes) == false) // if (_manualRepairedMissingRefs.TryGetValue(typeData, out var containerMissingTypes) == false)
{ // {
containerMissingTypes = new ContainerMissingTypes(typeData); // containerMissingTypes = new ContainerMissingRefs(typeData);
_missingTypes.Add(typeData, containerMissingTypes); // _manualRepairedMissingRefs.Add(typeData, containerMissingTypes);
} // }
//
containerMissingTypes.ManagedReferencesMissingTypeDatas.Add(missingTypeData); // containerMissingTypes.ManagedReferencesMissingTypeDatas.Add(missingTypeData);
} //}
#endregion #endregion
} }
} }
#endif

View File

@ -6,7 +6,7 @@ using UnityEngine;
namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
{ {
internal static class FileRepaireUtility internal static class RepaireFileUtility
{ {
private const string REFLINE_PATTERN = "- rid:"; private const string REFLINE_PATTERN = "- rid:";
public static void Replace(string[] fileLines, string oldTypeData, string newTypeData) public static void Replace(string[] fileLines, string oldTypeData, string newTypeData)
@ -19,6 +19,17 @@ namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
} }
} }
} }
public static int NextRefLine(string[] fileLines, int startIndex)
{
for (int i = startIndex; i < fileLines.Length; i++)
{
if (fileLines[i].Contains(REFLINE_PATTERN))
{
return ++i;
}
}
return -1;
}
public static string GenerateReplacedLine(TypeData typeData) public static string GenerateReplacedLine(TypeData typeData)
{ {
return $"type: {{class: {typeData.ClassName}, ns: {typeData.NamespaceName}, asm: {typeData.AssemblyName}}}"; return $"type: {{class: {typeData.ClassName}, ns: {typeData.NamespaceName}, asm: {typeData.AssemblyName}}}";

View File

@ -4,15 +4,17 @@ using System.Collections.Generic;
namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors namespace DCFApixels.DragonECS.Unity.RefRepairer.Editors
{ {
internal class ContainerMissingTypes internal class ContainerMissingRefs
{ {
public readonly TypeData TypeData; public readonly TypeData TypeData;
public readonly string ReplacedLine; public readonly string ReplacedLine;
public readonly List<MissingTypeData> ManagedReferencesMissingTypeDatas = new List<MissingTypeData>(); public readonly List<MissingTypeData> ManagedReferencesMissingTypeDatas = new List<MissingTypeData>(4);
public ContainerMissingTypes(TypeData typeData) public readonly bool IsHasMetaIDRegistry;
public ContainerMissingRefs(TypeData typeData)
{ {
TypeData = typeData; TypeData = typeData;
ReplacedLine = FileRepaireUtility.GenerateReplacedLine(typeData); ReplacedLine = RepaireFileUtility.GenerateReplacedLine(typeData);
IsHasMetaIDRegistry = MetaIDRegistry.instance.TryGetMetaID(TypeData, out _);
} }
} }
} }