This commit is contained in:
Mikhail 2024-11-01 13:50:48 +08:00
parent cec6b210ec
commit 59e41eb5cd
5 changed files with 63 additions and 18 deletions

View File

@ -765,13 +765,13 @@ namespace DCFApixels.DragonECS.Unity.Editors
private static SerializedProperty _currentProperty;
#region Init
private static ReferenceDropDown GetReferenceDropDown(Type[] predicatTypes)
private static ReferenceDropDown GetReferenceDropDown(Type[] predicatTypes, Type[] sortedWithOutTypes)
{
if (_predicatTypesMenus.TryGetValue(predicatTypes, out ReferenceDropDown menu) == false)
if (_predicatTypesMenus.TryGetValue((predicatTypes, sortedWithOutTypes), out ReferenceDropDown menu) == false)
{
menu = new ReferenceDropDown(predicatTypes);
menu = new ReferenceDropDown(predicatTypes, sortedWithOutTypes);
menu.OnSelected += SelectComponent;
_predicatTypesMenus.Add(predicatTypes, menu);
_predicatTypesMenus.Add((predicatTypes, sortedWithOutTypes), menu);
}
return menu;
@ -798,13 +798,16 @@ namespace DCFApixels.DragonECS.Unity.Editors
private readonly struct PredicateTypesKey : IEquatable<PredicateTypesKey>
{
public readonly Type[] types;
public PredicateTypesKey(Type[] types)
public readonly Type[] withoutTypes;
public PredicateTypesKey(Type[] types, Type[] withoutTypes)
{
this.types = types;
this.withoutTypes = withoutTypes;
}
public bool Equals(PredicateTypesKey other)
{
if (types.Length != other.types.Length) { return false; }
if (withoutTypes.Length != other.withoutTypes.Length) { return false; }
for (int i = 0; i < types.Length; i++)
{
if (types[i] != other.types[i])
@ -812,6 +815,13 @@ namespace DCFApixels.DragonECS.Unity.Editors
return false;
}
}
for (int i = 0; i < withoutTypes.Length; i++)
{
if (withoutTypes[i] != other.withoutTypes[i])
{
return false;
}
}
return true;
}
public override bool Equals(object obj)
@ -822,8 +832,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
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; }
public static implicit operator PredicateTypesKey((Type[], Type[]) types) { return new PredicateTypesKey(types.Item1, types.Item2); }
}
#endregion
@ -831,9 +840,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
private class ReferenceDropDown : AdvancedDropdown
{
public readonly Type[] PredicateTypes;
public ReferenceDropDown(Type[] predicateTypes) : base(new AdvancedDropdownState())
public readonly Type[] WithOutTypes;
public ReferenceDropDown(Type[] predicateTypes, Type[] withOutTypes) : base(new AdvancedDropdownState())
{
PredicateTypes = predicateTypes;
WithOutTypes = withOutTypes;
minimumSize = new Vector2(minimumSize.x, EditorGUIUtility.singleLineHeight * 30);
}
protected override AdvancedDropdownItem BuildRoot()
@ -855,6 +866,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
break;
}
}
foreach (Type withoutType in WithOutTypes)
{
if (withoutType.IsAssignableFrom(type))
{
isAssignable = false;
break;
}
}
if (isAssignable)
{
ITypeMeta meta = type.ToMeta();
@ -956,7 +975,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
#endregion
public static void DrawSelectReferenceButton(Rect position, SerializedProperty property, Type[] sortedPredicateTypes, bool isHideButtonIfNotNull)
public static void DrawSelectReferenceButton(Rect position, SerializedProperty property, Type[] sortedPredicateTypes, Type[] sortedWithOutTypes, bool isHideButtonIfNotNull)
{
object obj = property.hasMultipleDifferentValues ? null : property.managedReferenceValue;
string text = obj == null ? "Select..." : obj.GetMeta().Name;
@ -964,7 +983,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
if (GUI.Button(position, text, EditorStyles.layerMaskField))
{
DrawSelectReferenceMenu(position, property, sortedPredicateTypes);
DrawSelectReferenceMenu(position, property, sortedPredicateTypes, sortedWithOutTypes);
}
}
else
@ -972,10 +991,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
GUI.Label(position, text);
}
}
public static void DrawSelectReferenceMenu(Rect position, SerializedProperty property, Type[] sortedPredicateTypes)
public static void DrawSelectReferenceMenu(Rect position, SerializedProperty property, Type[] sortedPredicateTypes, Type[] sortedWithOutTypes)
{
_currentProperty = property;
GetReferenceDropDown(sortedPredicateTypes).Show(position);
GetReferenceDropDown(sortedPredicateTypes, sortedWithOutTypes).Show(position);
}
#endregion

View File

@ -1,4 +1,5 @@
#if UNITY_EDITOR
using DCFApixels.DragonECS.RunnersCore;
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Collections.Generic;
@ -14,16 +15,26 @@ namespace DCFApixels.DragonECS.Unity.Editors
public SystemsDropDown()
{
Type[] predicateTypes = new Type[] { typeof(IEcsModule), typeof(IEcsProcess) };
Type[] withoutTypes = new Type[] { typeof(IEcsRunner) };
IEnumerable<(Type, ITypeMeta)> itemMetaPairs = UnityEditorUtility._serializableTypes.Where(o =>
{
foreach (Type predicateTypes in predicateTypes)
bool result = false;
foreach (Type type in predicateTypes)
{
if (predicateTypes.IsAssignableFrom(o))
if (type.IsAssignableFrom(o))
{
return true;
result = true;
break;
}
}
return false;
foreach (Type type in withoutTypes)
{
if (type.IsAssignableFrom(o))
{
return false;
}
}
return result;
}).Select(o => (o, (ITypeMeta)o.ToMeta()));
Setup(itemMetaPairs);
}

View File

@ -21,9 +21,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
[CustomPropertyDrawer(typeof(ReferenceButtonAttribute), true)]
internal sealed class ReferenceButtonAttributeDrawer : ExtendedPropertyDrawer<IReferenceButtonAttribute>
{
private Type[] _withOutTypes;
protected override void OnInit()
{
Type fieldType = fieldInfo.FieldType;
_withOutTypes = fieldType.TryGetAttribute(out ReferenceButtonWithOutAttribute a) ? a.PredicateTypes : Array.Empty<Type>();
if (fieldType.IsGenericType)
{
if (fieldType.IsGenericTypeDefinition == false)
@ -71,7 +73,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
private void DrawSelectionPopupButton(Rect position, SerializedProperty property, GUIContent label)
{
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, _withOutTypes, Attribute.IsHideButtonIfNotNull);
}
}
}

View File

@ -1,4 +1,5 @@
using DCFApixels.DragonECS.Unity.Internal;
using DCFApixels.DragonECS.RunnersCore;
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
@ -100,6 +101,7 @@ namespace DCFApixels.DragonECS.Unity
{
[SerializeReference]
[ReferenceButton(true, typeof(IEcsModule), typeof(IEcsProcess))]
[ReferenceButtonWithOut(typeof(IEcsRunner))]
[ArrayElement]
public object target;// нельзя менять поярдок полей, иначе это поломает отрисовку в инспекторе изза применения property.Next(bool);
public AddParams parameters;

View File

@ -19,4 +19,15 @@ namespace DCFApixels.DragonECS
Array.Sort(predicateTypes, (a, b) => string.Compare(a.AssemblyQualifiedName, b.AssemblyQualifiedName, StringComparison.Ordinal));
}
}
public sealed class ReferenceButtonWithOutAttribute : Attribute
{
public readonly Type[] PredicateTypes;
[Obsolete("With empty parameters, this attribute makes no sense.", true)]
public ReferenceButtonWithOutAttribute() : this(Array.Empty<Type>()) { }
public ReferenceButtonWithOutAttribute(params Type[] predicateTypes)
{
PredicateTypes = predicateTypes;
Array.Sort(predicateTypes, (a, b) => string.Compare(a.AssemblyQualifiedName, b.AssemblyQualifiedName, StringComparison.Ordinal));
}
}
}