update editors, update EcsPipelineTemplateSO

This commit is contained in:
Mikhail 2024-09-14 23:30:11 +08:00
parent 2229ee0f5d
commit a0f5129f3e
14 changed files with 575 additions and 551 deletions

View File

@ -7,20 +7,17 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomEditor(typeof(AutoEntityCreator))]
[CanEditMultipleObjects]
internal class AutoEntityCreatorEditor : Editor
internal class AutoEntityCreatorEditor : ExtendedEditor<AutoEntityCreator>
{
private AutoEntityCreator Target => (AutoEntityCreator)target;
public override void OnInspectorGUI()
protected override void DrawCustom()
{
EditorGUI.BeginChangeCheck();
var iterator = serializedObject.GetIterator();
iterator.NextVisible(true);
while (iterator.NextVisible(false))
{
EditorGUILayout.PropertyField(iterator, true);
}
if (EditorGUI.EndChangeCheck())
if (EcsGUI.Changed)
{
serializedObject.ApplyModifiedProperties();
}
@ -33,9 +30,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
float height = EcsGUI.EntityBarHeight;
Rect rect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, height);
EditorGUI.DrawRect(rect, new Color(0f, 0f, 0f, 0.1f));
rect = RectUtility.AddPadding(rect, 2f, 0f);
var (left, autosetCascadeRect) = RectUtility.HorizontalSliceRight(rect, height);
var (_, autosetRect) = RectUtility.HorizontalSliceRight(left, height);
rect = rect.AddPadding(2f, 0f);
var (left, autosetCascadeRect) = rect.HorizontalSliceRight(height);
var (_, autosetRect) = rect.HorizontalSliceRight(height);
if (EcsGUI.AutosetCascadeButton(autosetCascadeRect))
{

View File

@ -7,24 +7,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomEditor(typeof(EcsEntityConnect))]
[CanEditMultipleObjects]
internal class EcsEntityConnectEditor : Editor
internal class EcsEntityConnectEditor : ExtendedEditor<EcsEntityConnect>
{
private bool _isInit = false;
private EcsEntityConnect Target => (EcsEntityConnect)target;
private bool IsMultipleTargets => targets.Length > 1;
private void Init()
protected override void DrawCustom()
{
if (_isInit)
{
return;
}
_isInit = true;
}
public override void OnInspectorGUI()
{
Init();
EcsEntityConnect[] targets = new EcsEntityConnect[this.targets.Length];
for (int i = 0; i < targets.Length; i++)
{
@ -47,16 +33,19 @@ namespace DCFApixels.DragonECS.Unity.Editors
private void DrawTemplates()
{
EditorGUI.BeginChangeCheck();
var iterator = serializedObject.GetIterator();
iterator.NextVisible(true);
while (iterator.NextVisible(false))
using (EcsGUI.CheckChanged())
{
EditorGUILayout.PropertyField(iterator, true);
}
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
var iterator = serializedObject.GetIterator();
iterator.NextVisible(true);
while (iterator.NextVisible(false))
{
EditorGUILayout.PropertyField(iterator, true);
}
if (EcsGUI.Changed)
{
serializedObject.ApplyModifiedProperties();
}
}
}
@ -65,8 +54,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
float height = EcsGUI.EntityBarHeight;
Rect rect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, height);
EditorGUI.DrawRect(rect, new Color(0f, 0f, 0f, 0.1f));
rect = RectUtility.AddPadding(rect, 2f, 0f);
var (_, buttonRect) = RectUtility.HorizontalSliceRight(rect, height);
rect = rect.AddPadding(2f, 0f);
var (_, buttonRect) = rect.HorizontalSliceRight(height);
if (EcsGUI.AutosetCascadeButton(buttonRect))
{
foreach (var target in targets)
@ -82,9 +71,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
target.Autoset_Editor();
}
}
using (new EditorGUI.DisabledScope(!Application.isPlaying))
using (EcsGUI.SetEnable(Application.isPlaying))
{
buttonRect = RectUtility.Move(buttonRect, -height, 0);
buttonRect = buttonRect.Move(-height, 0);
if (EcsGUI.DelEntityButton(buttonRect))
{
foreach (var target in targets)
@ -92,7 +81,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
target.DeleteEntity_Editor();
}
}
buttonRect = RectUtility.Move(buttonRect, -height, 0);
buttonRect = buttonRect.Move(-height, 0);
if (EcsGUI.UnlinkButton(buttonRect))
{
foreach (var target in targets)

View File

@ -2,19 +2,18 @@
using DCFApixels.DragonECS.Unity.Internal;
using UnityEditor;
using UnityEngine;
using static UnityEditor.EditorGUI;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomPropertyDrawer(typeof(entlong))]
internal class EntlongDrawer : PropertyDrawer
internal class EntlongDrawer : ExtendedPropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
{
using (new DisabledScope(false))
using (EcsGUI.Disable)
{
EntitySlotInfo slotInfo = new EntitySlotInfo(property.FindPropertyRelative("_full").longValue);
var (labelRect, barRect) = RectUtility.HorizontalSliceLeft(position, EditorGUIUtility.labelWidth * 0.65f);
var (labelRect, barRect) = position.HorizontalSliceLeft(EditorGUIUtility.labelWidth * 0.65f);
EditorGUI.LabelField(labelRect, label);
bool isAlive = EcsWorld.GetWorld(slotInfo.world).IsAlive(slotInfo.id, slotInfo.gen);

View File

@ -6,14 +6,12 @@ using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomEditor(typeof(EntityMonitor))]
internal class EntityMonitorEditor : Editor
internal class EntityMonitorEditor : ExtendedEditor<EntityMonitor>
{
private EntityMonitor Target => (EntityMonitor)target;
public override void OnInspectorGUI()
protected override void DrawCustom()
{
bool isAlive = Target.Entity.TryUnpackForUnityEditor(out int id, out short gen, out short worldID, out EcsWorld world);
using (new EditorGUI.DisabledScope(!isAlive))
using (EcsGUI.SetEnable(isAlive))
{
if (GUILayout.Button("Delete Entity", GUILayout.Height(36f)))
{

View File

@ -9,7 +9,7 @@ using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomEditor(typeof(PipelineMonitor))]
internal class PipelineMonitorEditor : Editor
internal class PipelineMonitorEditor : ExtendedEditor<PipelineMonitor>
{
private GUIStyle _headerStyle;
private GUIStyle _interfacesStyle;
@ -17,19 +17,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
private GUIStyle systemsListStyle;
private PipelineMonitor Target => (PipelineMonitor)target;
private bool IsShowInterfaces
{
get { return SettingsPrefs.instance.IsShowInterfaces; }
set { SettingsPrefs.instance.IsShowInterfaces = value; }
}
private bool IsShowHidden
{
get { return SettingsPrefs.instance.IsShowHidden; }
set { SettingsPrefs.instance.IsShowHidden = value; }
}
public override void OnInspectorGUI()
protected override void DrawCustom()
{
systemsListStyle = new GUIStyle(EditorStyles.miniLabel);
systemsListStyle.wordWrap = true;
@ -55,25 +43,27 @@ namespace DCFApixels.DragonECS.Unity.Editors
IsShowInterfaces = EditorGUILayout.Toggle("Show Interfaces", IsShowInterfaces);
IsShowHidden = EditorGUILayout.Toggle("Show Hidden", IsShowHidden);
GUILayout.BeginVertical();
foreach (var item in Target.Pipeline.AllSystems)
using (EcsGUI.Layout.BeginVertical())
{
DrawSystem(item);
foreach (var item in Target.Pipeline.AllSystems)
{
DrawSystem(item);
}
}
GUILayout.EndVertical();
GUILayout.Label("[Runners]", _headerStyle);
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f));
foreach (var item in Target.Pipeline.AllRunners)
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)))
{
if (item.Key.IsInterface == false)
foreach (var item in Target.Pipeline.AllRunners)
{
DrawRunner(item.Value);
if (item.Key.IsInterface == false)
{
DrawRunner(item.Value);
}
}
}
GUILayout.EndVertical();
}
private void DrawSystem(IEcsProcess system)
{
@ -82,8 +72,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
GUILayout.EndVertical();
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f));
GUILayout.BeginHorizontal();
using (var scope = EcsGUI.SetAlignment(GUI.skin.label))
using (EcsGUI.Layout.BeginHorizontal()) using (var scope = EcsGUI.SetAlignment(GUI.skin.label))
{
scope.Target.alignment = TextAnchor.UpperLeft;
@ -104,7 +93,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
scope.Target.alignment = TextAnchor.UpperRight;
GUILayout.Label(">", GUILayout.ExpandWidth(true));
}
GUILayout.EndHorizontal();
return;
}
@ -119,13 +107,15 @@ namespace DCFApixels.DragonECS.Unity.Editors
string name = meta.Name;
Color color = meta.Color.ToUnityColor();
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(color, 0.2f));
if (IsShowInterfaces)
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetStyle(color, 0.2f)))
{
GUILayout.Label(string.Join(", ", type.GetInterfaces().Select(o => o.Name)), _interfacesStyle);
if (IsShowInterfaces)
{
GUILayout.Label(string.Join(", ", type.GetInterfaces().Select(o => o.Name)), _interfacesStyle);
}
GUILayout.Label(name, EditorStyles.boldLabel);
}
GUILayout.Label(name, EditorStyles.boldLabel);
GUILayout.EndVertical();
}
private void DrawRunner(IEcsRunner runner)
{
@ -138,10 +128,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
Color color = meta.Color.ToUnityColor();
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(color, 0.2f));
GUILayout.Label(meta.Name, EditorStyles.boldLabel);
GUILayout.Label(string.Join(", ", runner.ProcessRaw.Cast<object>().Select(o => o.GetType().Name)), systemsListStyle);
GUILayout.EndVertical();
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetStyle(color, 0.2f)))
{
GUILayout.Label(meta.Name, EditorStyles.boldLabel);
GUILayout.Label(string.Join(", ", runner.ProcessRaw.Cast<object>().Select(o => o.GetType().Name)), systemsListStyle);
}
}
private bool CheckIsHidden(TypeMeta meta)
{

View File

@ -9,34 +9,16 @@ using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomEditor(typeof(PipelineProcessMonitor))]
internal class PipelineProcessesMonitorEditor : Editor
internal class PipelineProcessesMonitorEditor : ExtendedEditor<PipelineProcessMonitor>
{
private static Type SYSTEM_INTERFACE_TYPE = typeof(IEcsProcess);
private bool _isInit = false;
private List<ProcessData> _processList = new List<ProcessData>();
private Dictionary<Type, int> _processeIndexes = new Dictionary<Type, int>();
private SystemData[] _systemsList;
private PipelineProcessMonitor Target => (PipelineProcessMonitor)target;
private bool IsShowInterfaces
protected override void OnInit()
{
get { return SettingsPrefs.instance.IsShowInterfaces; }
set { SettingsPrefs.instance.IsShowInterfaces = value; }
}
private bool IsShowHidden
{
get { return SettingsPrefs.instance.IsShowHidden; }
set { SettingsPrefs.instance.IsShowHidden = value; }
}
private void Init()
{
if (_isInit)
{
return;
}
_processList.Clear();
_processeIndexes.Clear();
IEnumerable<IEcsProcess> fileretSystems = Target.Pipeline.AllSystems;
@ -70,22 +52,24 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
}
}
_isInit = true;
}
private Vector2 _position;
private Vector2 _cellsize = new Vector2(EditorGUIUtility.singleLineHeight, EditorGUIUtility.singleLineHeight);
private Vector2 _nameCellSize = new Vector2(200f, 200f);
private (TypeMeta system, TypeMeta process) _selectedPointMeta = default;
public override void OnInspectorGUI()
protected override void DrawCustom()
{
EditorGUI.BeginChangeCheck();
IsShowHidden = EditorGUILayout.Toggle("Show Hidden", IsShowHidden);
if (EditorGUI.EndChangeCheck())
using (EcsGUI.CheckChanged())
{
_isInit = false;
IsShowHidden = EditorGUILayout.Toggle("Show Hidden", IsShowHidden);
if (EcsGUI.Changed)
{
Init();
}
}
Init();
GUILayout.Label("", GUILayout.ExpandWidth(true), GUILayout.Height(400f));
Rect rect = GUILayoutUtility.GetLastRect();

View File

@ -5,11 +5,9 @@ using UnityEditor;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomEditor(typeof(WorldMonitor))]
internal class WorldMonitorEditor : Editor
internal class WorldMonitorEditor : ExtendedEditor<WorldMonitor>
{
private WorldMonitor Target => (WorldMonitor)target;
public override void OnInspectorGUI()
protected override void DrawCustom()
{
EcsGUI.Layout.DrawWorldBaseInfo(Target.World);
}

View File

@ -51,11 +51,11 @@ namespace DCFApixels.DragonECS
EcsPipelineTemplate result = new EcsPipelineTemplate();
result.layers = new string[_layers.Length];
Array.Copy(_layers, result.layers, _layers.Length);
result.systems = new EcsPipelineTemplate.AddCommand[_records.Length];
for (int i = 0; i < result.systems.Length; i++)
result.records = new EcsPipelineTemplate.Record[_records.Length];
for (int i = 0; i < result.records.Length; i++)
{
ref var s = ref _records[i];
result.systems[i] = new EcsPipelineTemplate.AddCommand(s.target, s.parameters);
result.records[i] = new EcsPipelineTemplate.Record(s.target, s.parameters);
}
return result;
}
@ -64,10 +64,10 @@ namespace DCFApixels.DragonECS
{
_layers = new string[template.layers.Length];
Array.Copy(template.layers, _layers, template.layers.Length);
_records = new Record[template.systems.Length];
_records = new Record[template.records.Length];
for (int i = 0; i < _records.Length; i++)
{
ref var s = ref template.systems[i];
ref var s = ref template.records[i];
_records[i] = new Record(s.target, s.parameters);
}
}
@ -136,7 +136,7 @@ namespace DCFApixels.DragonECS
public struct Record
{
[SerializeReference]
[ReferenceButton(typeof(IEcsModule), typeof(IEcsProcess))]
[ReferenceButton(true, typeof(IEcsModule), typeof(IEcsProcess))]
public object target;
public AddParams parameters;
public Record(object target, AddParams parameters)

View File

@ -8,6 +8,7 @@ using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomPropertyDrawer(typeof(EcsPipelineTemplateSO.Record))]
//[CustomPropertyDrawer(typeof(EcsPipelineTemplate.Record))]
internal class EcsPipelineTemplateSORecordDrawer : ExtendedPropertyDrawer
{
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
@ -85,7 +86,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
CreateLists();
}
private void CreateLists()
{
_reorderableLayersList = new ReorderableList(serializedObject, _layersProp, true, false, true, true);
@ -151,15 +151,25 @@ namespace DCFApixels.DragonECS.Unity.Editors
using (EcsGUI.CheckChanged())
{
var prop = _recordsProp.GetArrayElementAtIndex(index);
var mrProp = prop.FindPropertyRelative(nameof(EcsPipelineTemplateSO.Record.target));
ITypeMeta meta = mrProp.managedReferenceValue == null ? null : mrProp.managedReferenceValue.GetMeta();
EcsGUI.DrawTypeMetaBlock(ref rect, prop, meta);
var targetProp = prop.FindPropertyRelative(nameof(EcsPipelineTemplateSO.Record.target));
var paramsProp = prop.FindPropertyRelative(nameof(EcsPipelineTemplateSO.Record.parameters));
bool isNull = targetProp.managedReferenceValue == null;
ITypeMeta meta = isNull ? null : targetProp.managedReferenceValue.GetMeta();
if (EcsGUI.DrawTypeMetaBlock(ref rect, prop, meta))
{
return;
}
EditorGUI.PropertyField(rect, prop, true);
}
}
private float OnReorderableRecordsListElementHeight(int index)
{
return EcsGUI.GetTypeMetaBlockHeight(EditorGUI.GetPropertyHeight(_recordsProp.GetArrayElementAtIndex(index)));
float result;
result = EditorGUI.GetPropertyHeight(_recordsProp.GetArrayElementAtIndex(index));
return EcsGUI.GetTypeMetaBlockHeight(result);
}
private void OnReorderableRecordsListAdd(ReorderableList list)
@ -202,7 +212,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
private void DrawLayoutNameList(SerializedProperty layersProp)
{
using (EcsGUI.SetVerticalLayout())
using (EcsGUI.Layout.BeginVertical())
{
GUILayout.Label(UnityEditorUtility.GetLabel(layersProp.displayName), EditorStyles.boldLabel);
_reorderableLayersList.DoLayoutList();
@ -210,7 +220,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
private void DrawRecordList(SerializedProperty recordsProp)
{
using (EcsGUI.SetVerticalLayout())
using (EcsGUI.Layout.BeginVertical())
{
GUILayout.Label(UnityEditorUtility.GetLabel(recordsProp.displayName), EditorStyles.boldLabel);
_reorderableRecordsList.DoLayoutList();

View File

@ -1,16 +1,18 @@
using DCFApixels.DragonECS;
using System;
using System;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Internal
{
internal sealed class ReferenceButtonAttribute : PropertyAttribute
{
public readonly Type[] predicateTypes;
public ReferenceButtonAttribute() : this(Array.Empty<Type>()) { }
public ReferenceButtonAttribute(params Type[] predicateTypes)
public readonly Type[] PredicateTypes;
public readonly bool IsHideButtonIfNotNull;
public ReferenceButtonAttribute(bool isHideButtonIfNotNull = false) : this(isHideButtonIfNotNull, Array.Empty<Type>()) { }
public ReferenceButtonAttribute(params Type[] predicateTypes) : this(false, predicateTypes) { }
public ReferenceButtonAttribute(bool isHideButtonIfNotNull, params Type[] predicateTypes)
{
this.predicateTypes = predicateTypes;
IsHideButtonIfNotNull = isHideButtonIfNotNull;
PredicateTypes = predicateTypes;
Array.Sort(predicateTypes, (a, b) => string.Compare(a.AssemblyQualifiedName, b.AssemblyQualifiedName, StringComparison.Ordinal));
}
}
@ -21,237 +23,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityObject = UnityEngine.Object;
[CustomPropertyDrawer(typeof(ReferenceButtonAttribute))]
internal sealed class ReferenceButtonAttributeDrawer : PropertyDrawer
internal sealed class ReferenceButtonAttributeDrawer : ExtendedPropertyDrawer<ReferenceButtonAttribute>
{
private static bool _isInit;
private static Type[] _serializableTypes;
private static Dictionary<PredicateTypesKey, ReferenceDropDown> _predicatTypesMenus = new Dictionary<PredicateTypesKey, ReferenceDropDown>();
private ReferenceButtonAttribute TargetAttribute => (ReferenceButtonAttribute)attribute;
#region PredicateTypesKey
private readonly struct PredicateTypesKey : IEquatable<PredicateTypesKey>
{
public readonly Type[] types;
public PredicateTypesKey(Type[] types)
{
this.types = types;
}
public bool Equals(PredicateTypesKey other)
{
if (types.Length != other.types.Length) { return false; }
for (int i = 0; i < types.Length; i++)
{
if (types[i] != other.types[i])
{
return false;
}
}
return true;
}
public override bool Equals(object obj)
{
return obj is PredicateTypesKey key && Equals(key);
}
public override int GetHashCode()
{
return HashCode.Combine(types);
}
public static implicit operator PredicateTypesKey(Type[] types) { return new PredicateTypesKey(types); }
public static implicit operator Type[](PredicateTypesKey key) { return key.types; }
}
#endregion
#region ReferenceDropDown
private class ReferenceDropDown : AdvancedDropdown
{
public readonly Type[] PredicateTypes;
public ReferenceDropDown(Type[] predicateTypes) : base(new AdvancedDropdownState())
{
PredicateTypes = predicateTypes;
minimumSize = new Vector2(minimumSize.x, EditorGUIUtility.singleLineHeight * 30);
}
protected override AdvancedDropdownItem BuildRoot()
{
int increment = 0;
var root = new Item(null, "Select Type", increment++);
root.AddChild(new Item(null, "<NULL>", increment++));
Dictionary<Key, Item> dict = new Dictionary<Key, Item>();
foreach (var type in _serializableTypes)
{
bool isAssignable = false;
foreach (Type predicateTypes in PredicateTypes)
{
if (predicateTypes.IsAssignableFrom(type))
{
isAssignable = true;
break;
}
}
if (isAssignable)
{
ITypeMeta meta = type.ToMeta();
string description = meta.Description.Text;
MetaGroup group = meta.Group;
var splitedGroup = group.Splited;
Item parent = root;
if (splitedGroup.Count > 0)
{
int i = 1;
foreach (var subgroup in splitedGroup)
{
Key key = new Key(group, i);
if (dict.TryGetValue(key, out Item item) == false)
{
item = new Item(null, subgroup, increment++);
parent.AddChild(item);
dict.Add(key, item);
}
parent = item;
i++;
}
}
var leafItem = new Item(type, meta.Name, increment++);
parent.AddChild(leafItem);
}
}
return root;
}
protected override void ItemSelected(AdvancedDropdownItem item)
{
base.ItemSelected(item);
OnSelected((Item)item);
}
public event Action<Item> OnSelected = delegate { };
public class Item : AdvancedDropdownItem
{
public readonly Type Type;
public Item(Type type, string name, int id) : base(name)
{
Type = type;
this.id = id;
}
}
#region Key
private readonly struct Key : IEquatable<Key>
{
public readonly MetaGroup Group;
public readonly int Length;
public Key(MetaGroup group, int length)
{
Group = group;
Length = length;
}
public bool Equals(Key other)
{
if (Length != other.Length)
{
return false;
}
IEnumerator<string> splitedEnum = Group.Splited.GetEnumerator();
IEnumerator<string> splitedEnumOther = other.Group.Splited.GetEnumerator();
for (int i = 0; i < Length; i++)
{
splitedEnum.MoveNext();
splitedEnumOther.MoveNext();
if (splitedEnum.Current != splitedEnumOther.Current)
{
return false;
}
}
return true;
}
public override bool Equals(object obj)
{
return obj is Key key && Equals(key);
}
public override int GetHashCode()
{
unchecked
{
int state = Length;
state ^= state << 13;
state ^= state >> 17;
state ^= state << 5;
var x = Group.Splited.GetEnumerator();
x.MoveNext();
return x.Current.GetHashCode() ^ state;
};
}
}
#endregion
}
#endregion
#region Init
private static void Init()
{
if (_isInit) { return; }
List<Type> types = new List<Type>();
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var targetTypes = assembly.GetTypes().Where(type =>
(type.IsGenericType || type.IsAbstract || type.IsInterface) == false &&
type.IsSubclassOf(typeof(UnityObject)) == false &&
type.GetCustomAttribute<SerializableAttribute>() != null);
types.AddRange(targetTypes);
}
_serializableTypes = types.ToArray();
_isInit = true;
}
private static ReferenceDropDown GetReferenceDropDown(Type[] predicatTypes)
{
Init();
if (_predicatTypesMenus.TryGetValue(predicatTypes, out ReferenceDropDown menu) == false)
{
menu = new ReferenceDropDown(predicatTypes);
menu.OnSelected += SelectComponent;
_predicatTypesMenus.Add(predicatTypes, menu);
}
return menu;
}
[ThreadStatic]
private static SerializedProperty currentProperty;
private static void SelectComponent(ReferenceDropDown.Item item)
{
Type type = item.Type;
if (type == null)
{
currentProperty.managedReferenceValue = null;
}
else
{
currentProperty.managedReferenceValue = Activator.CreateInstance(type);
currentProperty.isExpanded = true;
}
currentProperty.serializedObject.ApplyModifiedProperties();
EcsGUI.Changed = true;
}
#endregion
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
if (property.managedReferenceValue != null)
@ -260,13 +36,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
else
{
return EditorGUIUtility.singleLineHeight;
return OneLineHeight;
}
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
{
Rect selButtnoRect = position;
selButtnoRect.height = EditorGUIUtility.singleLineHeight;
selButtnoRect.height = OneLineHeight;
DrawSelectionPopup(selButtnoRect, property, label);
if (property.managedReferenceValue != null)
@ -283,41 +60,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
private void DrawSelectionPopup(Rect position, SerializedProperty property, GUIContent label)
{
Rect buttonRect = RectUtility.AddPadding(position, EditorGUIUtility.labelWidth, 0f, 0f, 0f);
object obj = property.hasMultipleDifferentValues ? null : property.managedReferenceValue;
if (GUI.Button(buttonRect, obj == null ? "Select..." : obj.GetMeta().Name, EditorStyles.layerMaskField))
{
currentProperty = property;
if (TargetAttribute.predicateTypes.Length == 0)
{
GetReferenceDropDown(new Type[1] { fieldInfo.FieldType }).Show(buttonRect);
}
else
{
GetReferenceDropDown(TargetAttribute.predicateTypes).Show(buttonRect);
}
}
Rect buttonRect = position.AddPadding(EditorGUIUtility.labelWidth, 0f, 0f, 0f);
EcsGUI.DrawSelectReferenceButton(buttonRect, property, Attribute.PredicateTypes.Length == 0 ? new Type[1] { fieldInfo.FieldType } : Attribute.PredicateTypes, Attribute.IsHideButtonIfNotNull);
}
}
}
#endif
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.SYSTEMS_GROUP)]
[System.Serializable] public class TestSystem0 : IEcsProcess { }
[System.Serializable] public class TestSystem1 : IEcsProcess { }
[System.Serializable] public class TestSystem2 : IEcsProcess { }
[System.Serializable] public class TestSystem3 : IEcsProcess { }
[MetaGroup(EcsConsts.PACK_GROUP)]
[System.Serializable] public class TestSystem4 : IEcsProcess { }
[MetaGroup(EcsConsts.PACK_GROUP)]
[System.Serializable] public class TestSystem7 : IEcsProcess { }
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.AUTHOR)]
[System.Serializable] public class TestSystem8 : IEcsProcess { }
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.AUTHOR)]
[System.Serializable] public class _TestSystemX : IEcsProcess { }
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.AUTHOR)]
[System.Serializable] public class TestSystem9 : IEcsProcess { }
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.AUTHOR)]
[System.Serializable] public class TestSystem5 : IEcsProcess { }
[System.Serializable] public class TestSystem6 : IEcsProcess { }
#endif

View File

@ -23,30 +23,23 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
}
[CustomPropertyDrawer(typeof(ComponentTemplateReferenceAttribute), true)]
internal class ComponentTemplateReferenceDrawer : PropertyDrawer
internal class ComponentTemplateReferenceDrawer : ExtendedPropertyDrawer<ComponentTemplateReferenceAttribute>
{
private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f);
private float Padding => EditorGUIUtility.standardVerticalSpacing;
private float SingleLineWithPadding => EditorGUIUtility.singleLineHeight + Padding * 4f;
private const float DamagedComponentHeight = 18f * 2f;
private static bool _isInit;
private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f);
private static ComponentDropDown _componentDropDown;
private float SingleLineWithPadding => OneLineHeight + Padding * 4f;
private float Padding => Spacing;
protected override bool IsInit => _componentDropDown != null;
#region Init
private static void Init()
protected override void OnStaticInit()
{
if (_componentDropDown == null) { _isInit = false; }
if (_isInit) { return; }
_componentDropDown = new ComponentDropDown();
_componentDropDown.OnSelected += SelectComponent;
_isInit = true;
}
[ThreadStatic]
private static SerializedProperty currentProperty;
private static void SelectComponent(ComponentDropDown.Item item)
@ -93,8 +86,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
public override void OnGUI(Rect position, SerializedProperty componentRefProp, GUIContent label)
protected override void DrawCustom(Rect position, SerializedProperty componentRefProp, GUIContent label)
{
if (componentRefProp.propertyType == SerializedPropertyType.ManagedReference == false)
{

View File

@ -7,12 +7,11 @@ using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
internal abstract class EntityTemplateEditorBase : Editor
internal abstract class EntityTemplateEditorBase<T> : ExtendedEditor<ITemplateInternal>
{
private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f);
private ComponentDropDown _componentDropDown;
private bool _isInit = false;
private static ComponentColorMode AutoColorMode
{
@ -21,16 +20,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
#region Init
private void Init()
protected override bool IsInit => _componentDropDown != null;
protected override void OnInit()
{
if (_componentDropDown == null) { _isInit = false; }
if (_isInit) { return; }
_componentDropDown = new ComponentDropDown();
_componentDropDown.OnSelected += OnAddComponent;
_isInit = true;
}
#endregion
@ -167,60 +161,65 @@ namespace DCFApixels.DragonECS.Unity.Editors
optionButton.center += Vector2.up * padding * 2f;
bool cancelExpanded = EcsGUI.HitTest(optionButton) && Event.current.type == EventType.MouseUp;
EditorGUI.BeginChangeCheck();
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(alphaPanelColor));
using (EcsGUI.CheckChanged())
{
//EditorGUI.BeginChangeCheck();
#region Draw Component Block
//Close button
optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
if (EcsGUI.CloseButton(optionButton))
{
OnRemoveComponentAt(index);
return;
}
//Canceling isExpanded
if (cancelExpanded)
{
componentProperty.isExpanded = !componentProperty.isExpanded;
}
//Edit script button
if (UnityEditorUtility.TryGetScriptAsset(componentType, out MonoScript script))
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
EcsGUI.ScriptAssetButton(optionButton, script);
}
//Description icon
if (string.IsNullOrEmpty(description) == false)
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
EcsGUI.DescriptionIcon(optionButton, description);
}
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(alphaPanelColor));
if (propCount <= 0)
{
EcsGUI.Layout.DrawEmptyComponentProperty(componentRefProp, name, isEmpty);
}
else
{
GUIContent label = UnityEditorUtility.GetLabel(name);
if (componentProperty.propertyType == SerializedPropertyType.Generic)
#region Draw Component Block
//Close button
optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
if (EcsGUI.CloseButton(optionButton))
{
EditorGUILayout.PropertyField(componentProperty, label, true);
OnRemoveComponentAt(index);
return;
}
//Canceling isExpanded
if (cancelExpanded)
{
componentProperty.isExpanded = !componentProperty.isExpanded;
}
//Edit script button
if (UnityEditorUtility.TryGetScriptAsset(componentType, out MonoScript script))
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
EcsGUI.ScriptAssetButton(optionButton, script);
}
//Description icon
if (string.IsNullOrEmpty(description) == false)
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
EcsGUI.DescriptionIcon(optionButton, description);
}
if (propCount <= 0)
{
EcsGUI.Layout.DrawEmptyComponentProperty(componentRefProp, name, isEmpty);
}
else
{
Rect r = RectUtility.AddPadding(GUILayoutUtility.GetRect(label, EditorStyles.objectField), 0, 20f, 0, 0);
EditorGUI.PropertyField(r, componentProperty, label, true);
GUIContent label = UnityEditorUtility.GetLabel(name);
if (componentProperty.propertyType == SerializedPropertyType.Generic)
{
EditorGUILayout.PropertyField(componentProperty, label, true);
}
else
{
Rect r = RectUtility.AddPadding(GUILayoutUtility.GetRect(label, EditorStyles.objectField), 0, 20f, 0, 0);
EditorGUI.PropertyField(r, componentProperty, label, true);
}
}
}
#endregion
#endregion
GUILayout.EndVertical();
GUILayout.EndVertical();
if (EditorGUI.EndChangeCheck())
{
componentProperty.serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
//if (EditorGUI.EndChangeCheck())
if (EcsGUI.Changed)
{
componentProperty.serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
}
}
}
private void DrawDamagedComponent_Replaced(SerializedProperty componentRefProp, int index)
@ -254,19 +253,19 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
[CustomEditor(typeof(ScriptableEntityTemplate), true)]
internal class EntityTemplatePresetEditor : EntityTemplateEditorBase
internal class EntityTemplatePresetEditor : EntityTemplateEditorBase<ScriptableEntityTemplate>
{
public override void OnInspectorGUI()
protected override void DrawCustom()
{
Draw((ITemplateInternal)target);
Draw(Target);
}
}
[CustomEditor(typeof(MonoEntityTemplate), true)]
internal class EntityTemplateEditor : EntityTemplateEditorBase
internal class EntityTemplateEditor : EntityTemplateEditorBase<MonoEntityTemplate>
{
public override void OnInspectorGUI()
protected override void DrawCustom()
{
Draw((ITemplateInternal)target);
Draw(Target);
}
}
}

View File

@ -1,8 +1,11 @@
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using UnityComponent = UnityEngine.Component;
using UnityObject = UnityEngine.Object;
@ -14,6 +17,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
#region Scores
private static int _changedCounter = 0;
private static bool _changed = false;
private static bool _delayedChanged = false;
public static int ChangedCounter => _changedCounter;
public static bool Changed
@ -21,14 +25,27 @@ namespace DCFApixels.DragonECS.Unity.Editors
get
{
_changed = _changed || GUI.changed;
GUI.changed = _changed;
return _changed;
}
set
{
_changed = _changed || GUI.changed || value;
_changed = Changed || value;
GUI.changed = _changed;
}
}
public static bool DelayedChanged
{
get
{
return _delayedChanged;
}
set
{
_delayedChanged = DelayedChanged || value;
Changed = _delayedChanged;
}
}
public readonly struct CheckChangedScope : IDisposable
{
private readonly bool _value;
@ -47,25 +64,33 @@ namespace DCFApixels.DragonECS.Unity.Editors
if (_changedCounter <= 0)
{
_changedCounter = 0;
_changed = false;
_changed = _delayedChanged;
_delayedChanged = false;
}
}
}
public struct VerticalLayoutScope : IDisposable
public readonly struct CheckChangedScopeWithAutoApply : IDisposable
{
public static VerticalLayoutScope New() { GUILayout.BeginVertical(); return new VerticalLayoutScope(); }
public void Dispose() { GUILayout.EndVertical(); }
private readonly CheckChangedScope _scope;
private readonly SerializedObject _serializedObject;
public CheckChangedScopeWithAutoApply(SerializedObject serializedObject)
{
_scope = CheckChangedScope.New();
_serializedObject = serializedObject;
}
public void Dispose()
{
if (Changed)
{
_serializedObject.ApplyModifiedProperties();
}
_scope.Dispose();
}
}
public struct HorizontalLayoutScope : IDisposable
public struct ScrollViewScope : IDisposable
{
public static HorizontalLayoutScope New() { GUILayout.BeginVertical(); return new HorizontalLayoutScope(); }
public void Dispose() { GUILayout.EndVertical(); }
}
public struct ScrollViewLayoutScope : IDisposable
{
public ScrollViewLayoutScope(ref Vector2 pos) { pos = GUILayout.BeginScrollView(pos); }
public void Dispose() { GUILayout.EndScrollView(); }
public ScrollViewScope(Rect position, ref Vector2 pos, Rect viewRect) { pos = GUI.BeginScrollView(position, pos, viewRect); }
public void Dispose() { GUI.EndScrollView(); }
}
public readonly struct LabelWidthScope : IDisposable
{
@ -172,10 +197,41 @@ namespace DCFApixels.DragonECS.Unity.Editors
public void Dispose() { Target.fontStyle = _value; }
}
public static partial class Layout
{
public struct VerticalScope : IDisposable
{
public VerticalScope(GUILayoutOption[] options) { GUILayout.BeginVertical(options); }
public VerticalScope(GUIStyle style, GUILayoutOption[] options) { GUILayout.BeginVertical(style, options); }
public void Dispose() { GUILayout.EndVertical(); }
}
public struct HorizontalScope : IDisposable
{
public HorizontalScope(GUILayoutOption[] options) { GUILayout.BeginHorizontal(options); }
public HorizontalScope(GUIStyle style, GUILayoutOption[] options) { GUILayout.BeginHorizontal(style, options); }
public void Dispose() { GUILayout.EndHorizontal(); }
}
public struct ScrollViewScope : IDisposable
{
public ScrollViewScope(ref Vector2 pos, GUILayoutOption[] options) { pos = GUILayout.BeginScrollView(pos, options); }
public ScrollViewScope(ref Vector2 pos, GUIStyle style, GUILayoutOption[] options) { pos = GUILayout.BeginScrollView(pos, style, options); }
public void Dispose() { GUILayout.EndScrollView(); }
}
public static ScrollViewScope BeginScrollView(ref Vector2 pos) => new ScrollViewScope(ref pos, Array.Empty<GUILayoutOption>());
public static HorizontalScope BeginHorizontal() => new HorizontalScope(Array.Empty<GUILayoutOption>());
public static VerticalScope BeginVertical() => new VerticalScope(Array.Empty<GUILayoutOption>());
public static ScrollViewScope BeginScrollView(ref Vector2 pos, params GUILayoutOption[] options) => new ScrollViewScope(ref pos, options);
public static HorizontalScope BeginHorizontal(params GUILayoutOption[] options) => new HorizontalScope(options);
public static VerticalScope BeginVertical(params GUILayoutOption[] options) => new VerticalScope(options);
public static ScrollViewScope BeginScrollView(ref Vector2 pos, GUIStyle style, params GUILayoutOption[] options) => new ScrollViewScope(ref pos, style, options);
public static HorizontalScope BeginHorizontal(GUIStyle style, params GUILayoutOption[] options) => new HorizontalScope(style, options);
public static VerticalScope BeginVertical(GUIStyle style, params GUILayoutOption[] options) => new VerticalScope(style, options);
}
public static CheckChangedScope CheckChanged() => CheckChangedScope.New();
public static ScrollViewLayoutScope SetScrollViewLayout(ref Vector2 pos) => new ScrollViewLayoutScope(ref pos);
public static HorizontalLayoutScope SetHorizontalLayout() => HorizontalLayoutScope.New();
public static VerticalLayoutScope SetVerticalLayout() => VerticalLayoutScope.New();
public static CheckChangedScopeWithAutoApply CheckChanged(SerializedObject serializedObject) => new CheckChangedScopeWithAutoApply(serializedObject);
public static ScrollViewScope BeginScrollView(Rect position, ref Vector2 pos, Rect viewRect) => new ScrollViewScope(position, ref pos, viewRect);
public static FontStyleScope SetFontStyle(GUIStyle target, FontStyle value) => new FontStyleScope(target, value);
public static FontStyleScope SetFontStyle(FontStyle value) => new FontStyleScope(GUI.skin.label, value);
public static FontStyleScope SetFontStyle(GUIStyle target) => new FontStyleScope(target);
@ -196,6 +252,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
public static EditorGUI.DisabledScope Enable => new EditorGUI.DisabledScope(false);
public static EditorGUI.DisabledScope Disable => new EditorGUI.DisabledScope(true);
public static EditorGUI.DisabledScope SetEnable(bool value) => new EditorGUI.DisabledScope(!value);
public static LabelWidthScope SetLabelWidth(float value) => new LabelWidthScope(value);
#endregion
private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
@ -208,6 +265,28 @@ namespace DCFApixels.DragonECS.Unity.Editors
public static float EntityBarHeight => EditorGUIUtility.singleLineHeight + 3f;
private static Type[] _serializableTypes;
static EcsGUI()
{
InitSerializableTypes();
}
private static void InitSerializableTypes()
{
List<Type> types = new List<Type>();
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var targetTypes = assembly.GetTypes().Where(type =>
(type.IsGenericType || type.IsAbstract || type.IsInterface) == false &&
type.IsSubclassOf(typeof(UnityObject)) == false &&
type.GetCustomAttribute<SerializableAttribute>() != null);
types.AddRange(targetTypes);
}
_serializableTypes = types.ToArray();
}
#region Properties
private static ComponentColorMode AutoColorMode
{
@ -224,6 +303,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
get { return SettingsPrefs.instance.IsShowRuntimeComponents; }
set { SettingsPrefs.instance.IsShowRuntimeComponents = value; }
}
private static float OneLineHeight
{
get => EditorGUIUtility.singleLineHeight;
}
private static float Spacing
{
get => EditorGUIUtility.standardVerticalSpacing;
}
#endregion
#region enums
@ -379,7 +466,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
public static void EntityBar(Rect position, bool isPlaceholder, EntityStatus status, int id = 0, short gen = 0, short world = 0)
{
using (new LabelWidthScope(0f))
using (SetLabelWidth(0f))
{
var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(position, 3f);
@ -405,7 +492,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
private static void EntityBar_Internal(Rect position, bool isPlaceHolder, int id = 0, short gen = 0, short world = 0)
{
using (new LabelWidthScope(0f))
using (SetLabelWidth(0f))
{
Color w = Color.gray;
w.a = 0.6f;
@ -451,11 +538,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
return DrawTypeMetaBlockPadding * 2 + contentHeight;
}
public static void DrawTypeMetaBlock(ref Rect position, SerializedProperty property, ITypeMeta meta)
public static bool DrawTypeMetaBlock(ref Rect position, SerializedProperty property, ITypeMeta meta)
{
if (meta == null)
{
return;
return false;
}
GUIContent label = UnityEditorUtility.GetLabel(property.displayName);
@ -483,56 +570,58 @@ namespace DCFApixels.DragonECS.Unity.Editors
Color alphaPanelColor = panelColor;
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
EditorGUI.BeginChangeCheck();
EditorGUI.DrawRect(position, alphaPanelColor);
Rect paddingPosition = RectUtility.AddPadding(position, DrawTypeMetaBlockPadding * 2f);
Rect optionButton = position;
optionButton.center -= new Vector2(0, optionButton.height);
optionButton.yMin = optionButton.yMax;
optionButton.yMax += HeadIconsRect.height;
optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * DrawTypeMetaBlockPadding * 1f;
//Canceling isExpanded
if (HitTest(optionButton) && Event.current.type == EventType.MouseUp)
using (CheckChanged())
{
property.isExpanded = !property.isExpanded;
}
EditorGUI.DrawRect(position, alphaPanelColor);
//Close button
optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
if (CloseButton(optionButton))
{
property.ResetValues();
return;
}
//Edit script button
if (UnityEditorUtility.TryGetScriptAsset(meta.Type, out MonoScript script))
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
ScriptAssetButton(optionButton, script);
}
//Description icon
if (string.IsNullOrEmpty(description) == false)
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
DescriptionIcon(optionButton, description);
}
Rect paddingPosition = RectUtility.AddPadding(position, DrawTypeMetaBlockPadding * 2f);
//if (string.IsNullOrEmpty(label.text))
//{
// EditorGUI.indentLevel++;
// EditorGUI.PrefixLabel(position.AddPadding(0, 0, 0, position.height - SingleLineWithPadding), UnityEditorUtility.GetLabel(name));
// EditorGUI.indentLevel--;
//}
//else
//{
// GUI.Label(position.AddPadding(EditorGUIUtility.labelWidth, 0, 0, position.height - SingleLineWithPadding), name);
//}
Rect optionButton = position;
optionButton.center -= new Vector2(0, optionButton.height);
optionButton.yMin = optionButton.yMax;
optionButton.yMax += HeadIconsRect.height;
optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * DrawTypeMetaBlockPadding * 1f;
//Canceling isExpanded
if (HitTest(optionButton) && Event.current.type == EventType.MouseUp)
{
property.isExpanded = !property.isExpanded;
}
position = paddingPosition;
//Close button
optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
if (CloseButton(optionButton))
{
property.ResetValues();
return true;
}
//Edit script button
if (UnityEditorUtility.TryGetScriptAsset(meta.Type, out MonoScript script))
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
ScriptAssetButton(optionButton, script);
}
//Description icon
if (string.IsNullOrEmpty(description) == false)
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
DescriptionIcon(optionButton, description);
}
//if (string.IsNullOrEmpty(label.text))
//{
// EditorGUI.indentLevel++;
// EditorGUI.PrefixLabel(position.AddPadding(0, 0, 0, position.height - SingleLineWithPadding), UnityEditorUtility.GetLabel(name));
// EditorGUI.indentLevel--;
//}
//else
//{
// GUI.Label(position.AddPadding(EditorGUIUtility.labelWidth, 0, 0, position.height - SingleLineWithPadding), name);
//}
position = paddingPosition;
}
return false;
}
#endregion
@ -647,7 +736,220 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
#endregion
#region SerializeReferenceFixer
#region SerializeReference utils
private static Dictionary<PredicateTypesKey, ReferenceDropDown> _predicatTypesMenus = new Dictionary<PredicateTypesKey, ReferenceDropDown>();
[ThreadStatic]
private static SerializedProperty _currentProperty;
#region Init
private static ReferenceDropDown GetReferenceDropDown(Type[] predicatTypes)
{
if (_predicatTypesMenus.TryGetValue(predicatTypes, out ReferenceDropDown menu) == false)
{
menu = new ReferenceDropDown(predicatTypes);
menu.OnSelected += SelectComponent;
_predicatTypesMenus.Add(predicatTypes, menu);
}
return menu;
}
private static void SelectComponent(ReferenceDropDown.Item item)
{
Type type = item.Type;
if (type == null)
{
_currentProperty.managedReferenceValue = null;
}
else
{
_currentProperty.managedReferenceValue = Activator.CreateInstance(type);
_currentProperty.isExpanded = true;
}
_currentProperty.serializedObject.ApplyModifiedProperties();
DelayedChanged = true;
}
#endregion
#region PredicateTypesKey
private readonly struct PredicateTypesKey : IEquatable<PredicateTypesKey>
{
public readonly Type[] types;
public PredicateTypesKey(Type[] types)
{
this.types = types;
}
public bool Equals(PredicateTypesKey other)
{
if (types.Length != other.types.Length) { return false; }
for (int i = 0; i < types.Length; i++)
{
if (types[i] != other.types[i])
{
return false;
}
}
return true;
}
public override bool Equals(object obj)
{
return obj is PredicateTypesKey key && Equals(key);
}
public override int GetHashCode()
{
return HashCode.Combine(types);
}
public static implicit operator PredicateTypesKey(Type[] types) { return new PredicateTypesKey(types); }
public static implicit operator Type[](PredicateTypesKey key) { return key.types; }
}
#endregion
#region ReferenceDropDown
private class ReferenceDropDown : AdvancedDropdown
{
public readonly Type[] PredicateTypes;
public ReferenceDropDown(Type[] predicateTypes) : base(new AdvancedDropdownState())
{
PredicateTypes = predicateTypes;
minimumSize = new Vector2(minimumSize.x, EditorGUIUtility.singleLineHeight * 30);
}
protected override AdvancedDropdownItem BuildRoot()
{
int increment = 0;
var root = new Item(null, "Select Type", increment++);
root.AddChild(new Item(null, "<NULL>", increment++));
Dictionary<Key, Item> dict = new Dictionary<Key, Item>();
foreach (var type in _serializableTypes)
{
bool isAssignable = false;
foreach (Type predicateTypes in PredicateTypes)
{
if (predicateTypes.IsAssignableFrom(type))
{
isAssignable = true;
break;
}
}
if (isAssignable)
{
ITypeMeta meta = type.ToMeta();
string description = meta.Description.Text;
MetaGroup group = meta.Group;
var splitedGroup = group.Splited;
Item parent = root;
if (splitedGroup.Count > 0)
{
int i = 1;
foreach (var subgroup in splitedGroup)
{
Key key = new Key(group, i);
if (dict.TryGetValue(key, out Item item) == false)
{
item = new Item(null, subgroup, increment++);
parent.AddChild(item);
dict.Add(key, item);
}
parent = item;
i++;
}
}
var leafItem = new Item(type, meta.Name, increment++);
parent.AddChild(leafItem);
}
}
return root;
}
protected override void ItemSelected(AdvancedDropdownItem item)
{
base.ItemSelected(item);
OnSelected((Item)item);
}
public event Action<Item> OnSelected = delegate { };
public class Item : AdvancedDropdownItem
{
public readonly Type Type;
public Item(Type type, string name, int id) : base(name)
{
Type = type;
this.id = id;
}
}
#region Key
private readonly struct Key : IEquatable<Key>
{
public readonly MetaGroup Group;
public readonly int Length;
public Key(MetaGroup group, int length)
{
Group = group;
Length = length;
}
public bool Equals(Key other)
{
if (Length != other.Length)
{
return false;
}
IEnumerator<string> splitedEnum = Group.Splited.GetEnumerator();
IEnumerator<string> splitedEnumOther = other.Group.Splited.GetEnumerator();
for (int i = 0; i < Length; i++)
{
splitedEnum.MoveNext();
splitedEnumOther.MoveNext();
if (splitedEnum.Current != splitedEnumOther.Current)
{
return false;
}
}
return true;
}
public override bool Equals(object obj)
{
return obj is Key key && Equals(key);
}
public override int GetHashCode()
{
unchecked
{
int state = Length;
state ^= state << 13;
state ^= state >> 17;
state ^= state << 5;
var x = Group.Splited.GetEnumerator();
x.MoveNext();
return x.Current.GetHashCode() ^ state;
};
}
}
#endregion
}
#endregion
public static void DrawSelectReferenceButton(Rect position, SerializedProperty property, Type[] sortedPredicateTypes, bool isHideButtonIfNotNull)
{
object obj = property.hasMultipleDifferentValues ? null : property.managedReferenceValue;
if (!isHideButtonIfNotNull || obj == null)
{
if (GUI.Button(position, obj == null ? "Select..." : obj.GetMeta().Name, EditorStyles.layerMaskField))
{
_currentProperty = property;
GetReferenceDropDown(sortedPredicateTypes).Show(position);
}
}
else
{
GUI.Label(position, obj == null ? "Select..." : obj.GetMeta().Name);
}
}
#endregion
@ -656,7 +958,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
public static class Layout
public static partial class Layout
{
public static void ScriptAssetButton(MonoScript script, params GUILayoutOption[] options)
{
@ -934,4 +1236,4 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
}
}
#endif
#endif

View File

@ -25,7 +25,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
private bool _isStaticInit = false;
private bool _isInit = false;
protected float SingleLineHeight
protected float OneLineHeight
{
get => EditorGUIUtility.singleLineHeight;
}
@ -33,6 +33,17 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
get => EditorGUIUtility.standardVerticalSpacing;
}
protected bool IsShowInterfaces
{
get { return SettingsPrefs.instance.IsShowInterfaces; }
set { SettingsPrefs.instance.IsShowInterfaces = value; }
}
protected bool IsShowHidden
{
get { return SettingsPrefs.instance.IsShowHidden; }
set { SettingsPrefs.instance.IsShowHidden = value; }
}
protected bool IsMultipleTargets => targets.Length > 1;
protected virtual bool IsStaticInit { get { return _isStaticInit; } }
protected virtual bool IsInit { get { return _isInit; } }
@ -53,7 +64,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
public sealed override void OnInspectorGUI()
{
using (EcsGUI.CheckChanged())
using (EcsGUI.CheckChanged(serializedObject))
{
StaticInit();
Init();
@ -73,7 +84,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
return serializedObject.FindProperty(name);
}
}
internal abstract class ExtendedEditor<T> : ExtendedEditor where T : UnityObject
internal abstract class ExtendedEditor<T> : ExtendedEditor
{
public T Target
@ -132,7 +143,16 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
get => EditorGUIUtility.standardVerticalSpacing;
}
protected bool IsShowInterfaces
{
get { return SettingsPrefs.instance.IsShowInterfaces; }
set { SettingsPrefs.instance.IsShowInterfaces = value; }
}
protected bool IsShowHidden
{
get { return SettingsPrefs.instance.IsShowHidden; }
set { SettingsPrefs.instance.IsShowHidden = value; }
}
protected virtual bool IsStaticInit { get { return _isStaticInit; } }
protected virtual bool IsInit { get { return _isInit; } }
protected void StaticInit()
@ -152,7 +172,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
using (EcsGUI.CheckChanged())
using (EcsGUI.CheckChanged(property.serializedObject))
{
StaticInit();
Init();