#if UNITY_EDITOR using System; using System.Collections.Generic; using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; namespace WingmanInspector { public class WingmanPersistentData : ScriptableObject { public readonly WingmanClipboard Clipboard = new WingmanClipboard(); [SerializeField] private List indexLookUp = new List(); [SerializeField] private List searchFields = new List(); [SerializeField] private List selectedCompIds = new List(); [SerializeField] private List lockedInspectorRestoreStates = new List(); [Serializable] private class SelectionData { public List selectionList = new List(); } [Serializable] private class LockedInspectorRestoreState { public int inspectorInstanceId; public Object inspectingObject; } public List SelectedCompIds(Object obj) { if (GetObjectIndex(obj, out int index)) { return selectedCompIds[index].selectionList; } return null; } public string SearchString(Object obj) { if (GetObjectIndex(obj, out int index)) { return searchFields[index]; } return string.Empty; } public void SetSearchString(Object obj, string str) { if (GetObjectIndex(obj, out int index)) { searchFields[index] = str; } } public void AddDataForContainer(Object obj) { int id = obj.GetInstanceID(); // BinarySerach returns index if found in list, or negative bitwise compliment of index if not found int index = indexLookUp.BinarySearch(id); if (index >= 0) return; index = ~index; // Turn negative bitwise compliment into insertion index indexLookUp.Insert(index, id); selectedCompIds.Insert(index, new SelectionData()); searchFields.Insert(index, string.Empty); } public void SetDataForLockedInspector(EditorWindow inspectorWindow, Object inspectingObject) { int entryIndex = -1; for (int i = 0; i < lockedInspectorRestoreStates.Count; i++) { if (lockedInspectorRestoreStates[i].inspectorInstanceId == inspectorWindow.GetInstanceID()) { entryIndex = i; break; } } if (entryIndex == -1) { LockedInspectorRestoreState newState = new LockedInspectorRestoreState(); newState.inspectorInstanceId = inspectorWindow.GetInstanceID(); newState.inspectingObject = inspectingObject; lockedInspectorRestoreStates.Add(newState); return; } lockedInspectorRestoreStates[entryIndex].inspectingObject = inspectingObject; } public Object GetRestoredObjectForInspectorWindow(EditorWindow inspectorWindow) { foreach (LockedInspectorRestoreState state in lockedInspectorRestoreStates) { if (state.inspectorInstanceId == inspectorWindow.GetInstanceID()) { return state.inspectingObject; } } return null; } public void ClearAllData() { indexLookUp.Clear(); selectedCompIds.Clear(); searchFields.Clear(); lockedInspectorRestoreStates.Clear(); AssetDatabase.SaveAssetIfDirty(this); } private bool GetObjectIndex(Object obj, out int index) { index = indexLookUp.BinarySearch(obj.GetInstanceID()); return index >= 0; } [CustomEditor(typeof(WingmanPersistentData))] private class Editor : UnityEditor.Editor { public override void OnInspectorGUI() { GUIStyle labelStyle = new(EditorStyles.label); labelStyle.wordWrap = true; EditorGUILayout.LabelField( $"Stores persistent data for {nameof(Wingman)} like selected components and search strings.\n\n" + "This data clears every time the editor is restarted.\n\n" + "This file can be safely ignored by version control.", labelStyle ); } } } } #endif