update editors

This commit is contained in:
Mikhail 2024-09-16 19:31:01 +08:00
parent 1aa51c2a3c
commit 25251f044f
10 changed files with 376 additions and 194 deletions

View File

@ -137,7 +137,8 @@ namespace DCFApixels.DragonECS
{ {
[SerializeReference] [SerializeReference]
[ReferenceButton(true, typeof(IEcsModule), typeof(IEcsProcess))] [ReferenceButton(true, typeof(IEcsModule), typeof(IEcsProcess))]
public object target; [ArrayElement]
public object target;// нельзя менять поярдок полей, иначе это поломает отрисовку в инспекторе изза применения property.Next(bool);
public AddParams parameters; public AddParams parameters;
public Record(object target, AddParams parameters) public Record(object target, AddParams parameters)
{ {

View File

@ -8,7 +8,6 @@ using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors namespace DCFApixels.DragonECS.Unity.Editors
{ {
[CustomPropertyDrawer(typeof(EcsPipelineTemplateSO.Record))] [CustomPropertyDrawer(typeof(EcsPipelineTemplateSO.Record))]
//[CustomPropertyDrawer(typeof(EcsPipelineTemplate.Record))]
internal class EcsPipelineTemplateSORecordDrawer : ExtendedPropertyDrawer internal class EcsPipelineTemplateSORecordDrawer : ExtendedPropertyDrawer
{ {
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label) protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
@ -28,8 +27,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
Rect subPosition = position; Rect subPosition = position;
int depth = -1; int depth = -1;
property.Next(true);
float height = 0f; float height = 0f;
property.Next(true);
do do
{ {
subPosition.y += height; subPosition.y += height;
@ -71,7 +71,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
private SerializedProperty _recordsProp; private SerializedProperty _recordsProp;
private ReorderableList _reorderableLayersList; private ReorderableList _reorderableLayersList;
private ReorderableList _reorderableRecordsList; private ReorderableList _reorderableRecordsList;
private SystemsDropDown _systemsDropDown;
protected override bool IsInit protected override bool IsInit
{ {
@ -94,14 +94,29 @@ namespace DCFApixels.DragonECS.Unity.Editors
_reorderableLayersList.drawElementCallback += OnReorderableLayersListDrawElement; _reorderableLayersList.drawElementCallback += OnReorderableLayersListDrawElement;
_reorderableLayersList.onReorderCallback += OnReorderableListReorder; _reorderableLayersList.onReorderCallback += OnReorderableListReorder;
_reorderableRecordsList = new ReorderableList(serializedObject, _recordsProp, true, false, true, true); _reorderableRecordsList = new ReorderableList(serializedObject, _recordsProp, true, false, false, false);
_reorderableRecordsList.onAddCallback += OnReorderableRecordsListAdd; _reorderableRecordsList.onAddCallback += OnReorderableRecordsListAdd;
_reorderableRecordsList.onRemoveCallback += OnReorderableListRemove; _reorderableRecordsList.onRemoveCallback += OnReorderableListRemove;
_reorderableRecordsList.drawElementCallback += OnReorderableRecordsListDrawElement; _reorderableRecordsList.drawElementCallback += OnReorderableListDrawEmptyElement;
_reorderableRecordsList.drawElementBackgroundCallback += OnReorderableRecordsListDrawElement;
_reorderableRecordsList.drawNoneElementCallback += OnReorderableRecordsListDrawNoneElement;
_reorderableRecordsList.elementHeightCallback += OnReorderableRecordsListElementHeight; _reorderableRecordsList.elementHeightCallback += OnReorderableRecordsListElementHeight;
_reorderableRecordsList.onReorderCallback += OnReorderableListReorder; _reorderableRecordsList.onReorderCallback += OnReorderableListReorder;
_reorderableRecordsList.showDefaultBackground = false;
_reorderableRecordsList.footerHeight = 0f;
_reorderableRecordsList.headerHeight = 0f;
_reorderableRecordsList.elementHeight = 0f;
_systemsDropDown = new SystemsDropDown();
} }
private void OnReorderableRecordsListDrawNoneElement(Rect rect)
{
}
private void OnReorderableListDrawEmptyElement(Rect rect, int index, bool isActive, bool isFocused) { }
private void OnReorderableListReorder(ReorderableList list) private void OnReorderableListReorder(ReorderableList list)
{ {
EcsGUI.Changed = true; EcsGUI.Changed = true;
@ -148,17 +163,22 @@ namespace DCFApixels.DragonECS.Unity.Editors
#region _reorderableRecordsList #region _reorderableRecordsList
private void OnReorderableRecordsListDrawElement(Rect rect, int index, bool isActive, bool isFocused) private void OnReorderableRecordsListDrawElement(Rect rect, int index, bool isActive, bool isFocused)
{ {
if (index < 0) { return; }
rect = rect.AddPadding(OneLineHeight + Spacing, Spacing * 2f, Spacing, Spacing);
using (EcsGUI.CheckChanged()) using (EcsGUI.CheckChanged())
{ {
var prop = _recordsProp.GetArrayElementAtIndex(index); if (Event.current.type == EventType.Used)
{
return;
}
//EcsDebug.PrintPass(index);
SerializedProperty prop = _recordsProp.GetArrayElementAtIndex(index);
var targetProp = prop.FindPropertyRelative(nameof(EcsPipelineTemplateSO.Record.target)); var targetProp = prop.FindPropertyRelative(nameof(EcsPipelineTemplateSO.Record.target));
var paramsProp = prop.FindPropertyRelative(nameof(EcsPipelineTemplateSO.Record.parameters));
bool isNull = targetProp.managedReferenceValue == null; bool isNull = targetProp.managedReferenceValue == null;
ITypeMeta meta = isNull ? null : targetProp.managedReferenceValue.GetMeta(); ITypeMeta meta = isNull ? null : targetProp.managedReferenceValue.GetMeta();
if (EcsGUI.DrawTypeMetaBlock(ref rect, prop, meta)) if (EcsGUI.DrawTypeMetaElementBlock(ref rect, _recordsProp, index, prop, meta))
{ {
return; return;
} }
@ -169,7 +189,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
float result; float result;
result = EditorGUI.GetPropertyHeight(_recordsProp.GetArrayElementAtIndex(index)); result = EditorGUI.GetPropertyHeight(_recordsProp.GetArrayElementAtIndex(index));
return EcsGUI.GetTypeMetaBlockHeight(result); return EcsGUI.GetTypeMetaBlockHeight(result) + Spacing * 2f;
} }
private void OnReorderableRecordsListAdd(ReorderableList list) private void OnReorderableRecordsListAdd(ReorderableList list)
@ -183,14 +203,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
protected override void DrawCustom() protected override void DrawCustom()
{ {
using (EcsGUI.CheckChanged()) EcsGUI.Changed = GUILayout.Button("Validate");
{
EditorGUI.BeginChangeCheck();
DrawLayoutNameList(_layersProp); DrawLayoutNameList(_layersProp);
DrawRecordList(_recordsProp); DrawRecordList(_recordsProp);
EcsGUI.Changed = GUILayout.Button("Validate");
if (EcsGUI.Changed) if (EcsGUI.Changed)
{ {
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
@ -198,7 +215,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
Repaint(); Repaint();
} }
} }
}
private void Validate() private void Validate()
{ {
@ -219,10 +235,20 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
} }
private void DrawRecordList(SerializedProperty recordsProp) private void DrawRecordList(SerializedProperty recordsProp)
{
using (EcsGUI.Layout.BeginVertical())
{ {
GUILayout.Label(UnityEditorUtility.GetLabel(recordsProp.displayName), EditorStyles.boldLabel); GUILayout.Label(UnityEditorUtility.GetLabel(recordsProp.displayName), EditorStyles.boldLabel);
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)))
{
switch (EcsGUI.Layout.AddClearSystemButtons(out Rect dropDownRect))
{
case EcsGUI.AddClearButton.Add:
_systemsDropDown.OpenForArray(dropDownRect, recordsProp);
break;
case EcsGUI.AddClearButton.Clear:
recordsProp.ClearArray();
recordsProp.serializedObject.ApplyModifiedProperties();
break;
}
_reorderableRecordsList.DoLayoutList(); _reorderableRecordsList.DoLayoutList();
//EditorGUILayout.PropertyField(recordsProp, UnityEditorUtility.GetLabel(recordsProp.displayName)); //EditorGUILayout.PropertyField(recordsProp, UnityEditorUtility.GetLabel(recordsProp.displayName));
} }

View File

@ -28,8 +28,34 @@ namespace DCFApixels.DragonECS.Unity.Editors
[CustomPropertyDrawer(typeof(ReferenceButtonAttribute))] [CustomPropertyDrawer(typeof(ReferenceButtonAttribute))]
internal sealed class ReferenceButtonAttributeDrawer : ExtendedPropertyDrawer<ReferenceButtonAttribute> internal sealed class ReferenceButtonAttributeDrawer : ExtendedPropertyDrawer<ReferenceButtonAttribute>
{ {
protected override void OnInit()
{
Type referenceBaseType = typeof(Reference<>);
Type fieldType = fieldInfo.FieldType;
if (fieldType.IsGenericType)
{
if (fieldType.IsGenericTypeDefinition == false)
{
fieldType = fieldType.GetGenericTypeDefinition();
}
if (fieldType == referenceBaseType)
{
_isReferenceWrapper = true;
return;
}
}
_isReferenceWrapper = false;
}
private bool _isReferenceWrapper = false;
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{ {
if (_isReferenceWrapper)
{
property.Next(true);
}
if (property.managedReferenceValue != null) if (property.managedReferenceValue != null)
{ {
return EditorGUI.GetPropertyHeight(property, label, true); return EditorGUI.GetPropertyHeight(property, label, true);
@ -42,9 +68,19 @@ namespace DCFApixels.DragonECS.Unity.Editors
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label) protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
{ {
if (_isReferenceWrapper)
{
property.Next(true);
label.text = property.displayName;
}
if (IsArrayElement)
{
label = UnityEditorUtility.GetLabelTemp();
}
Rect selButtnoRect = position; Rect selButtnoRect = position;
selButtnoRect.height = OneLineHeight; selButtnoRect.height = OneLineHeight;
DrawSelectionPopup(selButtnoRect, property, label); DrawSelectionPopupButton(selButtnoRect, property, label);
if (property.managedReferenceValue != null) if (property.managedReferenceValue != null)
{ {
@ -58,9 +94,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
} }
private void DrawSelectionPopup(Rect position, SerializedProperty property, GUIContent label) private void DrawSelectionPopupButton(Rect position, SerializedProperty property, GUIContent label)
{ {
Rect buttonRect = position.AddPadding(EditorGUIUtility.labelWidth, 0f, 0f, 0f); Rect buttonRect = IsArrayElement ? position : position.AddPadding(EditorGUIUtility.labelWidth, 0f, 0f, 0f); ;
EcsGUI.DrawSelectReferenceButton(buttonRect, property, Attribute.PredicateTypes.Length == 0 ? new Type[1] { fieldInfo.FieldType } : Attribute.PredicateTypes, Attribute.IsHideButtonIfNotNull); EcsGUI.DrawSelectReferenceButton(buttonRect, property, Attribute.PredicateTypes.Length == 0 ? new Type[1] { fieldInfo.FieldType } : Attribute.PredicateTypes, Attribute.IsHideButtonIfNotNull);
} }
} }

View File

@ -163,7 +163,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
optionButton.xMin = optionButton.xMax - 64; optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * Padding * 1f; optionButton.center += Vector2.up * Padding * 1f;
//Canceling isExpanded //Canceling isExpanded
if (EcsGUI.HitTest(optionButton) && Event.current.type == EventType.MouseUp) if (EcsGUI.ClickTest(optionButton))
{ {
componentProperty.isExpanded = !componentProperty.isExpanded; componentProperty.isExpanded = !componentProperty.isExpanded;
} }

View File

@ -24,37 +24,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
protected override void OnInit() protected override void OnInit()
{ {
_componentDropDown = new ComponentDropDown(); _componentDropDown = new ComponentDropDown();
_componentDropDown.OnSelected += OnAddComponent;
} }
#endregion #endregion
#region Add/Remove #region Add/Remove
private void OnAddComponent(ComponentDropDown.Item item)
{
Type componentType = item.Obj.GetType();
IComponentTemplate cmptmp = item.Obj;
if (this.target is ITemplateInternal target)
{
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
if (cmptmp.IsUnique)
{
for (int i = 0, iMax = componentsProp.arraySize; i < iMax; i++)
{
if (componentsProp.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType)
{
return;
}
}
}
int index = componentsProp.arraySize;
componentsProp.InsertArrayElementAtIndex(index);
componentsProp.GetArrayElementAtIndex(index).managedReferenceValue = cmptmp.Clone();
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(this.target);
}
}
private void OnRemoveComponentAt(int index) private void OnRemoveComponentAt(int index)
{ {
if (this.target is ITemplateInternal target) if (this.target is ITemplateInternal target)
@ -76,24 +49,25 @@ namespace DCFApixels.DragonECS.Unity.Editors
return; return;
} }
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)); using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)))
DrawTop(target); {
DrawTop(target, componentsProp);
GUILayout.Label("", GUILayout.Height(0), GUILayout.ExpandWidth(true)); GUILayout.Label("", GUILayout.Height(0), GUILayout.ExpandWidth(true));
for (int i = componentsProp.arraySize - 1; i >= 0; i--) for (int i = componentsProp.arraySize - 1; i >= 0; i--)
{ {
DrawComponentData(componentsProp.GetArrayElementAtIndex(i), componentsProp.arraySize, i); DrawComponentData(componentsProp.GetArrayElementAtIndex(i), componentsProp.arraySize, i);
} }
GUILayout.EndVertical();
} }
private void DrawTop(ITemplateInternal target) }
private void DrawTop(ITemplateInternal target, SerializedProperty componentsProp)
{ {
switch (EcsGUI.Layout.AddClearComponentButtons(out Rect rect)) switch (EcsGUI.Layout.AddClearComponentButtons(out Rect rect))
{ {
case EcsGUI.AddClearComponentButton.AddComponent: case EcsGUI.AddClearButton.Add:
Init(); Init();
_componentDropDown.Show(rect); _componentDropDown.OpenForArray(rect, componentsProp, true);
break; break;
case EcsGUI.AddClearComponentButton.Clear: case EcsGUI.AddClearButton.Clear:
Init(); Init();
serializedObject.FindProperty(target.ComponentsPropertyName).ClearArray(); serializedObject.FindProperty(target.ComponentsPropertyName).ClearArray();
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
@ -159,15 +133,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
optionButton.yMax += HeadIconsRect.height; optionButton.yMax += HeadIconsRect.height;
optionButton.xMin = optionButton.xMax - 64; optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * padding * 2f; optionButton.center += Vector2.up * padding * 2f;
bool cancelExpanded = EcsGUI.HitTest(optionButton) && Event.current.type == EventType.MouseUp; bool cancelExpanded = EcsGUI.ClickTest(optionButton);
using (EcsGUI.CheckChanged())
{
//EditorGUI.BeginChangeCheck();
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(alphaPanelColor));
#region Draw Component Block #region Draw Component Block
using (EcsGUI.CheckChanged()) using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetStyle(alphaPanelColor)))
{
//Close button //Close button
optionButton.xMin = optionButton.xMax - HeadIconsRect.width; optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
if (EcsGUI.CloseButton(optionButton)) if (EcsGUI.CloseButton(optionButton))
@ -210,17 +180,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
EditorGUI.PropertyField(r, componentProperty, label, true); EditorGUI.PropertyField(r, componentProperty, label, true);
} }
} }
#endregion
GUILayout.EndVertical();
//if (EditorGUI.EndChangeCheck())
if (EcsGUI.Changed) if (EcsGUI.Changed)
{ {
componentProperty.serializedObject.ApplyModifiedProperties(); componentProperty.serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(componentProperty.serializedObject.targetObject); EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
} }
} }
#endregion
} }
private void DrawDamagedComponent_Replaced(SerializedProperty componentRefProp, int index) private void DrawDamagedComponent_Replaced(SerializedProperty componentRefProp, int index)
{ {

View File

@ -1,4 +1,5 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -8,6 +9,72 @@ using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors namespace DCFApixels.DragonECS.Unity.Editors
{ {
internal class SystemsDropDown : MetaObjectsDropDown<Type>
{
public SystemsDropDown()
{
Type[] predicateTypes = new Type[] { typeof(IEcsModule), typeof(IEcsProcess) };
IEnumerable<(Type, ITypeMeta)> itemMetaPairs = UnityEditorUtility._serializableTypes.Where(o =>
{
foreach (Type predicateTypes in predicateTypes)
{
if (predicateTypes.IsAssignableFrom(o))
{
return true;
}
}
return false;
}).Select(o => (o, (ITypeMeta)o.ToMeta()));
Setup(itemMetaPairs);
}
private SerializedProperty _arrayProperty;
private SerializedProperty _fieldProperty;
public void OpenForArray(Rect position, SerializedProperty arrayProperty)
{
_arrayProperty = arrayProperty;
_fieldProperty = null;
Show(position);
}
public void OpenForField(Rect position, SerializedProperty fieldProperty)
{
_arrayProperty = null;
_fieldProperty = fieldProperty;
Show(position);
}
protected override void ItemSelected(Item item)
{
base.ItemSelected(item);
Type type = item.Obj;
if (_arrayProperty != null)
{
int index = _arrayProperty.arraySize;
_arrayProperty.arraySize += 1;
_fieldProperty = _arrayProperty.GetArrayElementAtIndex(index);
_fieldProperty.Next(true);//Смещение чтобы перейти к полю Traget внутри рекорда
}
if (_fieldProperty != null)
{
if (type == null)
{
_fieldProperty.managedReferenceValue = null;
}
else
{
_fieldProperty.managedReferenceValue = Activator.CreateInstance(type);
_fieldProperty.isExpanded = true;
}
_fieldProperty.serializedObject.ApplyModifiedProperties();
EcsGUI.DelayedChanged = true;
}
}
}
internal class ComponentDropDown : MetaObjectsDropDown<IComponentTemplate> internal class ComponentDropDown : MetaObjectsDropDown<IComponentTemplate>
{ {
public ComponentDropDown() public ComponentDropDown()
@ -27,6 +94,59 @@ namespace DCFApixels.DragonECS.Unity.Editors
}); });
Setup(itemMetaPairs); Setup(itemMetaPairs);
} }
private bool _isCheckUnique;
private SerializedProperty _arrayProperty;
private SerializedProperty _fieldProperty;
public void OpenForArray(Rect position, SerializedProperty arrayProperty, bool isCheckUnique)
{
_isCheckUnique = isCheckUnique;
_arrayProperty = arrayProperty;
_fieldProperty = null;
Show(position);
}
public void OpenForField(Rect position, SerializedProperty fieldProperty)
{
_isCheckUnique = false;
_arrayProperty = null;
_fieldProperty = fieldProperty;
Show(position);
}
protected override void ItemSelected(Item item)
{
base.ItemSelected(item);
Type componentType = item.Obj.GetType();
IComponentTemplate cmptmp = item.Obj;
if (_arrayProperty != null)
{
int index = _arrayProperty.arraySize;
if (_isCheckUnique)
{
if (cmptmp.IsUnique)
{
for (int i = 0, iMax = _arrayProperty.arraySize; i < iMax; i++)
{
if (_arrayProperty.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType)
{
return;
}
}
}
}
_arrayProperty.arraySize += 1;
_fieldProperty = _arrayProperty.GetArrayElementAtIndex(index);
}
if (_fieldProperty != null)
{
_fieldProperty.managedReferenceValue = cmptmp.Clone();
_fieldProperty.serializedObject.ApplyModifiedProperties();
}
}
} }
internal class RuntimeComponentDropDown : MetaObjectsDropDown<IEcsPool> internal class RuntimeComponentDropDown : MetaObjectsDropDown<IEcsPool>
{ {
@ -38,6 +158,31 @@ namespace DCFApixels.DragonECS.Unity.Editors
}); });
Setup(itemMetaPairs); Setup(itemMetaPairs);
} }
private int _entityID;
public void Open(Rect position, int entityID)
{
_entityID = entityID;
Show(position);
}
protected override void ItemSelected(Item item)
{
IEcsPool pool = item.Obj;
if (pool.World.IsUsed(_entityID) == false)
{
return;
}
if (pool.Has(_entityID) == false)
{
pool.AddRaw(_entityID, Activator.CreateInstance(pool.ComponentType));
}
else
{
Debug.LogWarning($"Entity({_entityID}) already has component {EcsDebugUtility.GetGenericTypeName(pool.ComponentType)}.");
}
}
} }
internal class MetaObjectsDropDown<T> : AdvancedDropdown internal class MetaObjectsDropDown<T> : AdvancedDropdown
{ {
@ -49,7 +194,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
minimumSize = new Vector2(minimumSize.x, EditorGUIUtility.singleLineHeight * 30); minimumSize = new Vector2(minimumSize.x, EditorGUIUtility.singleLineHeight * 30);
} }
protected void Setup(IEnumerable<(T, ITypeMeta)> itemMetaPairs, string name = "Select Type", bool isContainsNull = true) protected void Setup(IEnumerable<(T, ITypeMeta)> itemMetaPairs, string name = "Select Type...", bool isContainsNull = true)
{ {
_name = name; _name = name;
_isContainsNull = isContainsNull; _isContainsNull = isContainsNull;
@ -103,8 +248,12 @@ namespace DCFApixels.DragonECS.Unity.Editors
protected override void ItemSelected(AdvancedDropdownItem item) protected override void ItemSelected(AdvancedDropdownItem item)
{ {
base.ItemSelected(item); base.ItemSelected(item);
OnSelected((Item)item); var tType = (Item)item;
ItemSelected(tType);
OnSelected(tType);
} }
protected virtual void ItemSelected(Item item) { }
public event Action<Item> OnSelected = delegate { }; public event Action<Item> OnSelected = delegate { };

View File

@ -2,7 +2,6 @@
using DCFApixels.DragonECS.Unity.Internal; using DCFApixels.DragonECS.Unity.Internal;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection; using System.Reflection;
using UnityEditor; using UnityEditor;
using UnityEditor.IMGUI.Controls; using UnityEditor.IMGUI.Controls;
@ -265,28 +264,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
public static float EntityBarHeight => EditorGUIUtility.singleLineHeight + 3f; 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 #region Properties
private static ComponentColorMode AutoColorMode private static ComponentColorMode AutoColorMode
{ {
@ -314,14 +291,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
#endregion #endregion
#region enums #region enums
public enum AddClearComponentButton : byte public enum AddClearButton : byte
{ {
None = 0, None = 0,
AddComponent, Add = 1,
Clear, Clear = 2,
} }
[Flags] [Flags]
public enum EntityStatus public enum EntityStatus : byte
{ {
NotAlive = 0, NotAlive = 0,
Alive = 1 << 0, Alive = 1 << 0,
@ -329,7 +306,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
#endregion #endregion
#region HitTest #region HitTest/ClickTest
internal static bool HitTest(Rect rect) internal static bool HitTest(Rect rect)
{ {
return HitTest(rect, Event.current.mousePosition); return HitTest(rect, Event.current.mousePosition);
@ -347,6 +324,15 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
return point.x >= rect.xMin - (float)offset && point.x < rect.xMax + (float)offset && point.y >= rect.yMin - (float)offset && point.y < rect.yMax + (float)offset; return point.x >= rect.xMin - (float)offset && point.x < rect.xMax + (float)offset && point.y >= rect.yMin - (float)offset && point.y < rect.yMax + (float)offset;
} }
internal static bool ClickTest(Rect rect)
{
Event evt = Event.current;
return ClickTest(rect, evt);
}
internal static bool ClickTest(Rect rect, Event evt)
{
return HitTest(rect, evt.mousePosition) && evt.type == EventType.MouseUp;
}
#endregion #endregion
#region small elems #region small elems
@ -538,14 +524,42 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
return DrawTypeMetaBlockPadding * 2 + contentHeight; return DrawTypeMetaBlockPadding * 2 + contentHeight;
} }
public static bool DrawTypeMetaElementBlock(ref Rect position, SerializedProperty arrayProperty, int elementIndex, SerializedProperty elementProperty, ITypeMeta meta)
{
var result = DrawTypeMetaBlock_Internal(ref position, elementProperty, meta);
if (result.HasFlag(DrawTypeMetaBlockResult.CloseButtonClicked))
{
arrayProperty.DeleteArrayElementAtIndex(elementIndex);
}
return result != DrawTypeMetaBlockResult.None;
}
public static bool DrawTypeMetaBlock(ref Rect position, SerializedProperty property, ITypeMeta meta) public static bool DrawTypeMetaBlock(ref Rect position, SerializedProperty property, ITypeMeta meta)
{ {
var result = DrawTypeMetaBlock_Internal(ref position, property, meta);
if (result.HasFlag(DrawTypeMetaBlockResult.CloseButtonClicked))
{
property.ResetValues();
}
return result.HasFlag(DrawTypeMetaBlockResult.Drop);
}
private enum DrawTypeMetaBlockResult
{
None = 0,
Drop = 1 << 0,
CloseButtonClicked = 1 << 1,
}
private static DrawTypeMetaBlockResult DrawTypeMetaBlock_Internal(ref Rect position, SerializedProperty property, ITypeMeta meta)
{
Color alphaPanelColor;
if (meta == null) if (meta == null)
{ {
return false; alphaPanelColor = Color.black;
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
EditorGUI.DrawRect(position, alphaPanelColor);
position = position.AddPadding(DrawTypeMetaBlockPadding * 2f);
return DrawTypeMetaBlockResult.None;
} }
GUIContent label = UnityEditorUtility.GetLabel(property.displayName);
var counter = property.Copy(); var counter = property.Copy();
int positionCountr = int.MaxValue; int positionCountr = int.MaxValue;
@ -555,45 +569,40 @@ namespace DCFApixels.DragonECS.Unity.Editors
positionCountr--; positionCountr--;
} }
//var counter = property.Copy();
//int positionCountr = int.MaxValue;
//while (counter.NextVisible(false))
//{
// positionCountr--;
//}
string name = meta.Name; string name = meta.Name;
string description = meta.Description.Text; string description = meta.Description.Text;
Color panelColor = EcsGUI.SelectPanelColor(meta, positionCountr, -1).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE); alphaPanelColor = SelectPanelColor(meta, positionCountr, -1).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
Color alphaPanelColor = panelColor;
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA; alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
DrawTypeMetaBlockResult result = DrawTypeMetaBlockResult.None;
using (CheckChanged()) using (CheckChanged())
{ {
EditorGUI.DrawRect(position, alphaPanelColor); EditorGUI.DrawRect(position, alphaPanelColor);
Rect paddingPosition = RectUtility.AddPadding(position, DrawTypeMetaBlockPadding * 2f);
Rect optionButton = position; Rect optionButton = position;
position = position.AddPadding(DrawTypeMetaBlockPadding * 2f);
optionButton.center -= new Vector2(0, optionButton.height); optionButton.center -= new Vector2(0, optionButton.height);
optionButton.yMin = optionButton.yMax; optionButton.yMin = optionButton.yMax;
optionButton.yMax += HeadIconsRect.height; optionButton.yMax += HeadIconsRect.height;
optionButton.xMin = optionButton.xMax - 64; optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * DrawTypeMetaBlockPadding * 1f; optionButton.center += Vector2.up * DrawTypeMetaBlockPadding * 1f;
//Canceling isExpanded //Canceling isExpanded
if (HitTest(optionButton) && Event.current.type == EventType.MouseUp) bool oldIsExpanded = property.isExpanded;
if (ClickTest(optionButton))
{ {
property.isExpanded = !property.isExpanded; property.isExpanded = oldIsExpanded;
result |= DrawTypeMetaBlockResult.Drop;
} }
//Close button //Close button
optionButton.xMin = optionButton.xMax - HeadIconsRect.width; optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
if (CloseButton(optionButton)) if (CloseButton(optionButton))
{ {
property.ResetValues(); result |= DrawTypeMetaBlockResult.CloseButtonClicked;
return true; return result;
} }
//Edit script button //Edit script button
if (UnityEditorUtility.TryGetScriptAsset(meta.Type, out MonoScript script)) if (UnityEditorUtility.TryGetScriptAsset(meta.Type, out MonoScript script))
@ -607,21 +616,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width)); optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
DescriptionIcon(optionButton, description); 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; return result;
} }
#endregion #endregion
@ -699,22 +695,30 @@ namespace DCFApixels.DragonECS.Unity.Editors
dropDownRect = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f); dropDownRect = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f);
return GUI.Button(dropDownRect, "Add Component"); return GUI.Button(dropDownRect, "Add Component");
} }
public static AddClearComponentButton AddClearComponentButtons(Rect position, out Rect dropDownRect) public static AddClearButton AddClearComponentButtons(Rect position, out Rect dropDownRect)
{
return AddClearButtons(position, "Add Component", "Clear", out dropDownRect);
}
public static AddClearButton AddClearSystemButtons(Rect position, out Rect dropDownRect)
{
return AddClearButtons(position, "Add Record", "Clear", out dropDownRect);
}
public static AddClearButton AddClearButtons(Rect position, string addText, string clearText, out Rect dropDownRect)
{ {
position = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f); position = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f);
var (left, right) = RectUtility.HorizontalSliceLerp(position, 0.75f); var (left, right) = RectUtility.HorizontalSliceLerp(position, 0.75f);
dropDownRect = left; dropDownRect = left;
if (GUI.Button(left, "Add Component")) if (GUI.Button(left, addText))
{ {
return AddClearComponentButton.AddComponent; return AddClearButton.Add;
} }
if (GUI.Button(right, "Clear")) if (GUI.Button(right, clearText))
{ {
return AddClearComponentButton.Clear; return AddClearButton.Clear;
} }
return AddClearComponentButton.None; return AddClearButton.None;
} }
public static void DrawEmptyComponentProperty(Rect position, SerializedProperty property, string name, bool isDisplayEmpty) public static void DrawEmptyComponentProperty(Rect position, SerializedProperty property, string name, bool isDisplayEmpty)
@ -822,7 +826,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
Dictionary<Key, Item> dict = new Dictionary<Key, Item>(); Dictionary<Key, Item> dict = new Dictionary<Key, Item>();
foreach (var type in _serializableTypes) foreach (var type in UnityEditorUtility._serializableTypes)
{ {
bool isAssignable = false; bool isAssignable = false;
foreach (Type predicateTypes in PredicateTypes) foreach (Type predicateTypes in PredicateTypes)
@ -937,20 +941,24 @@ namespace DCFApixels.DragonECS.Unity.Editors
public static void DrawSelectReferenceButton(Rect position, SerializedProperty property, Type[] sortedPredicateTypes, bool isHideButtonIfNotNull) public static void DrawSelectReferenceButton(Rect position, SerializedProperty property, Type[] sortedPredicateTypes, bool isHideButtonIfNotNull)
{ {
object obj = property.hasMultipleDifferentValues ? null : property.managedReferenceValue; object obj = property.hasMultipleDifferentValues ? null : property.managedReferenceValue;
string text = obj == null ? "Select..." : obj.GetMeta().Name;
if (!isHideButtonIfNotNull || obj == null) if (!isHideButtonIfNotNull || obj == null)
{ {
if (GUI.Button(position, obj == null ? "Select..." : obj.GetMeta().Name, EditorStyles.layerMaskField)) if (GUI.Button(position, text, EditorStyles.layerMaskField))
{ {
_currentProperty = property; DrawSelectReferenceMenu(position, property, sortedPredicateTypes);
GetReferenceDropDown(sortedPredicateTypes).Show(position);
} }
} }
else else
{ {
GUI.Label(position, obj == null ? "Select..." : obj.GetMeta().Name); GUI.Label(position, text);
} }
} }
public static void DrawSelectReferenceMenu(Rect position, SerializedProperty property, Type[] sortedPredicateTypes)
{
_currentProperty = property;
GetReferenceDropDown(sortedPredicateTypes).Show(position);
}
#endregion #endregion
@ -1045,10 +1053,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
return EcsGUI.AddComponentButton(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f), out dropDownRect); return EcsGUI.AddComponentButton(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f), out dropDownRect);
} }
public static AddClearComponentButton AddClearComponentButtons(out Rect dropDownRect) public static AddClearButton AddClearComponentButtons(out Rect dropDownRect)
{ {
return EcsGUI.AddClearComponentButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f), out dropDownRect); return EcsGUI.AddClearComponentButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f), out dropDownRect);
} }
public static AddClearButton AddClearSystemButtons(out Rect dropDownRect)
{
return EcsGUI.AddClearSystemButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f), out dropDownRect);
}
public static void DrawRuntimeComponents(entlong entity, bool isWithFoldout = true) public static void DrawRuntimeComponents(entlong entity, bool isWithFoldout = true)
{ {
if (entity.TryUnpackForUnityEditor(out int entityID, out _, out _, out EcsWorld world)) if (entity.TryUnpackForUnityEditor(out int entityID, out _, out _, out EcsWorld world))
@ -1071,9 +1083,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
if (AddComponentButtons(out Rect dropDownRect)) if (AddComponentButtons(out Rect dropDownRect))
{ {
RuntimeComponentDropDown genericMenu = RuntimeComponentsUtility.GetAddComponentGenericMenu(world); RuntimeComponentsUtility.GetAddComponentGenericMenu(world).Open(dropDownRect, entityID);
RuntimeComponentsUtility.CurrentEntityID = entityID;
genericMenu.Show(dropDownRect);
} }
GUILayout.Box("", UnityEditorUtility.GetStyle(GUI.color, 0.16f), GUILayout.ExpandWidth(true)); GUILayout.Box("", UnityEditorUtility.GetStyle(GUI.color, 0.16f), GUILayout.ExpandWidth(true));
@ -1109,7 +1119,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
optionButton.xMin = optionButton.xMax - 64; optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * padding * 2f; optionButton.center += Vector2.up * padding * 2f;
//Canceling isExpanded //Canceling isExpanded
if (HitTest(optionButton) && Event.current.type == EventType.MouseUp) if (ClickTest(optionButton))
{ {
ref bool isExpanded = ref expandMatrix.Down(); ref bool isExpanded = ref expandMatrix.Down();
isExpanded = !isExpanded; isExpanded = !isExpanded;

View File

@ -86,7 +86,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
internal abstract class ExtendedEditor<T> : ExtendedEditor internal abstract class ExtendedEditor<T> : ExtendedEditor
{ {
public T Target public T Target
{ {
get get
@ -124,7 +123,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
} }
private IEnumerable<Attribute> Attributes protected IEnumerable<Attribute> Attributes
{ {
get get
{ {

View File

@ -2,10 +2,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using UnityObject = UnityEngine.Object;
namespace DCFApixels.DragonECS.Unity.Editors namespace DCFApixels.DragonECS.Unity.Editors
{ {
@ -108,7 +110,30 @@ namespace DCFApixels.DragonECS.Unity.Editors
static UnityEditorUtility() static UnityEditorUtility()
{ {
colorBoxeStyles = new SparseArray<GUIStyle>(); colorBoxeStyles = new SparseArray<GUIStyle>();
#region 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();
//Array.Sort(_serializableTypes, (a, b) => string.Compare(a.AssemblyQualifiedName, b.AssemblyQualifiedName, StringComparison.Ordinal));
//_noHiddenSerializableTypes = _serializableTypes.Where(o => {
// var atr = o.GetCustomAttribute<MetaTagsAttribute>();
// return atr != null && atr.Tags.Contains(MetaTags.HIDDEN);
//}).ToArray();
#endregion
}
internal static readonly Type[] _serializableTypes;
//private static Type[] _noHiddenSerializableTypes;
private static SparseArray<GUIStyle> colorBoxeStyles = new SparseArray<GUIStyle>(); private static SparseArray<GUIStyle> colorBoxeStyles = new SparseArray<GUIStyle>();
private static GUIContent _singletonIconContent = null; private static GUIContent _singletonIconContent = null;
private static GUIContent _singletonContent = null; private static GUIContent _singletonContent = null;
@ -116,6 +141,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
private static Dictionary<Type, MonoScript> scriptsAssets = new Dictionary<Type, MonoScript>(256); private static Dictionary<Type, MonoScript> scriptsAssets = new Dictionary<Type, MonoScript>(256);
internal static void ResetValues(this SerializedProperty property, bool isExpand = false) internal static void ResetValues(this SerializedProperty property, bool isExpand = false)
{ {
ResetValues_Internal(property.Copy(), isExpand, property.depth); ResetValues_Internal(property.Copy(), isExpand, property.depth);
@ -156,7 +182,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
property.colorValue = default; property.colorValue = default;
break; break;
case SerializedPropertyType.ObjectReference: case SerializedPropertyType.ObjectReference:
property.objectReferenceValue = null; property.objectReferenceValue = default;
break; break;
case SerializedPropertyType.LayerMask: case SerializedPropertyType.LayerMask:
property.intValue = default; property.intValue = default;
@ -200,7 +226,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
property.quaternionValue = Quaternion.identity; property.quaternionValue = Quaternion.identity;
break; break;
case SerializedPropertyType.ExposedReference: case SerializedPropertyType.ExposedReference:
property.objectReferenceValue = null; property.objectReferenceValue = default;
break; break;
case SerializedPropertyType.FixedBufferSize: case SerializedPropertyType.FixedBufferSize:
for (int i = 0, iMax = property.fixedBufferSize; i < iMax; i++) for (int i = 0, iMax = property.fixedBufferSize; i < iMax; i++)
@ -423,41 +449,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
IEnumerable<IEcsPool> pools = world.AllPools.ToArray().Where(o => o.IsNullOrDummy() == false); IEnumerable<IEcsPool> pools = world.AllPools.ToArray().Where(o => o.IsNullOrDummy() == false);
RuntimeComponentDropDown genericMenu = new RuntimeComponentDropDown(pools); RuntimeComponentDropDown genericMenu = new RuntimeComponentDropDown(pools);
//var pools = world.AllPools;
//for (int i = 0; i < pools.Length; i++)
//{
// var pool = pools[i];
// if (pool.IsNullOrDummy())
// {
// continue;
// }
// var meta = pool.ComponentType.ToMeta();
// string name = meta.Group.Name + meta.Name;
// genericMenu.AddItem(new GUIContent(name, meta.Description.Text), false, OnAddComponent, pool);
//}
return new WorldData(genericMenu, world.PoolsCount); return new WorldData(genericMenu, world.PoolsCount);
} }
public static int CurrentEntityID = 0;
private static void OnAddComponent(object userData)
{
IEcsPool pool = (IEcsPool)userData;
if (pool.World.IsUsed(CurrentEntityID) == false)
{
return;
}
if (pool.Has(CurrentEntityID) == false)
{
pool.AddRaw(CurrentEntityID, Activator.CreateInstance(pool.ComponentType));
}
else
{
Debug.LogWarning($"Entity({CurrentEntityID}) already has component {EcsDebugUtility.GetGenericTypeName(pool.ComponentType)}.");
}
}
private class Listener : IEcsWorldEventListener private class Listener : IEcsWorldEventListener
{ {
private EcsWorld _world; private EcsWorld _world;