refactoring

This commit is contained in:
Mikhail 2024-10-02 14:01:18 +08:00
parent e2fca85636
commit 1517c944a0
8 changed files with 120 additions and 158 deletions

View File

@ -1,12 +1,15 @@
using System;
using DCFApixels.DragonECS.Unity.Editors;
using System;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Internal
namespace DCFApixels.DragonECS
{
internal sealed class ReferenceButtonAttribute : PropertyAttribute
public sealed class ReferenceButtonAttribute : PropertyAttribute, IReferenceButtonAttribute
{
public readonly Type[] PredicateTypes;
public readonly bool IsHideButtonIfNotNull;
Type[] IReferenceButtonAttribute.PredicateTypes { get { return PredicateTypes; } }
bool IReferenceButtonAttribute.IsHideButtonIfNotNull { get { return 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)
@ -17,6 +20,14 @@ namespace DCFApixels.DragonECS.Unity.Internal
}
}
}
namespace DCFApixels.DragonECS.Unity.Editors
{
public interface IReferenceButtonAttribute
{
Type[] PredicateTypes { get; }
bool IsHideButtonIfNotNull { get; }
}
}
#if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors
@ -25,8 +36,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
using System;
using UnityEditor;
[CustomPropertyDrawer(typeof(ReferenceButtonAttribute))]
internal sealed class ReferenceButtonAttributeDrawer : ExtendedPropertyDrawer<ReferenceButtonAttribute>
[CustomPropertyDrawer(typeof(ComponentTemplateReferenceAttribute), true)]
[CustomPropertyDrawer(typeof(ReferenceButtonAttribute), true)]
internal sealed class ReferenceButtonAttributeDrawer : ExtendedPropertyDrawer<IReferenceButtonAttribute>
{
protected override void OnInit()
{

View File

@ -527,21 +527,21 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
return DrawTypeMetaBlockPadding * 2 + contentHeight;
}
public static bool DrawTypeMetaElementBlock(ref Rect position, SerializedProperty arrayProperty, int elementIndex, SerializedProperty elementProperty, ITypeMeta meta)
public static bool DrawTypeMetaElementBlock(ref Rect position, SerializedProperty arrayProperty, int elementIndex, SerializedProperty elementRootProperty, ITypeMeta meta)
{
var result = DrawTypeMetaBlock_Internal(ref position, elementProperty, meta, elementIndex, arrayProperty.arraySize);
var result = DrawTypeMetaBlock_Internal(ref position, elementRootProperty, meta, elementIndex, arrayProperty.arraySize);
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 rootProperty, ITypeMeta meta, int index = -1, int total = -1)
{
var result = DrawTypeMetaBlock_Internal(ref position, property, meta);
var result = DrawTypeMetaBlock_Internal(ref position, rootProperty, meta, index, total);
if (result.HasFlag(DrawTypeMetaBlockResult.CloseButtonClicked))
{
property.ResetValues();
rootProperty.ResetValues();
}
return result.HasFlag(DrawTypeMetaBlockResult.Drop);
}
@ -552,7 +552,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
Drop = 1 << 0,
CloseButtonClicked = 1 << 1,
}
private static DrawTypeMetaBlockResult DrawTypeMetaBlock_Internal(ref Rect position, SerializedProperty property, ITypeMeta meta, int index = -1, int total = -1)
private static DrawTypeMetaBlockResult DrawTypeMetaBlock_Internal(ref Rect position, SerializedProperty rootProperty, ITypeMeta meta, int index = -1, int total = -1)
{
Color alphaPanelColor;
if (meta == null)
@ -567,24 +567,23 @@ namespace DCFApixels.DragonECS.Unity.Editors
string name = meta.Name;
string description = meta.Description.Text;
int positionCountr;
int positionIndex;
if (index < 0)
{
positionCountr = int.MaxValue;
var counter = property.Copy();
positionIndex = int.MaxValue;
var counter = rootProperty.Copy();
int depth = -1;
while (counter.NextVisibleDepth(false, ref depth))
{
positionCountr--;
positionIndex--;
}
}
else
{
positionCountr = index;
positionIndex = index;
}
alphaPanelColor = SelectPanelColor(meta, positionCountr, total).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
alphaPanelColor = SelectPanelColor(meta, positionIndex, total).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE).SetAlpha(EscEditorConsts.COMPONENT_DRAWER_ALPHA);
DrawTypeMetaBlockResult result = DrawTypeMetaBlockResult.None;
using (CheckChanged())
@ -601,10 +600,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
optionButton.center += Vector2.up * DrawTypeMetaBlockPadding * 1f;
//Canceling isExpanded
bool oldIsExpanded = property.isExpanded;
bool oldIsExpanded = rootProperty.isExpanded;
if (ClickTest(optionButton))
{
property.isExpanded = oldIsExpanded;
rootProperty.isExpanded = oldIsExpanded;
result |= DrawTypeMetaBlockResult.Drop;
}
@ -639,7 +638,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
depth = property.depth;
}
return property.NextVisible(child) && property.depth >= depth;
var next = property.NextVisible(child);
return next && property.depth >= depth;
}
internal static bool NextDepth(this SerializedProperty property, bool child, ref int depth)
{

View File

@ -53,13 +53,13 @@ namespace DCFApixels.DragonECS.Unity.Editors
protected virtual bool IsStaticInit { get { return _isStaticInit; } }
protected virtual bool IsInit { get { return _isInit; } }
protected void StaticInit()
public void StaticInit()
{
if (IsStaticInit) { return; }
_isStaticInit = true;
OnStaticInit();
}
protected void Init()
public void Init()
{
if (IsInit) { return; }
_isInit = true;
@ -165,13 +165,13 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
protected virtual bool IsStaticInit { get { return _isStaticInit; } }
protected virtual bool IsInit { get { return _isInit; } }
protected void StaticInit()
public void StaticInit()
{
if (IsStaticInit) { return; }
_isStaticInit = true;
OnStaticInit();
}
protected void Init()
public void Init()
{
if (IsInit) { return; }
_isInit = true;
@ -180,14 +180,20 @@ namespace DCFApixels.DragonECS.Unity.Editors
protected virtual void OnStaticInit() { }
protected virtual void OnInit() { }
//private Stopwatch _stopwatch = new Stopwatch();
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
//_stopwatch.Restart();
using (EcsGUI.CheckChanged(property.serializedObject))
{
StaticInit();
Init();
DrawCustom(position, property, label);
}
//_stopwatch.Stop();
//var result = _stopwatch.Elapsed;
//UnityEngine.Debug.Log($"{result.Minutes}:{result.Seconds}:{result.Milliseconds}");
}
protected abstract void DrawCustom(Rect position, SerializedProperty property, GUIContent label);
}

View File

@ -118,6 +118,13 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
base.ItemSelected(item);
if (item.Obj == null)
{
_fieldProperty.managedReferenceValue = null;
_fieldProperty.serializedObject.ApplyModifiedProperties();
return;
}
Type componentType = item.Obj.GetType();
IComponentTemplate cmptmp = item.Obj;

View File

@ -102,7 +102,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
#if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors
{
using System.Reflection;
using UnityEditor;
[InitializeOnLoad]

View File

@ -16,5 +16,10 @@ namespace DCFApixels.DragonECS.Unity.Internal
b = b + (gray - b) * (1 - t);
return new Color(r, g, b, self.a);
}
public static Color SetAlpha(this Color self, float a)
{
self.a = a;
return self;
}
}
}

View File

@ -1,4 +1,5 @@
using System;
using DCFApixels.DragonECS.Unity.Editors;
using System;
using System.Runtime.CompilerServices;
using UnityEngine;
@ -61,5 +62,16 @@ namespace DCFApixels.DragonECS
public readonly struct Null { }
}
public sealed class ComponentTemplateReferenceAttribute : PropertyAttribute { }
public sealed class ComponentTemplateReferenceAttribute : PropertyAttribute, IReferenceButtonAttribute
{
public readonly Type[] PredicateTypes;
public readonly bool IsHideButtonIfNotNull;
Type[] IReferenceButtonAttribute.PredicateTypes { get { return PredicateTypes; } }
bool IReferenceButtonAttribute.IsHideButtonIfNotNull { get { return IsHideButtonIfNotNull; } }
public ComponentTemplateReferenceAttribute()
{
PredicateTypes = new Type[] { typeof(IComponentTemplate) };
IsHideButtonIfNotNull = true;
}
}
}

View File

@ -1,25 +1,29 @@
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomPropertyDrawer(typeof(ComponentTemplateProperty), true)]
internal class ComponentTemplatePropertyDrawer : PropertyDrawer
internal class ComponentTemplatePropertyDrawer : ExtendedPropertyDrawer
{
private ComponentTemplateReferenceDrawer _drawer = new ComponentTemplateReferenceDrawer();
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
property.Next(true);
_drawer.StaticInit();
_drawer.Init();
return _drawer.GetPropertyHeight(property, label);
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
{
var root = property.Copy();
property.Next(true);
_drawer.OnGUI(position, property, label);
_drawer.StaticInit();
_drawer.Init();
_drawer.Draw(position, root, property, label);
}
}
[CustomPropertyDrawer(typeof(ComponentTemplateReferenceAttribute), true)]
@ -29,9 +33,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
private static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f);
private static ComponentDropDown _componentDropDown;
#region Properties
private float SingleLineWithPadding => OneLineHeight + Padding * 4f;
private float Padding => Spacing;
protected override bool IsInit => _componentDropDown != null;
protected override bool IsStaticInit => _componentDropDown != null;
#endregion
#region Init
protected override void OnStaticInit()
@ -53,25 +59,29 @@ namespace DCFApixels.DragonECS.Unity.Editors
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
if (property.propertyType == SerializedPropertyType.ManagedReference == false)
#region No SerializeReference
if (property.propertyType != SerializedPropertyType.ManagedReference)
{
return EditorGUI.GetPropertyHeight(property, label);
}
IComponentTemplate template = property.managedReferenceValue as IComponentTemplate;
if (template == null || property.managedReferenceValue == null)
#endregion
var instance = property.managedReferenceValue;
IComponentTemplate template = instance as IComponentTemplate;
if (template == null || instance == null)
{
return EditorGUIUtility.singleLineHeight + Padding * 2f;
}
try
{
ComponentTemplateBase customTemplate = property.managedReferenceValue as ComponentTemplateBase;
if (customTemplate != null)
if (instance is ComponentTemplateBase customTemplate)
{
property = property.FindPropertyRelative("component");
}
}
catch (Exception)
catch
{
property = null;
}
@ -85,155 +95,66 @@ namespace DCFApixels.DragonECS.Unity.Editors
return (propCount <= 0 ? EditorGUIUtility.singleLineHeight : EditorGUI.GetPropertyHeight(property, label)) + Padding * 4f;
}
protected override void DrawCustom(Rect position, SerializedProperty componentRefProp, GUIContent label)
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
{
if (componentRefProp.propertyType == SerializedPropertyType.ManagedReference == false)
Draw(position, property, property, label);
}
public void Draw(Rect position, SerializedProperty rootProperty, SerializedProperty property, GUIContent label)
{
#region No SerializeReference
if (property.propertyType != SerializedPropertyType.ManagedReference)
{
EditorGUI.PropertyField(position, componentRefProp, label, true);
EditorGUI.PropertyField(position, property, label, true);
return;
}
#endregion
var instance = property.managedReferenceValue;
IComponentTemplate template = instance as IComponentTemplate;
if (template == null || instance == null)
{
DrawSelectionPopup(position, property, label);
return;
}
Init();
var counter = componentRefProp.Copy();
int positionCountr = int.MaxValue;
while (counter.NextVisible(false))
SerializedProperty componentProp = property;
if (componentProp.managedReferenceValue is ComponentTemplateBase customTemplate)
{
positionCountr--;
componentProp = property.FindPropertyRelative("component");
}
IComponentTemplate template = componentRefProp.managedReferenceValue as IComponentTemplate;
if (template == null || componentRefProp.managedReferenceValue == null)
if (componentProp == null)
{
DrawSelectionPopup(position, componentRefProp, label);
return;
}
Type componentType;
SerializedProperty componentProperty = componentRefProp;
try
{
ComponentTemplateBase customTemplate = componentProperty.managedReferenceValue as ComponentTemplateBase;
if (customTemplate != null)
{
componentProperty = componentRefProp.FindPropertyRelative("component");
componentType = customTemplate.GetType().GetField("component", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FieldType;
}
else
{
componentType = componentProperty.managedReferenceValue.GetType();
}
if (componentType == null || componentProperty == null)
{
throw new NullReferenceException();
}
}
catch (Exception e)
{
Debug.LogException(e, componentRefProp.serializedObject.targetObject);
DrawDamagedComponent(position, "Damaged component template.");
return;
}
//сюда попадают уже валидные компоненты
ITypeMeta meta = template is ITypeMeta metaOverride ? metaOverride : template.Type.ToMeta();
string name = meta.Name;
string description = meta.Description.Text;
int propCount = EcsGUI.GetChildPropertiesCount(componentProperty);
Color panelColor = EcsGUI.SelectPanelColor(meta, positionCountr, -1).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
Color alphaPanelColor = panelColor;
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
EditorGUI.BeginChangeCheck();
EditorGUI.DrawRect(position, alphaPanelColor);
Rect paddingPosition = RectUtility.AddPadding(position, Padding * 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 * Padding * 1f;
//Canceling isExpanded
if (EcsGUI.ClickTest(optionButton))
Rect rect = position;
if (EcsGUI.DrawTypeMetaBlock(ref rect, rootProperty, meta))
{
componentProperty.isExpanded = !componentProperty.isExpanded;
}
#region Draw Component Block
//Close button
optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
if (EcsGUI.CloseButton(optionButton))
{
componentRefProp.managedReferenceValue = null;
return;
}
//Edit script button
if (ScriptsCache.TryGetScriptAsset(meta.FindRootTypeMeta(), 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)
label.text = meta.Name;
if (componentProp.propertyType == SerializedPropertyType.Generic)
{
EcsGUI.DrawEmptyComponentProperty(paddingPosition, componentRefProp, label, false);
EditorGUI.PropertyField(rect, componentProp, label, true);
}
else
{
if (componentProperty.propertyType == SerializedPropertyType.Generic)
{
EditorGUI.PropertyField(paddingPosition, componentProperty, label, true);
}
else
{
Rect r = RectUtility.AddPadding(paddingPosition, 0, 20f, 0, 0);
EditorGUI.PropertyField(r, componentProperty, label, true);
}
}
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);
}
#endregion
if (EditorGUI.EndChangeCheck())
{
componentProperty.serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
EditorGUI.PropertyField(rect.AddPadding(0, 20f, 0, 0), componentProp, label, true);
}
}
private void DrawSelectionPopup(Rect position, SerializedProperty componentRefProp, GUIContent label)
private void DrawSelectionPopup(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.LabelField(position, label);
Rect buttonRect = RectUtility.AddPadding(position, EditorGUIUtility.labelWidth, 0f, 0f, 0f);
if (GUI.Button(buttonRect, "Select"))
{
currentProperty = componentRefProp;
currentProperty = property;
_componentDropDown.Show(buttonRect);
}
}