From ecf1f4b4c42546045247ad8d88103cdf63905d1b Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 29 Sep 2024 15:59:14 +0800 Subject: [PATCH] stash --- src/DragonDocs/Editors/DragonDocsWindow.cs | 5 +- src/Internal/ArrayUtility.cs | 64 +++++ src/Internal/Editor/UnityEditorUtility.cs | 14 +- src/Internal/ReflectionExtensions.cs | 3 + src/RefRepairer.meta | 8 + src/RefRepairer/Editor.meta | 8 + src/RefRepairer/Editor/RefRepairerWindow.cs | 54 ++++ .../Editor/RefRepairerWindow.cs.meta | 11 + src/RefRepairer/MetaIDRegistry.cs | 173 ++++++++++++ src/RefRepairer/RefRepaireUtility.cs | 257 ++++++++++++++++++ src/RefRepairer/RefRepaireUtility.cs.meta | 11 + src/RefRepairer/RepairerFile.cs | 75 +++++ src/RefRepairer/RepairerFile.cs.meta | 11 + .../Editor/EntityTemplateEditor.cs | 2 +- .../Templates/ComponentTemplateBase.cs | 16 +- 15 files changed, 688 insertions(+), 24 deletions(-) create mode 100644 src/Internal/ArrayUtility.cs create mode 100644 src/RefRepairer.meta create mode 100644 src/RefRepairer/Editor.meta create mode 100644 src/RefRepairer/Editor/RefRepairerWindow.cs create mode 100644 src/RefRepairer/Editor/RefRepairerWindow.cs.meta create mode 100644 src/RefRepairer/MetaIDRegistry.cs create mode 100644 src/RefRepairer/RefRepaireUtility.cs create mode 100644 src/RefRepairer/RefRepaireUtility.cs.meta create mode 100644 src/RefRepairer/RepairerFile.cs create mode 100644 src/RefRepairer/RepairerFile.cs.meta diff --git a/src/DragonDocs/Editors/DragonDocsWindow.cs b/src/DragonDocs/Editors/DragonDocsWindow.cs index 9635b3e..8dae1de 100644 --- a/src/DragonDocs/Editors/DragonDocsWindow.cs +++ b/src/DragonDocs/Editors/DragonDocsWindow.cs @@ -8,11 +8,12 @@ namespace DCFApixels.DragonECS.Unity.Docs.Editors { internal class DragonDocsWindow : EditorWindow { - [MenuItem("Tools/" + EcsConsts.FRAMEWORK_NAME + "/Documentation")] + public const string TITLE = "Documentation"; + [MenuItem("Tools/" + EcsConsts.FRAMEWORK_NAME + "/" + TITLE)] static void Open() { var wnd = GetWindow(); - wnd.titleContent = new GUIContent($"{EcsConsts.FRAMEWORK_NAME} Documentation"); + wnd.titleContent = new GUIContent(TITLE); wnd.minSize = new Vector2(100f, 120f); wnd.Show(); } diff --git a/src/Internal/ArrayUtility.cs b/src/Internal/ArrayUtility.cs new file mode 100644 index 0000000..43cbe92 --- /dev/null +++ b/src/Internal/ArrayUtility.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace DCFApixels.DragonECS.Unity.Internal +{ + internal interface ILinkedNext + { + int Next { get; } + } + internal readonly struct LinkedListIterator : IEnumerable + where T : ILinkedNext + { + public readonly T[] Array; + public readonly int Count; + public readonly int StartIndex; + public LinkedListIterator(T[] array, int count, int startIndex) + { + Array = array; + Count = count; + StartIndex = startIndex; + } + public Enumerator GetEnumerator() + { + return new Enumerator(Array, Count, StartIndex); + } + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + public struct Enumerator : IEnumerator + { + private readonly T[] _array; + private readonly int _count; + private int _index; + private int _counter; + public Enumerator(T[] array, int count, int index) + { + _array = array; + _count = count; + _index = index; + _counter = 0; + } + public ref T Current + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return ref _array[_index]; } + } + T IEnumerator.Current { get { return _array[_index]; } } + object IEnumerator.Current { get { return Current; } } + public bool MoveNext() + { + if (++_counter > _count) { return false; } + if (_counter > 1) + { + _index = _array[_index].Next; + } + return true; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IDisposable.Dispose() { } + void IEnumerator.Reset() { throw new NotSupportedException(); } + } + } +} \ No newline at end of file diff --git a/src/Internal/Editor/UnityEditorUtility.cs b/src/Internal/Editor/UnityEditorUtility.cs index 7697571..3fb9793 100644 --- a/src/Internal/Editor/UnityEditorUtility.cs +++ b/src/Internal/Editor/UnityEditorUtility.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; -using UnityEditor; using UnityEngine; using UnityObject = UnityEngine.Object; @@ -104,6 +103,8 @@ namespace DCFApixels.DragonECS.Unity.Editors #if UNITY_EDITOR namespace DCFApixels.DragonECS.Unity.Editors { + using UnityEditor; + [InitializeOnLoad] internal static partial class UnityEditorUtility { @@ -111,8 +112,7 @@ namespace DCFApixels.DragonECS.Unity.Editors { colorBoxeStyles = new SparseArray(); - #region InitSerializableTypes - List types = new List(); + List serializableTypes = new List(); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { var targetTypes = assembly.GetTypes().Where(type => @@ -120,18 +120,20 @@ namespace DCFApixels.DragonECS.Unity.Editors type.IsSubclassOf(typeof(UnityObject)) == false && type.GetCustomAttribute() != null); - types.AddRange(targetTypes); + serializableTypes.AddRange(targetTypes); } - _serializableTypes = types.ToArray(); + _serializableTypes = serializableTypes.ToArray(); + _serializableTypeWithMetaIDMetas = serializableTypes.Where(type => TypeMeta.IsHasMetaID(type)).Select(type => type.GetMeta()).ToArray(); //Array.Sort(_serializableTypes, (a, b) => string.Compare(a.AssemblyQualifiedName, b.AssemblyQualifiedName, StringComparison.Ordinal)); //_noHiddenSerializableTypes = _serializableTypes.Where(o => { // var atr = o.GetCustomAttribute(); // return atr != null && atr.Tags.Contains(MetaTags.HIDDEN); //}).ToArray(); - #endregion } + internal static readonly Type[] _serializableTypes; + internal static readonly TypeMeta[] _serializableTypeWithMetaIDMetas; //private static Type[] _noHiddenSerializableTypes; private static SparseArray colorBoxeStyles = new SparseArray(); diff --git a/src/Internal/ReflectionExtensions.cs b/src/Internal/ReflectionExtensions.cs index dfd0800..074469d 100644 --- a/src/Internal/ReflectionExtensions.cs +++ b/src/Internal/ReflectionExtensions.cs @@ -1,16 +1,19 @@ #if UNITY_EDITOR using System; using System.Reflection; +using System.Runtime.CompilerServices; namespace DCFApixels.DragonECS.Unity.Internal { internal static class ReflectionExtensions { + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetAttribute(this MemberInfo self, out T attrbiute) where T : Attribute { attrbiute = self.GetCustomAttribute(); return attrbiute != null; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasAttribute(this MemberInfo self) where T : Attribute { return self.GetCustomAttribute() != null; diff --git a/src/RefRepairer.meta b/src/RefRepairer.meta new file mode 100644 index 0000000..3350741 --- /dev/null +++ b/src/RefRepairer.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3d2e79fd0957b6d43a3334b142c0cc72 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/RefRepairer/Editor.meta b/src/RefRepairer/Editor.meta new file mode 100644 index 0000000..46112af --- /dev/null +++ b/src/RefRepairer/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c4c9608eab407004dba648302e06974b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/RefRepairer/Editor/RefRepairerWindow.cs b/src/RefRepairer/Editor/RefRepairerWindow.cs new file mode 100644 index 0000000..c942ece --- /dev/null +++ b/src/RefRepairer/Editor/RefRepairerWindow.cs @@ -0,0 +1,54 @@ +#if UNITY_EDITOR +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + internal class RefRepairerWindow : EditorWindow + { + public const string TITLE = "Reference Repairer"; + [MenuItem("Tools/" + EcsConsts.FRAMEWORK_NAME + "/" + TITLE)] + static void Open() + { + var wnd = GetWindow(); + wnd.titleContent = new GUIContent(TITLE); + wnd.minSize = new Vector2(100f, 120f); + wnd.Show(); + } + + private List _missingTypes; + //private readonly CollectorMissingTypes _collectorMissingTypes = new CollectorMissingTypes(); + + private bool TryInit() + { + var allCurrentDirtyScenes = EditorSceneManager + .GetSceneManagerSetup() + .Where(sceneSetup => sceneSetup.isLoaded) + .Select(sceneSetup => EditorSceneManager.GetSceneByPath(sceneSetup.path)) + .Where(scene => scene.isDirty) + .ToArray(); + + if (allCurrentDirtyScenes.Length != 0) + { + bool result = EditorUtility.DisplayDialog( + "Current active scene(s) is dirty", + "Please save all active scenes as they may be overwritten", + "Save active scene and Continue", + "Cancel update" + ); + if (result == false) + return false; + + foreach (var dirtyScene in allCurrentDirtyScenes) + EditorSceneManager.SaveScene(dirtyScene); + } + + //_missingTypes = _collectorMissingTypes.Collect(); + return true; + } + } +} +#endif \ No newline at end of file diff --git a/src/RefRepairer/Editor/RefRepairerWindow.cs.meta b/src/RefRepairer/Editor/RefRepairerWindow.cs.meta new file mode 100644 index 0000000..8de59f5 --- /dev/null +++ b/src/RefRepairer/Editor/RefRepairerWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a7d6a916b19cda418d5b119c0b02804 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/RefRepairer/MetaIDRegistry.cs b/src/RefRepairer/MetaIDRegistry.cs new file mode 100644 index 0000000..d6b9d22 --- /dev/null +++ b/src/RefRepairer/MetaIDRegistry.cs @@ -0,0 +1,173 @@ +#if UNITY_EDITOR +using DCFApixels.DragonECS.Unity.Internal; +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using UnityEditor; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + [FilePath(EcsUnityConsts.LOCAL_CACHE_FOLDER + "/" + nameof(MetaIDRegistry) + ".prefs", FilePathAttribute.Location.ProjectFolder)] + internal class MetaIDRegistry : ScriptableSingleton, ISerializationCallbackReceiver + { + [SerializeField] + private TypeDataList[] _typeDataLists; + [SerializeField] + private int _typeDataListsCount = 0; + [SerializeField] + private TypeDataNode[] _typeDataNodes; + [SerializeField] + private int _typeDataNodesCount = 0; + #region [SerializeField] + private struct Pair + { + public string metaID; + public int listIndex; + public Pair(string metaID, int listIndex) + { + this.metaID = metaID; + this.listIndex = listIndex; + } + } + private Pair[] _metaIDListIndexPairsSerializable; + #endregion + private Dictionary _metaIDListIndexPairs = new Dictionary(); + + + + #region Update + private void Update() + { + var typeMetas = UnityEditorUtility._serializableTypeWithMetaIDMetas; + bool isChanged = false; + + for (int i = 0; i < _typeDataListsCount; i++) + { + _typeDataLists[i].containsFlag = false; + } + + foreach (var meta in typeMetas) + { + var type = meta.Type; + + var name = type.Name; + var nameSpace = type.Namespace; + var assembly = type.Assembly.FullName; + + if (_metaIDListIndexPairs.TryGetValue(meta.MetaID, out int listIndex) == false) + { + if (_typeDataLists.Length <= _typeDataListsCount) + { + Array.Resize(ref _typeDataLists, _typeDataLists.Length << 1); + } + listIndex = _typeDataListsCount++; + _metaIDListIndexPairs.Add(meta.MetaID, listIndex); + isChanged = true; + } + + ref var listRef = ref _typeDataLists[listIndex]; + listRef.containsFlag = true; + if (listRef.count > 0 && _typeDataNodes[listRef.startNode].EqualsWith(name, nameSpace, assembly)) + { + continue; + } + + if (_typeDataNodes.Length <= _typeDataNodesCount) + { + Array.Resize(ref _typeDataNodes, _typeDataNodes.Length << 1); + } + int nodeIndex = _typeDataNodesCount++; + ref var nodeRef = ref _typeDataNodes[nodeIndex]; + isChanged = true; + + nodeRef = new TypeDataNode(name, nameSpace, assembly); + nodeRef.next = listRef.startNode; + listRef.startNode = listIndex; + listRef.count++; + } + + for (int i = 0; i < _typeDataListsCount; i++) + { + ref var list = ref _typeDataLists[i]; + if (list.containsFlag == false) + { + _metaIDListIndexPairs.Remove(); + } + } + + if (isChanged) + { + EditorUtility.SetDirty(this); + } + } + #endregion + + #region ISerializationCallbackReceiver + void ISerializationCallbackReceiver.OnAfterDeserialize() + { + _metaIDListIndexPairs.Clear(); + if (_typeDataNodes == null) + { + _typeDataLists = new TypeDataList[256]; + _typeDataListsCount = 0; + _typeDataNodes = new TypeDataNode[256]; + _typeDataNodesCount = 0; + } + else + { + foreach (var pair in _metaIDListIndexPairsSerializable) + { + _metaIDListIndexPairs[pair.metaID] = pair.listIndex; + } + } + Update(); + } + void ISerializationCallbackReceiver.OnBeforeSerialize() + { + int i = 0; + _metaIDListIndexPairsSerializable = new Pair[_metaIDListIndexPairs.Count]; + foreach (var pair in _metaIDListIndexPairs) + { + _metaIDListIndexPairsSerializable[i++] = new Pair(pair.Key, pair.Value); + } + } + #endregion + + #region Utils + [Serializable] + public struct TypeDataList + { + public string metaID_key; + public bool containsFlag; + public int startNode; + public int count; + } + [Serializable] + public struct TypeDataNode : ILinkedNext + { + public readonly string Name; + public readonly string Namespace; + public readonly string Assembly; + public int next; + + public bool EqualsWith(string name, string nameSpace, string assembly) + { + return name == Name && nameSpace == Namespace && assembly == Assembly; + } + public TypeDataNode(string name, string nameSpace, string assembly) : this() + { + Name = name; + Namespace = nameSpace; + Assembly = assembly; + } + int ILinkedNext.Next + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return next; } + } + } + #endregion + } +} +#endif \ No newline at end of file diff --git a/src/RefRepairer/RefRepaireUtility.cs b/src/RefRepairer/RefRepaireUtility.cs new file mode 100644 index 0000000..8ab0436 --- /dev/null +++ b/src/RefRepairer/RefRepaireUtility.cs @@ -0,0 +1,257 @@ +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityObject = UnityEngine.Object; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + public static class UnityObjectExtensions + { + public static int GetLocalIdentifierInFile(this UnityObject unityObject) + { + PropertyInfo inspectorModeInfo = typeof(SerializedObject).GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance); + SerializedObject serializedObject = new SerializedObject(unityObject); + inspectorModeInfo.SetValue(serializedObject, InspectorMode.Debug, null); + SerializedProperty localIdProp = serializedObject.FindProperty("m_LocalIdentfierInFile"); + return localIdProp.intValue; + } + } + + internal class RefRepaireUtility + { + private readonly Dictionary _missingTypes = new Dictionary(); + + + #region Collect + public List Collect() + { + _missingTypes.Clear(); + + CollectByPrefabs(); + CollectByScriptableObjects(); + CollectByScenes(); + + List result = new List(_missingTypes.Select((typeAndContainer) => typeAndContainer.Value)); + _missingTypes.Clear(); + return result; + } + private void CollectByPrefabs() + { + Scene previewScene = EditorSceneManager.NewPreviewScene(); + + foreach (var pathToPrefab in AssetDatabase.GetAllAssetPaths().Where(path => path.StartsWith("Assets/") && path.EndsWith(".prefab"))) + { + var prefab = AssetDatabase.LoadAssetAtPath(pathToPrefab); + PrefabUtility.LoadPrefabContentsIntoPreviewScene(pathToPrefab, previewScene); + var copyPrefab = previewScene.GetRootGameObjects()[0]; + + var componentsPrefab = prefab.GetComponentsInChildren(); + var componentsCopyPrefab = copyPrefab.GetComponentsInChildren(); + + for (int i = 0; i < componentsCopyPrefab.Length; ++i) + { + var monoBehaviour = componentsCopyPrefab[i]; + if (SerializationUtility.HasManagedReferencesWithMissingTypes(monoBehaviour) == false) + { + continue; + } + + foreach (var missingType in SerializationUtility.GetManagedReferencesWithMissingTypes(monoBehaviour)) + { + var prefabObject = new UnityObjectData(componentsPrefab[i].gameObject, pathToPrefab); + + AddMissingType(missingType, prefabObject); + } + } + + UnityObject.DestroyImmediate(copyPrefab); + } + + EditorSceneManager.ClosePreviewScene(previewScene); + } + private void CollectByScriptableObjects() + { + foreach (var pathToPrefab in AssetDatabase.GetAllAssetPaths().Where(path => path.StartsWith("Assets/") && path.EndsWith(".asset"))) + { + var scriptableObject = AssetDatabase.LoadAssetAtPath(pathToPrefab); + + if (SerializationUtility.HasManagedReferencesWithMissingTypes(scriptableObject) == false) + { + continue; + } + + foreach (var missingType in SerializationUtility.GetManagedReferencesWithMissingTypes(scriptableObject)) + { + var prefabObject = new UnityObjectData(scriptableObject, pathToPrefab); + AddMissingType(missingType, prefabObject); + } + } + } + private void CollectByScenes() + { + try + { + foreach (var scene in GetAllScenesInAssets()) + { + var gameObjects = scene.GetRootGameObjects(); + + foreach (var objectOnScene in gameObjects) + { + foreach (var monoBehaviour in objectOnScene.GetComponentsInChildren()) + { + if (SerializationUtility.HasManagedReferencesWithMissingTypes(monoBehaviour) == false) + { + continue; + } + + foreach (var missingType in SerializationUtility.GetManagedReferencesWithMissingTypes(monoBehaviour)) + { + var sceneObject = new SceneObjectData(scene); + AddMissingType(missingType, sceneObject); + } + } + } + } + } + catch (System.Exception e) + { + + Debug.LogException(e); + } + + + + // SerializationUtility. + } + #endregion + + #region Utils + private static IEnumerable GetAllScenesInAssets() + { + var oldScenesSetup = EditorSceneManager.GetSceneManagerSetup(); + + (bool isHasSelected, string scenePath, int identifierInFile) oldSelectedObject = default; + GameObject activeGameObject = Selection.activeGameObject; + if (activeGameObject != null) + { + oldSelectedObject.isHasSelected = true; + oldSelectedObject.scenePath = activeGameObject.scene.path; + oldSelectedObject.identifierInFile = activeGameObject.GetLocalIdentifierInFile(); + } + + foreach (var pathToScene in AssetDatabase.GetAllAssetPaths().Where(path => path.StartsWith("Assets/") && path.EndsWith(".unity"))) + { + Scene scene = EditorSceneManager.OpenScene(pathToScene, OpenSceneMode.Single); + yield return scene; + } + + EditorSceneManager.RestoreSceneManagerSetup(oldScenesSetup); + + if (oldSelectedObject.isHasSelected) + { + Selection.activeGameObject = SceneManager.GetSceneByPath(oldSelectedObject.scenePath) + .GetRootGameObjects() + .FirstOrDefault(gameObject => gameObject.GetLocalIdentifierInFile() == oldSelectedObject.identifierInFile); + } + else + { + Selection.activeGameObject = null; + } + } + + private void AddMissingType(ManagedReferenceMissingType missingType, BaseUnityObjectData unityObject) + { + var typeData = new TypeData(missingType); + var missingTypeData = new MissingTypeData(missingType, unityObject); + if (_missingTypes.TryGetValue(typeData, out var containerMissingTypes) == false) + { + containerMissingTypes = new ContainerMissingTypes(typeData); + _missingTypes.Add(typeData, containerMissingTypes); + } + + containerMissingTypes.Add(missingTypeData); + } + #endregion + + } + + + + + + public class ContainerMissingTypes + { + public readonly TypeData TypeData; + + private readonly List _managedReferencesMissingTypeDatas = new List(); + + public IReadOnlyCollection ManagedReferencesMissingTypeDatas => _managedReferencesMissingTypeDatas; + + public ContainerMissingTypes(TypeData typeData) + { + TypeData = typeData; + } + + public void Add(MissingTypeData missingTypeData) => _managedReferencesMissingTypeDatas.Add(missingTypeData); + + public void Remove(MissingTypeData missingTypeData) => _managedReferencesMissingTypeDatas.Remove(missingTypeData); + + public void RemoveAt(int index) => _managedReferencesMissingTypeDatas.RemoveAt(index); + } + public struct MissingTypeData + { + public readonly ManagedReferenceMissingType Data; + public readonly BaseUnityObjectData UnityObject; + + public MissingTypeData(ManagedReferenceMissingType missingType, BaseUnityObjectData unityObject) + { + Data = missingType; + UnityObject = unityObject; + } + } + public struct TypeData + { + public readonly string AssemblyName; + public readonly string NamespaceName; + public readonly string ClassName; + + public TypeData(ManagedReferenceMissingType missingType) + { + AssemblyName = missingType.assemblyName; + NamespaceName = missingType.namespaceName; + ClassName = missingType.className; + } + } + public abstract class BaseUnityObjectData + { + public string LocalAssetPath => AssetDatabase.GUIDToAssetPath(AssetGuid); + public abstract GUID AssetGuid { get; } + } + public class SceneObjectData : BaseUnityObjectData + { + public readonly string SceneName; + + public override GUID AssetGuid { get; } + + public SceneObjectData(Scene scene) + { + SceneName = scene.name; + AssetGuid = AssetDatabase.GUIDFromAssetPath(scene.path); + } + } + public class UnityObjectData : BaseUnityObjectData + { + public readonly UnityObject UnityObject; + public override GUID AssetGuid { get; } + + public UnityObjectData(UnityObject unityObject, string pathToPrefab) + { + UnityObject = unityObject; + AssetGuid = AssetDatabase.GUIDFromAssetPath(pathToPrefab); + } + } +} \ No newline at end of file diff --git a/src/RefRepairer/RefRepaireUtility.cs.meta b/src/RefRepairer/RefRepaireUtility.cs.meta new file mode 100644 index 0000000..2cc5aad --- /dev/null +++ b/src/RefRepairer/RefRepaireUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 784d02aa2b8675846ae22da855eca93f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/RefRepairer/RepairerFile.cs b/src/RefRepairer/RepairerFile.cs new file mode 100644 index 0000000..7f81db4 --- /dev/null +++ b/src/RefRepairer/RepairerFile.cs @@ -0,0 +1,75 @@ +using System; +using System.IO; +using UnityEditor; +using UnityEngine; + +namespace DCFApixels.DragonECS.Unity.Editors +{ + public static class FileRepaireUtility + { + private const string REFLINE_PATTERN = "- rid:"; + public static void Replace(string filePath) + { + + } + } + public class RepairerFile + { + private readonly Type _type; + private readonly string[] _fileLines; + + private string _currentLine; + private string _nextLine; + + private int _currentIndex; + + private readonly string _path; + private readonly string _localAssetPath; + + public RepairerFile(Type type, string localAssetPath) + { + _type = type; + _localAssetPath = localAssetPath; + + _path = $"{Application.dataPath.Replace("/Assets", "")}/{localAssetPath}"; + _fileLines = File.ReadAllLines(_path); + } + + public delegate bool GetterMissingTypeData(out MissingTypeData missingType); + + public void Repair(Func callbackForNextLine) + { + for (int i = 0; i < _fileLines.Length - 1; ++i) + { + _currentIndex = i; + + _currentLine = _fileLines[i]; + _nextLine = _fileLines[i + 1]; + + if (callbackForNextLine.Invoke()) + break; + } + + File.WriteAllLines(_path, _fileLines); + + AssetDatabase.ImportAsset(_localAssetPath, ImportAssetOptions.ForceUpdate); + AssetDatabase.Refresh(); + } + + public bool CheckNeedLineAndReplacedIt(ManagedReferenceMissingType missingType) + { + string rid = $"rid: {missingType.referenceId}"; + string oldTypeData = $"type: {{class: {missingType.className}, ns: {missingType.namespaceName}, asm: {missingType.assemblyName}}}"; + + if (_currentLine.Contains(rid) && _nextLine.Contains(oldTypeData)) + { + string newTypeData = $"type: {{class: {_type.Name}, ns: {_type.Namespace}, asm: {_type.Assembly.GetName().Name}}}"; + _fileLines[_currentIndex + 1] = _nextLine.Replace(oldTypeData, newTypeData); + + return true; + } + + return false; + } + } +} diff --git a/src/RefRepairer/RepairerFile.cs.meta b/src/RefRepairer/RepairerFile.cs.meta new file mode 100644 index 0000000..6e808f5 --- /dev/null +++ b/src/RefRepairer/RepairerFile.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd87f9f7b02388741a94e1e36f1a46ac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Templates/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/Templates/EntityTemplate/Editor/EntityTemplateEditor.cs index ad9a74e..cf581e5 100644 --- a/src/Templates/EntityTemplate/Editor/EntityTemplateEditor.cs +++ b/src/Templates/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -18,7 +18,7 @@ namespace DCFApixels.DragonECS.Unity.Editors private ReorderableList _reorderableComponentsList; #region Init - protected override bool IsInit => _componentDropDown != null; + protected override bool IsInit { get { return _componentDropDown != null; } } protected override void OnInit() { _componentDropDown = new ComponentDropDown(); diff --git a/src/Templates/EntityTemplate/Templates/ComponentTemplateBase.cs b/src/Templates/EntityTemplate/Templates/ComponentTemplateBase.cs index 76f92c9..c1cb9e0 100644 --- a/src/Templates/EntityTemplate/Templates/ComponentTemplateBase.cs +++ b/src/Templates/EntityTemplate/Templates/ComponentTemplateBase.cs @@ -127,23 +127,9 @@ namespace DCFApixels.DragonECS.Unity.Editors static ComponentTemplateTypeCache() { - List types = new List(); Type interfaceType = typeof(IComponentTemplate); - foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) - { - var targetTypes = assembly.GetTypes().Where(type => !type.IsGenericType && !(type.IsAbstract || type.IsInterface) /*&& type.GetCustomAttribute() != null*/); - types.AddRange(targetTypes.Where(type => interfaceType.IsAssignableFrom(type))); - - foreach (var t in targetTypes) - { - if (t.IsSubclassOf(typeof(ComponentTemplateBase<>))) - { - types.Add(t); - } - } - } - _types = types.ToArray(); + _types = UnityEditorUtility._serializableTypes.Where(type => interfaceType.IsAssignableFrom(type)).ToArray(); foreach (var type in _types) { EcsDebugUtility.GetTypeMeta(type);