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

View File

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

View File

@ -21,9 +21,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
[CustomPropertyDrawer(typeof(ReferenceButtonAttribute), true)] [CustomPropertyDrawer(typeof(ReferenceButtonAttribute), true)]
internal sealed class ReferenceButtonAttributeDrawer : ExtendedPropertyDrawer<IReferenceButtonAttribute> internal sealed class ReferenceButtonAttributeDrawer : ExtendedPropertyDrawer<IReferenceButtonAttribute>
{ {
private Type[] _withOutTypes;
protected override void OnInit() protected override void OnInit()
{ {
Type fieldType = fieldInfo.FieldType; Type fieldType = fieldInfo.FieldType;
_withOutTypes = fieldType.TryGetAttribute(out ReferenceButtonWithOutAttribute a) ? a.PredicateTypes : Array.Empty<Type>();
if (fieldType.IsGenericType) if (fieldType.IsGenericType)
{ {
if (fieldType.IsGenericTypeDefinition == false) if (fieldType.IsGenericTypeDefinition == false)
@ -71,7 +73,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
private void DrawSelectionPopupButton(Rect position, SerializedProperty property, GUIContent label) private void DrawSelectionPopupButton(Rect position, SerializedProperty property, GUIContent label)
{ {
Rect buttonRect = IsArrayElement ? position : 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, _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;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -100,6 +101,7 @@ namespace DCFApixels.DragonECS.Unity
{ {
[SerializeReference] [SerializeReference]
[ReferenceButton(true, typeof(IEcsModule), typeof(IEcsProcess))] [ReferenceButton(true, typeof(IEcsModule), typeof(IEcsProcess))]
[ReferenceButtonWithOut(typeof(IEcsRunner))]
[ArrayElement] [ArrayElement]
public object target;// нельзя менять поярдок полей, иначе это поломает отрисовку в инспекторе изза применения property.Next(bool); public object target;// нельзя менять поярдок полей, иначе это поломает отрисовку в инспекторе изза применения property.Next(bool);
public AddParams parameters; 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)); 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));
}
}
} }