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); }
private void DrawEntities(WorldEditor world) { var style = EditorStyles.helpBox; this.scrollEntitiesPosition = GUILayout.BeginScrollView(this.scrollEntitiesPosition, style, GUILayout.ExpandHeight(true)); { if (world == null) { var centeredStyle = new GUIStyle(EditorStyles.centeredGreyMiniLabel); centeredStyle.stretchHeight = true; centeredStyle.richText = true; GUILayout.Label("Select world from the left list.", centeredStyle); } else { var padding = 2f; var margin = 1f; var dataStyle = new GUIStyle(EditorStyles.label); dataStyle.richText = true; dataStyle.wordWrap = true; var modules = world.GetModules(); //var componentsStorage = world.GetComponentsStorage(); var entitiesStorage = world.GetEntitiesStorage(); 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.BeginVertical(); { var foldout = world.IsFoldOut(storage); GUILayoutExt.FoldOut(ref foldout, GUILayoutExt.GetTypeLabel(storage.GetType()), () => { var list = storage.GetData(); for (var i = list.FromIndex; i < list.SizeCount; ++i) { if (list.IsFree(i) == true) { continue; } var item = list.Get <ME.ECS.IEntity>(i); var entityData = item; GUILayoutExt.Box( padding, margin, () => { GUILayout.Space(2f); GUILayout.Label("Entity " + entityData.entity.id.ToString() + " (" + entityData.entity.storageIdx.ToString() + ")"); GUILayoutExt.Box( padding, margin, () => { #region Data var foldoutData = world.IsFoldOutData(storage, entityData.entity.id); GUILayoutExt.FoldOut(ref foldoutData, "Data", () => { { // Draw data table GUILayoutExt.DrawFields(item, 120f); } }); world.SetFoldOutData(storage, entityData.entity.id, foldoutData); #endregion #region Components var foldoutComponents = world.IsFoldOutComponents(storage, entityData.entity.id); GUILayoutExt.FoldOut(ref foldoutComponents, "Components", () => { GUILayout.Label("Due to technical issues components list is not supported for now", EditorStyles.miniBoldLabel); /*ME.ECS.IComponentsBase components; * if (componentsStorage.TryGetValue(entityData.entity.id, out components) == true) { * * var componentsDic = components.GetData(entityData.entity.id); * foreach (var component in componentsDic) { * * GUILayoutExt.Box( * padding, * margin, * () => { * * GUILayout.Space(2f); * GUILayout.BeginHorizontal(); * GUILayout.Label(component.GetType().Name, GUILayout.Width(90f)); * GUILayoutExt.TypeLabel(component.GetType()); * GUILayout.EndHorizontal(); * * GUILayoutExt.Box( * padding, * margin, * () => { * * GUILayout.Label("Data", EditorStyles.miniBoldLabel); * GUILayoutExt.DrawFields(component, 120f); * * }, GUIStyle.none); * * }, "dragtabdropwindow"); * * } * * }*/ }); world.SetFoldOutComponents(storage, entityData.entity.id, foldoutComponents); #endregion #if VIEWS_MODULE_SUPPORT var foldoutViews = world.IsFoldOutViews(storage, entityData.entity.id); GUILayoutExt.FoldOut(ref foldoutViews, "Views", () => { { // Draw views table var viewsModules = modules.OfType <ME.ECS.Views.IViewModuleBase>().ToArray(); foreach (var viewsModule in viewsModules) { if (viewsModule != null) { var allViews = viewsModule.GetData(); foreach (DictionaryEntry itemEntry in allViews) { var key = (EntityId)itemEntry.Key; if (key == entityData.entity.id) { var listViews = (IList)itemEntry.Value; for (int j = 0; j < listViews.Count; ++j) { var view = (ME.ECS.Views.IViewBase)listViews[j]; GUILayoutExt.Box( padding, margin, () => { GUILayout.Label("Prefab Source Id: " + view.prefabSourceId.ToString()); var provider = viewsModule.GetViewSourceProvider(view.prefabSourceId); GUILayout.Label("Provider: " + GUILayoutExt.GetTypeLabel(provider.GetType())); GUILayout.Label("Creation Tick: " + view.creationTick.ToString()); }); } } } } } } }); world.SetFoldOutViews(storage, entityData.entity.id, foldoutViews); #endif }, GUIStyle.none); }, "dragtabdropwindow"); list.Set(i, entityData); } }); world.SetFoldOut(storage, foldout); } GUILayout.EndVertical(); } } } } GUILayout.EndScrollView(); }
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); } } }