public void DrawInspectorGUI(ME.ECS.Entity entity, bool drawDefaultInspector = false) { var isMultiple = false; string output = string.Empty; if (this.targets.Length > 1) { foreach (var t in this.targets) { var str = t.ToString(); if (output != string.Empty && output != str) { isMultiple = true; } output = str; } } if (entity != ME.ECS.Entity.Empty) { GUILayoutExt.Box(2f, 2f, () => { EditorGUILayout.HelpBox(isMultiple == true ? "-" : this.target.ToString(), MessageType.Info); if (isMultiple == false) { GUILayoutExt.DrawEntitySelection(ME.ECS.Worlds.currentWorld, in entity, checkAlive: true); } }, UnityEngine.GUIStyle.none); GUILayoutExt.Separator(); } EditorGUILayout.BeginHorizontal(); UnityEngine.GUILayout.FlexibleSpace(); var style = new UnityEngine.GUIStyle(UnityEngine.GUI.skin.button); style.fontSize = 12; style.fixedWidth = 230; style.fixedHeight = 23; if (UnityEngine.GUILayout.Button("Refresh Data", style) == true) { var targets = this.targets; foreach (var target in targets) { ((IDoValidate)target).DoValidate(); UnityEditor.EditorUtility.SetDirty(target); } } UnityEngine.GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); if (drawDefaultInspector == true) { EditorGUILayout.Space(); this.DrawDefaultInspector(); } }
public override void OnInspectorGUI() { this.serializedObject.Update(); EditorGUILayout.PropertyField(this.editorComment); this.serializedObject.ApplyModifiedProperties(); base.OnInspectorGUI(); if (this.targets.Length == 1) { var target = (DataConfigTemplate)this.target; if (target.usedIn.Count > 0) { GUILayoutExt.Separator(6f); GUILayoutExt.DrawHeader("Used by Configs:"); GUILayoutExt.Separator(); var rect = new Rect(0f, 0f, EditorGUIUtility.currentViewWidth, 1000f); var style = new GUIStyle("AssetLabel Partial"); var buttonRects = EditorGUIUtility.GetFlowLayoutedRects(rect, style, 4f, 4f, target.usedIn.Select(x => { var config = x; if (config == null) { return(string.Empty); } return(config.name); }).ToList()); GUILayout.BeginHorizontal(); GUILayout.EndHorizontal(); var areaRect = GUILayoutUtility.GetLastRect(); for (int i = 0; i < buttonRects.Count; ++i) { areaRect.height = Mathf.Max(0f, buttonRects[i].yMax); } GUILayoutUtility.GetRect(areaRect.width, areaRect.height); GUI.BeginGroup(areaRect); for (int i = 0; i < target.usedIn.Count; ++i) { var config = target.usedIn[i]; if (config == null) { continue; } if (GUI.Button(buttonRects[i], config.name, style) == true) { EditorGUIUtility.PingObject(config); } } GUI.EndGroup(); } } }
bool IGUIEditorBase.OnDrawGUI() { var style = new UnityEngine.GUIStyle(UnityEngine.GUI.skin.label); style.richText = true; var dataCount = 0; foreach (System.Collections.DictionaryEntry ren in this.target.GetData()) { dataCount += ((ME.ECS.Collections.SortedList <long, HistoryEvent>)ren.Value).Count; } GUILayoutExt.Box(2f, 2f, () => { UnityEngine.GUILayout.Label("<b>Memory Usage:</b> " + ME.ECS.MathUtils.BytesCountToString(WorldEditor.current.stateSize * (this.target.GetCacheSize() / this.target.GetTicksPerState())), style); UnityEngine.GUILayout.Label("<b>Events:</b> " + dataCount.ToString(), style); UnityEngine.GUILayout.Label("<b>Events Added:</b> " + this.target.GetEventsAddedCount().ToString(), style); UnityEngine.GUILayout.Label("<b>Events Played:</b> " + this.target.GetEventsPlayedCount().ToString(), style); }); GUILayoutExt.Separator(); var val = this.syncTableFoldState; GUILayoutExt.FoldOut(ref val, "Sync Table", () => { const float padding = 2f; const float margin = 2f; const float col1 = 60f; const float col2 = 50f; const float col3 = 22f; const float cellHeight = 22f; var tableStyle = (GUIStyle)"Box"; GUILayout.BeginHorizontal(); { GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Tick", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.Width(col1), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Player", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.Width(col2), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Hash", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.ExpandWidth(true), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption(string.Empty, EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.Width(col3), GUILayout.Height(cellHeight)); } GUILayout.EndHorizontal(); var syncHashTable = this.target.GetSyncHashTable(); /*if (syncHashTable.ContainsKey(20) == false) syncHashTable.Add(20, new System.Collections.Generic.Dictionary<int, int>() { * { 100, 1234 } * }); * if (syncHashTable.ContainsKey(100) == false) syncHashTable.Add(100, new System.Collections.Generic.Dictionary<int, int>() { * { 100, 1902832914 }, * { 101, 1902832914 }, * { 102, 1902832915 }, * }); * if (syncHashTable.ContainsKey(2000) == false) syncHashTable.Add(2000, new System.Collections.Generic.Dictionary<int, int>() { * { 100, 2345 } * });*/ foreach (var item in syncHashTable) { var tick = item.Key; int localHash = 0; GUILayout.BeginHorizontal(); { GUILayoutExt.DataLabel(tick.ToString(), GUILayout.Width(col1)); } GUILayout.EndHorizontal(); var stateHashResult = 0; foreach (var kv in item.Value) { var hash = kv.Value; if (localHash != 0 && localHash != hash) { stateHashResult = -1; break; } else if (localHash != 0) { stateHashResult = 1; } localHash = hash; } foreach (var kv in item.Value) { var playerId = kv.Key; GUILayout.BeginHorizontal(); { GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.DataLabel(string.Empty); }, tableStyle, GUILayout.Width(col1), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.DataLabel(playerId.ToString()); }, tableStyle, GUILayout.Width(col2), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.DataLabel(kv.Value.ToString()); }, tableStyle, GUILayout.ExpandWidth(true), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (stateHashResult == 1) { using (new GUILayoutExt.GUIColorUsing(Color.green)) { GUILayout.Toggle(true, new GUIContent(string.Empty, $"Local hash synced with player #{playerId}."), StatesHistoryModuleEditor.syncBoxStyle); } } else if (stateHashResult == -1) { using (new GUILayoutExt.GUIColorUsing(Color.red)) { GUILayout.Toggle(true, new GUIContent(string.Empty, $"Local hash is not the same as player #{playerId} has, your server must resync that player."), StatesHistoryModuleEditor.syncBoxStyle); } } else { using (new GUILayoutExt.GUIColorUsing(Color.yellow)) { GUILayout.Toggle(false, new GUIContent(string.Empty, $"Local hash is not sync yet with player #{playerId}, current tick is less than remote."), StatesHistoryModuleEditor.syncBoxStyle); } } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); }, tableStyle, GUILayout.Width(col3), GUILayout.Height(cellHeight)); } GUILayout.EndHorizontal(); } } }); this.syncTableFoldState = val; GUILayoutExt.Separator(); val = this.statesHistoryFoldState; GUILayoutExt.FoldOut(ref val, "States History", () => { var padding = 2f; var margin = 2f; var col1 = 60f; var col2 = 70f; var cellHeight = 22f; var tableStyle = (GUIStyle)"Box"; UnityEngine.GUILayout.BeginHorizontal(); { if (UnityEngine.GUILayout.Button("Entities", UnityEditor.EditorStyles.miniButtonLeft) == true) { var world = Worlds.currentWorld; this.PrintEntities(world.currentState); } if (UnityEngine.GUILayout.Button("Events", UnityEditor.EditorStyles.miniButtonMid) == true) { foreach (System.Collections.DictionaryEntry ren in this.target.GetData()) { var entry = (ME.ECS.Collections.SortedList <long, HistoryEvent>)ren.Value; for (int i = 0; i < entry.Count; ++i) { UnityEngine.Debug.Log(entry.GetByIndex(i).ToString()); } } } if (UnityEngine.GUILayout.Button("Reset State", UnityEditor.EditorStyles.miniButtonRight) == true) { this.target.RecalculateFromResetState(); } } UnityEngine.GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); { GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Tick", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.Width(col1), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Hash", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.ExpandWidth(true), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Actions", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.Width(col2), GUILayout.Height(cellHeight)); } GUILayout.EndHorizontal(); var dataStates = this.target.GetDataStates(); var entries = dataStates.GetEntries(); foreach (var entryData in entries) { var entry = entryData as ME.ECS.Network.IStatesHistoryEntry; var state = entry.GetData() as State; UnityEngine.GUILayout.BeginHorizontal(); { GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.DataLabel(entry.isEmpty == true ? "-" : state.tick.ToString()); }, tableStyle, GUILayout.Width(col1), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.DataLabel(entry.isEmpty == true ? "-" : state.GetHash().ToString()); }, tableStyle, GUILayout.ExpandWidth(true), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { EditorGUI.BeginDisabledGroup(entry.isEmpty == true); if (UnityEngine.GUILayout.Button("Entities") == true) { this.PrintEntities(state); } EditorGUI.EndDisabledGroup(); }, tableStyle, GUILayout.Width(col2), GUILayout.Height(cellHeight)); } UnityEngine.GUILayout.EndHorizontal(); } }); this.statesHistoryFoldState = val; GUILayoutExt.Separator(); GUILayoutExt.Separator(); val = this.eventsFoldState; GUILayoutExt.FoldOut(ref val, "Events Table", () => { const float padding = 2f; const float margin = 2f; const float col1 = 60f; const float col2 = 50f; const float cellHeight = 22f; var tableStyle = (GUIStyle)"Box"; GUILayout.BeginHorizontal(); { GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Tick", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.Width(col1), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Player", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.Width(col2), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Rpc ID", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.ExpandWidth(true), GUILayout.Height(cellHeight)); } GUILayout.EndHorizontal(); var events = this.target.GetEvents(); foreach (var item in events) { var tick = item.tick; GUILayout.BeginHorizontal(); { GUILayoutExt.DataLabel(tick.ToString(), GUILayout.Width(col1)); } GUILayout.EndHorizontal(); var playerId = item.order; GUILayout.BeginHorizontal(); { GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.DataLabel(tick.ToString()); }, tableStyle, GUILayout.Width(col1), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.DataLabel(playerId.ToString()); }, tableStyle, GUILayout.Width(col2), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.DataLabel(item.rpcId.ToString()); }, tableStyle, GUILayout.ExpandWidth(true), GUILayout.Height(cellHeight)); } GUILayout.EndHorizontal(); } }); this.eventsFoldState = val; return(false); }
public override void OnInspectorGUI() { var style = new GUIStyle(EditorStyles.toolbar); style.fixedHeight = 0f; style.stretchHeight = true; var backStyle = new GUIStyle(EditorStyles.label); backStyle.normal.background = Texture2D.whiteTexture; var dataConfig = (ME.ECS.DataConfigs.DataConfig) this.target; if (DataConfigEditor.worldEditors.TryGetValue(this.target, out var worldEditor) == false) { worldEditor = new WorldsViewerEditor.WorldEditor(); DataConfigEditor.worldEditors.Add(this.target, worldEditor); } GUILayoutExt.Padding(8f, () => { var usedComponents = new System.Collections.Generic.HashSet <System.Type>(); var kz = 0; var registries = dataConfig.structComponents; var sortedRegistries = new System.Collections.Generic.SortedDictionary <int, Registry>(new WorldsViewerEditor.DuplicateKeyComparer <int>()); for (int i = 0; i < registries.Length; ++i) { var registry = registries[i]; if (registry == null) { continue; } var component = registry; usedComponents.Add(component.GetType()); var editor = WorldsViewerEditor.GetEditor(component, out var order); if (editor != null) { sortedRegistries.Add(order, new Registry() { index = i, data = component }); } else { sortedRegistries.Add(0, new Registry() { index = i, data = component }); } } foreach (var registryKv in sortedRegistries) { var registry = registryKv.Value; var component = registry.data; var backColor = GUI.backgroundColor; GUI.backgroundColor = new Color(1f, 1f, 1f, kz++ % 2 == 0 ? 0f : 0.05f); GUILayout.BeginVertical(backStyle); { GUI.backgroundColor = backColor; var editor = WorldsViewerEditor.GetEditor(component); if (editor != null) { EditorGUI.BeginChangeCheck(); editor.OnDrawGUI(); if (EditorGUI.EndChangeCheck() == true) { component = editor.GetTarget <IStructComponent>(); dataConfig.structComponents[registry.index] = component; } } else { var componentName = component.GetType().Name; var fieldsCount = GUILayoutExt.GetFieldsCount(component); if (fieldsCount == 0) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.Toggle(componentName, true); EditorGUI.EndDisabledGroup(); } else if (fieldsCount == 1) { var changed = GUILayoutExt.DrawFields(worldEditor, component, componentName); if (changed == true) { dataConfig.structComponents[registry.index] = component; } } else { GUILayout.BeginHorizontal(); { GUILayout.Space(18f); GUILayout.BeginVertical(); { var key = "ME.ECS.WorldsViewerEditor.FoldoutTypes." + component.GetType().FullName; var foldout = EditorPrefs.GetBool(key, true); GUILayoutExt.FoldOut(ref foldout, componentName, () => { var changed = GUILayoutExt.DrawFields(worldEditor, component); if (changed == true) { dataConfig.structComponents[registry.index] = component; } }); EditorPrefs.SetBool(key, foldout); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } } } GUILayout.EndVertical(); GUILayoutExt.Separator(); } GUILayoutExt.DrawAddComponentMenu(usedComponents, (addType, isUsed) => { if (isUsed == true) { usedComponents.Remove(addType); for (int i = 0; i < dataConfig.structComponents.Length; ++i) { if (dataConfig.structComponents[i].GetType() == addType) { var list = dataConfig.structComponents.ToList(); list.RemoveAt(i); dataConfig.structComponents = list.ToArray(); dataConfig.OnScriptLoad(); break; } } } else { usedComponents.Add(addType); System.Array.Resize(ref dataConfig.structComponents, dataConfig.structComponents.Length + 1); dataConfig.structComponents[dataConfig.structComponents.Length - 1] = (IStructComponent)System.Activator.CreateInstance(addType); dataConfig.OnScriptLoad(); } }); }); GUILayoutExt.Padding(8f, () => { var usedComponents = new System.Collections.Generic.HashSet <System.Type>(); var kz = 0; var registries = dataConfig.components; var sortedRegistries = new System.Collections.Generic.SortedDictionary <int, RegistryComponent>(new WorldsViewerEditor.DuplicateKeyComparer <int>()); for (int i = 0; i < registries.Length; ++i) { var registry = registries[i]; if (registry == null) { continue; } var component = registry; usedComponents.Add(component.GetType()); var editor = WorldsViewerEditor.GetEditor(component, out var order); if (editor != null) { sortedRegistries.Add(order, new RegistryComponent() { index = i, data = component }); } else { sortedRegistries.Add(0, new RegistryComponent() { index = i, data = component }); } } foreach (var registryKv in sortedRegistries) { var registry = registryKv.Value; var component = registry.data; var backColor = GUI.backgroundColor; GUI.backgroundColor = new Color(1f, 1f, 1f, kz++ % 2 == 0 ? 0f : 0.05f); GUILayout.BeginVertical(backStyle); { GUI.backgroundColor = backColor; var editor = WorldsViewerEditor.GetEditor(component); if (editor != null) { EditorGUI.BeginChangeCheck(); editor.OnDrawGUI(); if (EditorGUI.EndChangeCheck() == true) { component = editor.GetTarget <IComponent>(); dataConfig.components[registry.index] = component; } } else { var componentName = component.GetType().Name; var fieldsCount = GUILayoutExt.GetFieldsCount(component); if (fieldsCount == 0) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.Toggle(componentName, true); EditorGUI.EndDisabledGroup(); } else if (fieldsCount == 1) { var changed = GUILayoutExt.DrawFields(worldEditor, component, componentName); if (changed == true) { dataConfig.components[registry.index] = component; } } else { GUILayout.BeginHorizontal(); { GUILayout.Space(18f); GUILayout.BeginVertical(); { var key = "ME.ECS.WorldsViewerEditor.FoldoutTypes." + component.GetType().FullName; var foldout = EditorPrefs.GetBool(key, true); GUILayoutExt.FoldOut(ref foldout, componentName, () => { var changed = GUILayoutExt.DrawFields(worldEditor, component); if (changed == true) { dataConfig.components[registry.index] = component; } }); EditorPrefs.SetBool(key, foldout); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } } } GUILayout.EndVertical(); GUILayoutExt.Separator(); } GUILayoutExt.DrawAddComponentMenu(usedComponents, (addType, isUsed) => { if (isUsed == true) { usedComponents.Remove(addType); for (int i = 0; i < dataConfig.components.Length; ++i) { if (dataConfig.components[i].GetType() == addType) { var list = dataConfig.components.ToList(); list.RemoveAt(i); dataConfig.components = list.ToArray(); dataConfig.OnScriptLoad(); break; } } } else { usedComponents.Add(addType); System.Array.Resize(ref dataConfig.components, dataConfig.components.Length + 1); dataConfig.components[dataConfig.components.Length - 1] = (IComponent)System.Activator.CreateInstance(addType); dataConfig.OnScriptLoad(); } }, drawRefComponents: true); }); }
private WorldEditor DrawWorlds() { WorldEditor selectedWorld = null; var style = EditorStyles.helpBox; this.scrollPosition = GUILayout.BeginScrollView(this.scrollPosition, style, GUILayout.ExpandHeight(true)); { if (this.worlds.Count == 0) { var centeredStyle = new GUIStyle(EditorStyles.centeredGreyMiniLabel); centeredStyle.stretchHeight = true; centeredStyle.richText = true; GUILayout.Label("This is runtime utility to view current running worlds.\nPress <b>Play</b> to start profiling.", centeredStyle); } else { foreach (var worldEditor in this.worlds) { var systems = worldEditor.GetSystems(); var modules = worldEditor.GetModules(); var entitiesStorage = worldEditor.GetEntitiesStorage(); var filters = worldEditor.GetFilters(); var world = worldEditor.world; GUILayoutExt.Padding(4f, () => { GUILayoutExt.FoldOut(ref worldEditor.foldout, worldEditor.ToString() + " (Hash: " + worldEditor.world.GetStateHash() + ")", () => { GUILayoutExt.Box(2f, 4f, () => { GUILayout.Label("Last Entity Id: " + worldEditor.world.GetLastEntityId().ToString()); GUILayout.Label("State Tick: " + worldEditor.world.GetStateTick().ToString()); GUILayout.Label("Tick: " + worldEditor.world.GetCurrentTick().ToString()); GUILayout.Label("Tick Time: " + worldEditor.world.GetTickTime().ToString() + "ms."); GUILayout.Label("Time: " + ME.ECS.MathUtils.SecondsToString(worldEditor.world.GetTimeSinceStart())); }); GUILayoutExt.FoldOut(ref worldEditor.foldoutSystems, "Systems (" + systems.Count.ToString() + ")", () => { var cellHeight = 25f; var padding = 2f; var margin = 1f; var col1 = 250f; var col2 = 50f; var col3 = 50f; var tableStyle = (GUIStyle)"Box"; var dataStyle = new GUIStyle(EditorStyles.label); GUILayoutExt.Padding(4f, () => { GUILayout.BeginHorizontal(); { GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Caption", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.Width(col1), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Logic", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.Width(col2), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Visual", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.Width(col3), GUILayout.Height(cellHeight)); } GUILayout.EndHorizontal(); foreach (var system in systems) { GUILayout.BeginHorizontal(); { GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TypeLabel(system.GetType()); }, tableStyle, GUILayout.Width(col1), GUILayout.Height(cellHeight)); } { // Logic GUILayoutExt.Box(padding, margin, () => { GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.FlexibleSpace(); var flag = world.GetSystemState(system); var state = (flag & ME.ECS.ModuleState.LogicInactive) == 0; if (this.ToggleMethod(worldEditor, system, "AdvanceTick", ref state) == true) { world.SetSystemState( system, state == false ? flag | ME.ECS.ModuleState.LogicInactive : flag & ~ME.ECS.ModuleState.LogicInactive); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); }, tableStyle, GUILayout.Width(col2), GUILayout.Height(cellHeight)); } { // Visual GUILayoutExt.Box(padding, margin, () => { GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.FlexibleSpace(); var flag = world.GetSystemState(system); var state = (flag & ME.ECS.ModuleState.VisualInactive) == 0; if (this.ToggleMethod(worldEditor, system, "Update", ref state) == true) { world.SetSystemState( system, state == false ? flag | ME.ECS.ModuleState.VisualInactive : flag & ~ME.ECS.ModuleState.VisualInactive); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); }, tableStyle, GUILayout.Width(col3), GUILayout.Height(cellHeight)); } GUILayout.EndHorizontal(); { GUILayoutExt.Box(padding, margin, () => { /*if (system is IGUIEditor systemEditor) { * * systemEditor.OnDrawGUI(); * * }*/ }, tableStyle, GUILayout.ExpandWidth(true)); GUILayout.Space(2f); } } }); }); GUILayoutExt.FoldOut(ref worldEditor.foldoutModules, "Modules (" + modules.Count.ToString() + ")", () => { var cellHeight = 25f; var padding = 2f; var margin = 1f; var col2 = 50f; var col3 = 50f; var tableStyle = (GUIStyle)"Box"; var dataStyle = new GUIStyle(EditorStyles.label); dataStyle.richText = true; dataStyle.wordWrap = true; GUILayoutExt.Padding(4f, () => { GUILayout.BeginHorizontal(); { GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Caption", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.ExpandWidth(true), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Logic", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.Width(col2), GUILayout.Height(cellHeight)); GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Visual", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.Width(col3), GUILayout.Height(cellHeight)); //GUILayoutExt.Box(2f, 1f, () => { GUILayoutExt.TableCaption("Info", EditorStyles.miniBoldLabel); }, tableStyle, // GUILayout.ExpandWidth(true), GUILayout.Height(cellHeight)); } GUILayout.EndHorizontal(); foreach (var module in modules) { GUILayout.BeginHorizontal(); { GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TypeLabel(module.GetType()); }, tableStyle, GUILayout.ExpandWidth(true), GUILayout.Height(cellHeight)); } { // Logic GUILayoutExt.Box(padding, margin, () => { GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.FlexibleSpace(); var flag = world.GetModuleState(module); var state = (flag & ME.ECS.ModuleState.LogicInactive) == 0; if (this.ToggleMethod(worldEditor, module, "AdvanceTick", ref state) == true) { world.SetModuleState( module, state == false ? flag | ME.ECS.ModuleState.LogicInactive : flag & ~ME.ECS.ModuleState.LogicInactive); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); }, tableStyle, GUILayout.Width(col2), GUILayout.Height(cellHeight)); } { // Visual GUILayoutExt.Box(padding, margin, () => { GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.FlexibleSpace(); var flag = world.GetModuleState(module); var state = (flag & ME.ECS.ModuleState.VisualInactive) == 0; if (this.ToggleMethod(worldEditor, module, "Update", ref state) == true) { world.SetModuleState( module, state == false ? flag | ME.ECS.ModuleState.VisualInactive : flag & ~ME.ECS.ModuleState.VisualInactive); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); }, tableStyle, GUILayout.Width(col3), GUILayout.Height(cellHeight)); } GUILayout.EndHorizontal(); { GUILayoutExt.Box(padding, margin, () => { var editor = this.GetEditor(module); if (editor != null) { editor.OnDrawGUI(); } }, tableStyle, GUILayout.ExpandWidth(true)); GUILayout.Space(2f); } } }); }); var entitiesCount = 0; foreach (var entityStorage in entitiesStorage) { if (entityStorage == null) { continue; } var storages = entityStorage.Cast <ME.ECS.IStorage>().ToList(); foreach (var storage in storages) { if (storage == null) { continue; } entitiesCount += storage.Count; } } GUILayoutExt.FoldOut(ref worldEditor.foldoutEntitiesStorage, "Entities (" + entitiesCount.ToString() + ")", () => { var cellHeight = 25f; var padding = 2f; var margin = 1f; //var col1 = 80f; var tableStyle = (GUIStyle)"Box"; var dataStyle = new GUIStyle(EditorStyles.label); dataStyle.richText = true; GUILayoutExt.Padding(4f, () => { GUILayout.BeginHorizontal(); { /*GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Caption", EditorStyles.miniBoldLabel); }, tableStyle, * GUILayout.Width(col1), * GUILayout.Height(cellHeight));*/ GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Data", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.ExpandWidth(true), GUILayout.Height(cellHeight)); } GUILayout.EndHorizontal(); GUILayout.BeginVertical(); foreach (var entityStorage in entitiesStorage) { if (entityStorage == null) { continue; } var storages = entityStorage.Cast <ME.ECS.IStorage>().ToList(); foreach (var storage in storages) { if (storage == null) { continue; } GUILayout.BeginHorizontal(); { GUILayoutExt.Box( padding, margin, () => { GUILayoutExt.TypeLabel(storage.GetType()); GUILayout.Label(storage.ToString(), dataStyle); }, tableStyle, GUILayout.ExpandWidth(true), GUILayout.Height(cellHeight)); } GUILayout.EndHorizontal(); } } GUILayout.EndVertical(); }); }); var filtersCount = filters.Count; GUILayoutExt.FoldOut(ref worldEditor.foldoutFilters, "Filters (" + filtersCount.ToString() + ")", () => { var cellHeight = 25f; var padding = 2f; var margin = 1f; //var col1 = 80f; var tableStyle = (GUIStyle)"Box"; var dataStyle = new GUIStyle(EditorStyles.label); dataStyle.richText = true; GUILayoutExt.Padding(4f, () => { GUILayout.BeginHorizontal(); { /*GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Caption", EditorStyles.miniBoldLabel); }, tableStyle, * GUILayout.Width(col1), * GUILayout.Height(cellHeight));*/ GUILayoutExt.Box(padding, margin, () => { GUILayoutExt.TableCaption("Data", EditorStyles.miniBoldLabel); }, tableStyle, GUILayout.ExpandWidth(true), GUILayout.Height(cellHeight)); } GUILayout.EndHorizontal(); GUILayout.BeginVertical(); foreach (var filter in filters.GetData()) { GUILayout.BeginHorizontal(); { GUILayoutExt.Box( padding, margin, () => { GUILayoutExt.TypeLabel(filter.GetType()); GUILayout.Label(filter.ToString(), dataStyle); }, tableStyle, GUILayout.ExpandWidth(true), GUILayout.Height(cellHeight)); } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); }); }); }); if (worldEditor.foldout == true) { selectedWorld = worldEditor; // Fold in all others foreach (var wEditor in this.worlds) { if (wEditor != worldEditor) { wEditor.foldout = false; } } } }); GUILayoutExt.Separator(); } } } GUILayout.EndScrollView(); return(selectedWorld); }
public override void OnInspectorGUI() { ((Component)this.target).transform.hideFlags = HideFlags.HideInInspector; GUILayoutExt.CollectEditors <IDebugViewGUIEditor <InitializerBase>, ViewProviderCustomEditorAttribute>(ref this.viewsDebugEditors); GUILayoutExt.CollectEditors <IJobsViewGUIEditor <InitializerBase>, ViewProviderCustomEditorAttribute>(ref this.viewsJobsEditors); var target = this.target as InitializerBase; if (target.featuresList == null) { target.featuresList = new FeaturesList(); } if (target.featuresList.features == null) { target.featuresList.features = new System.Collections.Generic.List <FeaturesList.FeatureData>(); } if (this.list == null) { this.list = new UnityEditorInternal.ReorderableList(target.featuresList.features, typeof(FeaturesList.FeatureData), true, true, true, true); this.list.drawElementCallback = this.OnDrawListItem; this.list.drawHeaderCallback = this.OnDrawHeader; this.list.onChangedCallback = this.OnChanged; this.list.elementHeightCallback = this.GetElementHeight; } GUILayoutExt.Box(15f, 0f, () => { var isDirty = false; this.definesFoldOut = GUILayoutExt.BeginFoldoutHeaderGroup(this.definesFoldOut, new GUIContent("Defines"), EditorStyles.foldoutHeader); if (this.definesFoldOut == true) { GUILayout.Space(10f); EditorGUI.BeginDisabledGroup(EditorApplication.isCompiling == true || EditorApplication.isPlaying == true || EditorApplication.isPaused == true /* || InitializerEditor.isCompilingManual == true*/); foreach (var defineInfo in InitializerEditor.defines) { if (defineInfo.showInList == false) { continue; } var value = defineInfo.isActive.Invoke(); if (GUILayoutExt.ToggleLeft( ref value, ref isDirty, defineInfo.define, defineInfo.description) == true) { //InitializerEditor.isCompilingManual = true; if (value == true) { this.CompileWithDefine(defineInfo.define); } else { this.CompileWithoutDefine(defineInfo.define); } } } EditorGUI.EndDisabledGroup(); } this.settingsFoldOut = GUILayoutExt.BeginFoldoutHeaderGroup(this.settingsFoldOut, new GUIContent("Settings"), EditorStyles.foldoutHeader); if (this.settingsFoldOut == true) { GUILayout.Space(10f); GUILayoutExt.ToggleLeft( ref target.worldSettings.turnOffViews, ref isDirty, "Turn off views module", "If you want to run ME.ECS on server, you don't need to use Views at all. Turn off views module to avoid updating view instances overhead."); GUILayoutExt.ToggleLeft( ref target.worldSettings.useJobsForSystems, ref isDirty, "Use jobs for Systems", "Each system with filter has `jobs` flag which determine AdvanceTick behavior. If checked, jobs will be enabled and AdvanceTick will run asynchronously."); GUILayoutExt.ToggleLeft( ref target.worldSettings.useJobsForViews, ref isDirty, "Use jobs for Views", "Some view providers have jobs implementation. Turn it on to enable them update views inside jobs. Please note that some providers could lose some method calls."); if (this.viewsJobsEditors != null) { GUILayout.BeginHorizontal(); GUILayout.Space(10f); { GUILayout.BeginVertical(); foreach (var editor in this.viewsJobsEditors) { GUILayoutExt.Separator(); editor.Value.target = this.target as InitializerBase; if (editor.Value.OnDrawGUI() == true) { isDirty = true; } } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } } this.settingsDebugFoldOut = GUILayoutExt.BeginFoldoutHeaderGroup(this.settingsDebugFoldOut, new GUIContent("Debug Settings"), EditorStyles.foldoutHeader); if (this.settingsDebugFoldOut == true) { GUILayout.Space(10f); GUILayoutExt.ToggleLeft( ref target.worldDebugSettings.createGameObjectsRepresentation, ref isDirty, "Create GameObject representation", "Editor-only feature. If checked, all entities will be represented by GameObject with debug information."); GUILayoutExt.ToggleLeft( ref target.worldDebugSettings.showViewsOnScene, ref isDirty, "Show Views in Hierarchy", "Editor-only feature. If checked, views module always show views on scene."); if (this.viewsDebugEditors != null) { GUILayout.BeginHorizontal(); GUILayout.Space(10f); { GUILayout.BeginVertical(); foreach (var editor in this.viewsDebugEditors) { GUILayoutExt.Separator(); editor.Value.target = this.target as InitializerBase; if (editor.Value.OnDrawGUI() == true) { isDirty = true; } } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } } { var editor = Editor.CreateEditor(target); var field = editor.serializedObject.GetIterator(); editor.serializedObject.Update(); var baseClassEnd = false; while (field.NextVisible(true) == true) { if (baseClassEnd == true) { EditorGUILayout.PropertyField(field); } if (field.type == "EndOfBaseClass") { baseClassEnd = true; } } editor.serializedObject.ApplyModifiedProperties(); } if (isDirty == true) { EditorUtility.SetDirty(this.target); } }); EditorGUILayout.Space(); EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying == true || EditorApplication.isPaused == true); this.drawWidth = GUILayoutUtility.GetLastRect().width; this.list.DoLayoutList(); EditorGUI.EndDisabledGroup(); }
private void DrawTemplates(ME.ECS.DataConfigs.DataConfig dataConfig) { GUILayoutExt.Separator(6f); GUILayoutExt.DrawHeader("Used Templates:"); GUILayoutExt.Separator(); var usedComponents = new System.Collections.Generic.HashSet <ME.ECS.DataConfigs.DataConfigTemplate>(); if (dataConfig.templates != null) { var rect = new Rect(0f, 0f, EditorGUIUtility.currentViewWidth, 1000f); var style = new GUIStyle("AssetLabel Partial"); var buttonRects = EditorGUIUtility.GetFlowLayoutedRects(rect, style, 4f, 4f, dataConfig.templates.Select(x => { var guid = x; if (string.IsNullOrEmpty(guid) == true) { return(string.Empty); } var path = AssetDatabase.GUIDToAssetPath(guid); if (string.IsNullOrEmpty(path) == true) { return(string.Empty); } var template = AssetDatabase.LoadAssetAtPath <ME.ECS.DataConfigs.DataConfigTemplate>(path); if (template == null) { return(string.Empty); } return(template.name); }).ToList()); GUILayout.BeginHorizontal(); GUILayout.EndHorizontal(); var areaRect = GUILayoutUtility.GetLastRect(); for (int i = 0; i < buttonRects.Count; ++i) { areaRect.height = Mathf.Max(0f, buttonRects[i].yMax); } GUILayoutUtility.GetRect(areaRect.width, areaRect.height); GUI.BeginGroup(areaRect); for (int i = 0; i < dataConfig.templates.Length; ++i) { var guid = dataConfig.templates[i]; if (string.IsNullOrEmpty(guid) == true) { continue; } var path = AssetDatabase.GUIDToAssetPath(guid); if (string.IsNullOrEmpty(path) == true) { continue; } var template = AssetDatabase.LoadAssetAtPath <ME.ECS.DataConfigs.DataConfigTemplate>(path); if (template == null) { continue; } if (usedComponents.Contains(template) == false) { usedComponents.Add(template); } } for (int i = 0; i < dataConfig.templates.Length; ++i) { var guid = dataConfig.templates[i]; if (string.IsNullOrEmpty(guid) == true) { continue; } var path = AssetDatabase.GUIDToAssetPath(guid); if (string.IsNullOrEmpty(path) == true) { continue; } var template = AssetDatabase.LoadAssetAtPath <ME.ECS.DataConfigs.DataConfigTemplate>(path); if (template == null) { continue; } if (GUI.Button(buttonRects[i], template.name, style) == true) { EditorGUIUtility.PingObject(template); //this.RemoveTemplate(dataConfig, template, usedComponents); } } GUI.EndGroup(); } GUILayoutExt.DrawManageDataConfigTemplateMenu(usedComponents, (template, isUsed) => { var path = AssetDatabase.GetAssetPath(template); var guid = AssetDatabase.AssetPathToGUID(path); if (string.IsNullOrEmpty(guid) == true) { return; } if (isUsed == true) { usedComponents.Remove(template); for (int i = 0; i < dataConfig.templates.Length; ++i) { if (dataConfig.templates[i] == guid) { this.RemoveTemplate(dataConfig, template, usedComponents); break; } } } else { usedComponents.Add(template); if (dataConfig.templates == null) { dataConfig.templates = new string[0]; } System.Array.Resize(ref dataConfig.templates, dataConfig.templates.Length + 1); dataConfig.templates[dataConfig.templates.Length - 1] = guid; dataConfig.AddTemplate(template); dataConfig.OnScriptLoad(); this.Save(dataConfig); AssetDatabase.ForceReserializeAssets(new [] { AssetDatabase.GetAssetPath(dataConfig) }, ForceReserializeAssetsOptions.ReserializeAssetsAndMetadata); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(dataConfig), ImportAssetOptions.ForceUpdate); AssetDatabase.SaveAssets(); } }); }
public override void OnInspectorGUI() { var style = new GUIStyle(EditorStyles.toolbar); style.fixedHeight = 0f; style.stretchHeight = true; var backStyle = new GUIStyle(EditorStyles.label); backStyle.normal.background = Texture2D.whiteTexture; var slice = new ME.ECS.DataConfigs.DataConfigSlice(); var isMultiple = false; if (this.targets.Length > 1) { slice = ME.ECS.DataConfigs.DataConfigSlice.Distinct(this.targets.Cast <ME.ECS.DataConfigs.DataConfig>().ToArray()); isMultiple = true; } else { var config = (ME.ECS.DataConfigs.DataConfig) this.target; slice = new ME.ECS.DataConfigs.DataConfigSlice() { configs = new [] { config }, structComponentsDataTypeIds = config.structComponentsDataTypeIds, componentsTypeIds = config.componentsTypeIds }; } var usedComponentsAll = new System.Collections.Generic.HashSet <System.Type>(); foreach (var cfg in slice.configs) { var componentTypes = cfg.GetStructComponentTypes(); foreach (var cType in componentTypes) { if (usedComponentsAll.Contains(cType) == false) { usedComponentsAll.Add(cType); } } if (DataConfigEditor.worldEditors.TryGetValue(cfg, out var worldEditor) == false) { worldEditor = new WorldsViewerEditor.WorldEditor(); DataConfigEditor.worldEditors.Add(cfg, worldEditor); } } if (isMultiple == true) { GUILayoutExt.DrawHeader("The same components:"); GUILayoutExt.Padding(8f, () => { var kz = 0; for (int i = 0; i < slice.structComponentsDataTypeIds.Length; ++i) { var typeId = slice.structComponentsDataTypeIds[i]; var component = slice.configs[0].GetByTypeId(typeId); var components = slice.configs.Select(x => x.GetByTypeId(typeId)).ToArray(); var backColor = GUI.backgroundColor; GUI.backgroundColor = new Color(1f, 1f, 1f, kz++ % 2 == 0 ? 0f : 0.05f); GUILayout.BeginVertical(backStyle); { GUI.backgroundColor = backColor; var editor = WorldsViewerEditor.GetEditor(components); if (editor != null) { EditorGUI.BeginChangeCheck(); editor.OnDrawGUI(); if (EditorGUI.EndChangeCheck() == true) { slice.Set(typeId, components); this.Save(slice.configs); } } else { var componentName = GUILayoutExt.GetStringCamelCaseSpace(component.GetType().Name); var fieldsCount = GUILayoutExt.GetFieldsCount(component); if (fieldsCount == 0) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.Toggle(componentName, true); EditorGUI.EndDisabledGroup(); } else if (fieldsCount == 1) { var changed = GUILayoutExt.DrawFields(DataConfigEditor.multipleWorldEditor, components, componentName); if (changed == true) { slice.Set(typeId, components); this.Save(slice.configs); } } else { GUILayout.BeginHorizontal(); { GUILayout.Space(18f); GUILayout.BeginVertical(); { var key = "ME.ECS.WorldsViewerEditor.FoldoutTypes." + component.GetType().FullName; var foldout = EditorPrefs.GetBool(key, true); GUILayoutExt.FoldOut(ref foldout, componentName, () => { var changed = GUILayoutExt.DrawFields(DataConfigEditor.multipleWorldEditor, components); if (changed == true) { slice.Set(typeId, components); this.Save(slice.configs); } }); EditorPrefs.SetBool(key, foldout); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } } GUILayoutExt.DrawComponentHelp(component.GetType()); } GUILayout.EndVertical(); GUILayoutExt.Separator(); } }); GUILayoutExt.DrawAddComponentMenu(usedComponentsAll, (addType, isUsed) => { foreach (var dataConfigInner in slice.configs) { if (isUsed == true) { usedComponentsAll.Remove(addType); for (int i = 0; i < dataConfigInner.structComponents.Length; ++i) { if (dataConfigInner.structComponents[i].GetType() == addType) { var list = dataConfigInner.structComponents.ToList(); list.RemoveAt(i); dataConfigInner.structComponents = list.ToArray(); dataConfigInner.OnScriptLoad(); this.Save(dataConfigInner); break; } } } else { usedComponentsAll.Add(addType); System.Array.Resize(ref dataConfigInner.structComponents, dataConfigInner.structComponents.Length + 1); dataConfigInner.structComponents[dataConfigInner.structComponents.Length - 1] = (IStructComponent)System.Activator.CreateInstance(addType); dataConfigInner.OnScriptLoad(); this.Save(dataConfigInner); } } }); return; } GUILayoutExt.Separator(6f); GUILayoutExt.DrawHeader("Add Struct Components:"); GUILayoutExt.Separator(); var dataConfig = (ME.ECS.DataConfigs.DataConfig) this.target; GUILayoutExt.Padding(8f, () => { var usedComponents = new System.Collections.Generic.HashSet <System.Type>(); var kz = 0; var registries = dataConfig.structComponents; var sortedRegistries = new System.Collections.Generic.SortedDictionary <int, Registry>(new WorldsViewerEditor.DuplicateKeyComparer <int>()); for (int i = 0; i < registries.Length; ++i) { var registry = registries[i]; if (registry == null) { continue; } var component = registry; usedComponents.Add(component.GetType()); var editor = WorldsViewerEditor.GetEditor(component, out var order); if (editor != null) { sortedRegistries.Add(order, new Registry() { index = i, data = component }); } else { sortedRegistries.Add(0, new Registry() { index = i, data = component }); } } foreach (var registryKv in sortedRegistries) { var registry = registryKv.Value; var component = registry.data; var backColor = GUI.backgroundColor; GUI.backgroundColor = new Color(1f, 1f, 1f, kz++ % 2 == 0 ? 0f : 0.05f); GUILayout.BeginVertical(backStyle); { GUI.backgroundColor = backColor; var editor = WorldsViewerEditor.GetEditor(component); if (editor != null) { EditorGUI.BeginChangeCheck(); editor.OnDrawGUI(); if (EditorGUI.EndChangeCheck() == true) { component = editor.GetTarget <IStructComponent>(); dataConfig.structComponents[registry.index] = component; this.Save(dataConfig); } } else { var componentName = GUILayoutExt.GetStringCamelCaseSpace(component.GetType().Name); var fieldsCount = GUILayoutExt.GetFieldsCount(component); if (fieldsCount == 0) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.Toggle(componentName, true); EditorGUI.EndDisabledGroup(); } else if (fieldsCount == 1) { var changed = GUILayoutExt.DrawFields(DataConfigEditor.multipleWorldEditor, component, componentName); if (changed == true) { dataConfig.structComponents[registry.index] = component; this.Save(dataConfig); } } else { GUILayout.BeginHorizontal(); { GUILayout.Space(18f); GUILayout.BeginVertical(); { var key = "ME.ECS.WorldsViewerEditor.FoldoutTypes." + component.GetType().FullName; var foldout = EditorPrefs.GetBool(key, true); GUILayoutExt.FoldOut(ref foldout, componentName, () => { var changed = GUILayoutExt.DrawFields(DataConfigEditor.multipleWorldEditor, component); if (changed == true) { dataConfig.structComponents[registry.index] = component; this.Save(dataConfig); } }); EditorPrefs.SetBool(key, foldout); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } } GUILayoutExt.DrawComponentHelp(component.GetType()); this.DrawComponentTemplatesUsage(dataConfig, component); } GUILayout.EndVertical(); GUILayoutExt.Separator(); } GUILayoutExt.DrawAddComponentMenu(usedComponents, (addType, isUsed) => { if (isUsed == true) { usedComponents.Remove(addType); for (int i = 0; i < dataConfig.structComponents.Length; ++i) { if (dataConfig.structComponents[i].GetType() == addType) { var list = dataConfig.structComponents.ToList(); list.RemoveAt(i); dataConfig.structComponents = list.ToArray(); dataConfig.OnScriptLoad(); this.Save(dataConfig); break; } } } else { usedComponents.Add(addType); System.Array.Resize(ref dataConfig.structComponents, dataConfig.structComponents.Length + 1); dataConfig.structComponents[dataConfig.structComponents.Length - 1] = (IStructComponent)System.Activator.CreateInstance(addType); dataConfig.OnScriptLoad(); this.Save(dataConfig); } }); }); GUILayoutExt.Separator(6f); GUILayoutExt.DrawHeader("Add Managed Components:"); GUILayoutExt.Separator(); GUILayoutExt.Padding(8f, () => { var usedComponents = new System.Collections.Generic.HashSet <System.Type>(); var kz = 0; var registries = dataConfig.components; var sortedRegistries = new System.Collections.Generic.SortedDictionary <int, RegistryComponent>(new WorldsViewerEditor.DuplicateKeyComparer <int>()); for (int i = 0; i < registries.Length; ++i) { var registry = registries[i]; if (registry == null) { continue; } var component = registry; usedComponents.Add(component.GetType()); var editor = WorldsViewerEditor.GetEditor(component, out var order); if (editor != null) { sortedRegistries.Add(order, new RegistryComponent() { index = i, data = component }); } else { sortedRegistries.Add(0, new RegistryComponent() { index = i, data = component }); } } foreach (var registryKv in sortedRegistries) { var registry = registryKv.Value; var component = registry.data; var backColor = GUI.backgroundColor; GUI.backgroundColor = new Color(1f, 1f, 1f, kz++ % 2 == 0 ? 0f : 0.05f); GUILayout.BeginVertical(backStyle); { GUI.backgroundColor = backColor; var editor = WorldsViewerEditor.GetEditor(component); if (editor != null) { EditorGUI.BeginChangeCheck(); editor.OnDrawGUI(); if (EditorGUI.EndChangeCheck() == true) { component = editor.GetTarget <IComponent>(); dataConfig.components[registry.index] = component; this.Save(dataConfig); } } else { var componentName = component.GetType().Name; var fieldsCount = GUILayoutExt.GetFieldsCount(component); if (fieldsCount == 0) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.Toggle(componentName, true); EditorGUI.EndDisabledGroup(); } else if (fieldsCount == 1) { var changed = GUILayoutExt.DrawFields(DataConfigEditor.multipleWorldEditor, component, componentName); if (changed == true) { dataConfig.components[registry.index] = component; this.Save(dataConfig); } } else { GUILayout.BeginHorizontal(); { GUILayout.Space(18f); GUILayout.BeginVertical(); { var key = "ME.ECS.WorldsViewerEditor.FoldoutTypes." + component.GetType().FullName; var foldout = EditorPrefs.GetBool(key, true); GUILayoutExt.FoldOut(ref foldout, componentName, () => { var changed = GUILayoutExt.DrawFields(DataConfigEditor.multipleWorldEditor, component); if (changed == true) { dataConfig.components[registry.index] = component; this.Save(dataConfig); } }); EditorPrefs.SetBool(key, foldout); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } } GUILayoutExt.DrawComponentHelp(component.GetType()); this.DrawComponentTemplatesUsage(dataConfig, component); } GUILayout.EndVertical(); GUILayoutExt.Separator(); } GUILayoutExt.DrawAddComponentMenu(usedComponents, (addType, isUsed) => { if (isUsed == true) { usedComponents.Remove(addType); for (int i = 0; i < dataConfig.components.Length; ++i) { if (dataConfig.components[i].GetType() == addType) { var list = dataConfig.components.ToList(); list.RemoveAt(i); dataConfig.components = list.ToArray(); dataConfig.OnScriptLoad(); this.Save(dataConfig); break; } } } else { usedComponents.Add(addType); System.Array.Resize(ref dataConfig.components, dataConfig.components.Length + 1); dataConfig.components[dataConfig.components.Length - 1] = (IComponent)System.Activator.CreateInstance(addType); dataConfig.OnScriptLoad(); this.Save(dataConfig); } }, drawRefComponents: true); }); GUILayoutExt.Separator(6f); GUILayoutExt.DrawHeader("Remove Struct Components:"); GUILayoutExt.Separator(); // Remove struct components GUILayoutExt.Padding(8f, () => { var usedComponents = new System.Collections.Generic.HashSet <System.Type>(); var kz = 0; var registries = dataConfig.removeStructComponentsDataTypeIds; for (int i = 0; i < registries.Length; ++i) { var registry = registries[i]; var type = ComponentTypesRegistry.allTypeId.FirstOrDefault(x => x.Value == registry).Key; if (type == null) { continue; } usedComponents.Add(type); var backColor = GUI.backgroundColor; GUI.backgroundColor = new Color(1f, 1f, 1f, kz++ % 2 == 0 ? 0f : 0.05f); GUILayout.BeginVertical(backStyle); { GUI.backgroundColor = backColor; var componentName = GUILayoutExt.GetStringCamelCaseSpace(type.Name); EditorGUI.BeginDisabledGroup(true); EditorGUILayout.Toggle(componentName, true); EditorGUI.EndDisabledGroup(); GUILayoutExt.DrawComponentHelp(type); this.DrawComponentTemplatesUsage(dataConfig, dataConfig.removeStructComponents[i]); } GUILayout.EndVertical(); GUILayoutExt.Separator(); } GUILayoutExt.DrawAddComponentMenu(usedComponents, (addType, isUsed) => { if (isUsed == true) { usedComponents.Remove(addType); for (int i = 0; i < dataConfig.removeStructComponents.Length; ++i) { if (dataConfig.removeStructComponents[i].GetType() == addType) { var list = dataConfig.removeStructComponents.ToList(); list.RemoveAt(i); dataConfig.removeStructComponents = list.ToArray(); dataConfig.OnScriptLoad(); this.Save(dataConfig); break; } } } else { usedComponents.Add(addType); System.Array.Resize(ref dataConfig.removeStructComponents, dataConfig.removeStructComponents.Length + 1); dataConfig.removeStructComponents[dataConfig.removeStructComponents.Length - 1] = (IStructComponent)System.Activator.CreateInstance(addType); dataConfig.OnScriptLoad(); this.Save(dataConfig); } }); }); if ((dataConfig is ME.ECS.DataConfigs.DataConfigTemplate) == false) { this.DrawTemplates(dataConfig); } }
public override void OnInspectorGUI() { var dataConfig = (ME.ECS.DataConfigs.DataConfig) this.target; if (dataConfig is ME.ECS.DataConfigs.DataConfigTemplate == false) { foreach (var target in this.targets) { var dc = (ME.ECS.DataConfigs.DataConfig)target; if (dc.sharedGroupId == 0) { dc.sharedGroupId = ME.ECS.MathUtils.GetHash(AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(dc))); this.Save(dc); } } GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); this.serializedObject.Update(); var sharedIdLabelStyle = new GUIStyle(EditorStyles.miniBoldLabel); sharedIdLabelStyle.alignment = TextAnchor.MiddleRight; EditorGUILayout.LabelField("Shared ID:", sharedIdLabelStyle); EditorGUILayout.PropertyField(this.sharedGroupId, new GUIContent(string.Empty), GUILayout.Width(100f)); this.serializedObject.ApplyModifiedProperties(); GUILayout.EndHorizontal(); } this.search = GUILayoutExt.SearchField("Search", this.search); { var style = new GUIStyle(EditorStyles.toolbar); style.fixedHeight = 0f; style.stretchHeight = true; var backStyle = new GUIStyle(EditorStyles.label); backStyle.normal.background = Texture2D.whiteTexture; var slice = new ME.ECS.DataConfigs.DataConfigSlice(); var isMultiple = false; if (this.targets.Length > 1) { slice = ME.ECS.DataConfigs.DataConfigSlice.Distinct(this.targets.Cast <ME.ECS.DataConfigs.DataConfig>().ToArray()); isMultiple = true; } else { var config = (ME.ECS.DataConfigs.DataConfig) this.target; slice = new ME.ECS.DataConfigs.DataConfigSlice() { configs = new[] { config }, structComponentsTypes = config.structComponents.Where(x => x != null).Select(x => x.GetType()).ToArray(), }; } var usedComponentsAll = new System.Collections.Generic.HashSet <System.Type>(); foreach (var cfg in slice.configs) { var componentTypes = cfg.GetStructComponentTypes(); foreach (var cType in componentTypes) { if (usedComponentsAll.Contains(cType) == false) { usedComponentsAll.Add(cType); } } if (DataConfigEditor.worldEditors.TryGetValue(cfg, out var worldEditor) == false) { worldEditor = new WorldsViewerEditor.WorldEditor(); DataConfigEditor.worldEditors.Add(cfg, worldEditor); } } if (isMultiple == true) { GUILayoutExt.DrawHeader("The Same Components:"); GUILayoutExt.Padding(4f, () => { var kz = 0; for (int i = 0; i < slice.structComponentsTypes.Length; ++i) { var type = slice.structComponentsTypes[i]; var component = slice.configs[0].GetByType(slice.configs[0].structComponents, type); if (GUILayoutExt.IsSearchValid(component, this.search) == false) { continue; } var components = slice.configs.Select(x => x.GetByType(x.structComponents, type)).ToArray(); var backColor = GUI.backgroundColor; GUI.backgroundColor = new Color(1f, 1f, 1f, kz++ % 2 == 0 ? 0f : 0.05f); GUILayout.BeginVertical(backStyle); { GUI.backgroundColor = backColor; var editor = WorldsViewerEditor.GetEditor(components); if (editor != null) { EditorGUI.BeginChangeCheck(); editor.OnDrawGUI(); if (EditorGUI.EndChangeCheck() == true) { slice.Set(components); this.Save(slice.configs); } } else { var componentName = GUILayoutExt.GetStringCamelCaseSpace(component.GetType().Name); var fieldsCount = GUILayoutExt.GetFieldsCount(component); if (fieldsCount == 0) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.Toggle(componentName, true); EditorGUI.EndDisabledGroup(); } else if (fieldsCount == 1) { var changed = GUILayoutExt.DrawFields(DataConfigEditor.multipleWorldEditor, components, componentName); if (changed == true) { slice.Set(components); this.Save(slice.configs); } } else { GUILayout.BeginHorizontal(); { GUILayout.Space(18f); GUILayout.BeginVertical(); { var key = "ME.ECS.WorldsViewerEditor.FoldoutTypes." + component.GetType().FullName; var foldout = EditorPrefs.GetBool(key, true); GUILayoutExt.FoldOut(ref foldout, componentName, () => { var changed = GUILayoutExt.DrawFields(DataConfigEditor.multipleWorldEditor, components); if (changed == true) { slice.Set(components); this.Save(slice.configs); } }); EditorPrefs.SetBool(key, foldout); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } } GUILayoutExt.DrawComponentHelp(component.GetType()); this.DrawShared(component); } GUILayout.EndVertical(); GUILayoutExt.Separator(); } }); GUILayoutExt.DrawAddComponentMenu(usedComponentsAll, (addType, isUsed) => { foreach (var dataConfigInner in slice.configs) { if (isUsed == true) { this.OnRemoveComponent(addType); usedComponentsAll.Remove(addType); for (int i = 0; i < dataConfigInner.structComponents.Length; ++i) { if (dataConfigInner.structComponents[i].GetType() == addType) { var list = dataConfigInner.structComponents.ToList(); list.RemoveAt(i); dataConfigInner.structComponents = list.ToArray(); //dataConfigInner.OnScriptLoad(); this.Save(dataConfigInner); break; } } } else { usedComponentsAll.Add(addType); System.Array.Resize(ref dataConfigInner.structComponents, dataConfigInner.structComponents.Length + 1); dataConfigInner.structComponents[dataConfigInner.structComponents.Length - 1] = (IStructComponentBase)System.Activator.CreateInstance(addType); //dataConfigInner.OnScriptLoad(); this.Save(dataConfigInner); this.OnAddComponent(addType); } } }); return; } GUILayoutExt.DrawHeader("Add Struct Components:"); GUILayoutExt.Separator(); GUILayoutExt.Padding(4f, () => { var usedComponents = new System.Collections.Generic.HashSet <System.Type>(); this.serializedObject.Update(); if (GUILayoutExt.DrawFieldsSingle(this.search, this, DataConfigEditor.multipleWorldEditor, dataConfig.structComponents, (index, component, prop) => { GUILayout.BeginVertical(); }, (index, component, prop) => { if (component == null) { return; } usedComponents.Add(component.GetType()); GUILayoutExt.DrawComponentHelp(component.GetType()); this.DrawComponentTemplatesUsage(dataConfig, component); this.DrawShared(component); GUILayout.EndVertical(); { var lastRect = GUILayoutUtility.GetLastRect(); if (Event.current.type == EventType.ContextClick && lastRect.Contains(Event.current.mousePosition) == true) { var menu = new GenericMenu(); if (this.CanMove(dataConfig, index, index - 1) == true) { menu.AddItem(new GUIContent("Move Up"), false, () => { this.MoveElement(dataConfig, index, index - 1); }); } else { menu.AddDisabledItem(new GUIContent("Move Up")); } if (this.CanMove(dataConfig, index, index + 1) == true) { menu.AddItem(new GUIContent("Move Down"), false, () => { this.MoveElement(dataConfig, index, index + 1); }); } else { menu.AddDisabledItem(new GUIContent("Move Down")); } menu.AddItem(new GUIContent("Delete"), false, () => { var list = dataConfig.structComponents.ToList(); this.OnRemoveComponent(list[index].GetType()); list.RemoveAt(index); dataConfig.structComponents = list.ToArray(); //dataConfig.OnScriptLoad(); this.Save(dataConfig); }); this.OnComponentMenu(menu, index); menu.ShowAsContext(); } } GUILayoutExt.Separator(); }) == true) { this.serializedObject.ApplyModifiedProperties(); this.Save(dataConfig); } GUILayoutExt.DrawAddComponentMenu(usedComponents, (addType, isUsed) => { if (isUsed == true) { this.OnRemoveComponent(addType); usedComponents.Remove(addType); for (int i = 0; i < dataConfig.structComponents.Length; ++i) { if (dataConfig.structComponents[i].GetType() == addType) { var list = dataConfig.structComponents.ToList(); list.RemoveAt(i); dataConfig.structComponents = list.ToArray(); //dataConfig.OnScriptLoad(); this.Save(dataConfig); break; } } } else { usedComponents.Add(addType); System.Array.Resize(ref dataConfig.structComponents, dataConfig.structComponents.Length + 1); dataConfig.structComponents[dataConfig.structComponents.Length - 1] = (IStructComponentBase)System.Activator.CreateInstance(addType); //dataConfig.OnScriptLoad(); this.Save(dataConfig); this.OnAddComponent(addType); } }); }); GUILayoutExt.DrawHeader("Remove Struct Components:"); GUILayoutExt.Separator(); // Remove struct components GUILayoutExt.Padding(4f, () => { var usedComponents = new System.Collections.Generic.HashSet <System.Type>(); var kz = 0; var registries = dataConfig.removeStructComponents; for (int i = 0; i < registries.Length; ++i) { var registry = registries[i]; if (GUILayoutExt.IsSearchValid(registry, this.search) == false) { continue; } var type = registry.GetType(); usedComponents.Add(type); var backColor = GUI.backgroundColor; GUI.backgroundColor = new Color(1f, 1f, 1f, kz++ % 2 == 0 ? 0f : 0.05f); GUILayout.BeginVertical(backStyle); { GUI.backgroundColor = backColor; var componentName = GUILayoutExt.GetStringCamelCaseSpace(type.Name); EditorGUI.BeginDisabledGroup(true); EditorGUILayout.Toggle(componentName, true); EditorGUI.EndDisabledGroup(); GUILayoutExt.DrawComponentHelp(type); this.DrawComponentTemplatesUsage(dataConfig, dataConfig.removeStructComponents[i]); } GUILayout.EndVertical(); GUILayoutExt.Separator(); } GUILayoutExt.DrawAddComponentMenu(usedComponents, (addType, isUsed) => { if (isUsed == true) { this.OnRemoveComponentFromRemoveList(addType); usedComponents.Remove(addType); for (int i = 0; i < dataConfig.removeStructComponents.Length; ++i) { if (dataConfig.removeStructComponents[i].GetType() == addType) { var list = dataConfig.removeStructComponents.ToList(); list.RemoveAt(i); dataConfig.removeStructComponents = list.ToArray(); //dataConfig.OnScriptLoad(); this.Save(dataConfig); break; } } } else { usedComponents.Add(addType); System.Array.Resize(ref dataConfig.removeStructComponents, dataConfig.removeStructComponents.Length + 1); dataConfig.removeStructComponents[dataConfig.removeStructComponents.Length - 1] = (IStructComponentBase)System.Activator.CreateInstance(addType); //dataConfig.OnScriptLoad(); this.Save(dataConfig); this.OnAddComponentFromRemoveList(addType); } }); }); if ((dataConfig is ME.ECS.DataConfigs.DataConfigTemplate) == false) { this.DrawTemplates(dataConfig); } } }