mirror of
https://github.com/DCFApixels/DragonECS-Unity.git
synced 2026-04-22 04:35:55 +08:00
rework components display
This commit is contained in:
parent
a23fbb712e
commit
2c5461fca1
@ -45,16 +45,9 @@ namespace DCFApixels.DragonECS
|
|||||||
[MetaGroup(EcsUnityConsts.PACK_GROUP, OTHER_GROUP)]
|
[MetaGroup(EcsUnityConsts.PACK_GROUP, OTHER_GROUP)]
|
||||||
[MetaDescription(AUTHOR, "Template for UnityComponent<T>")]
|
[MetaDescription(AUTHOR, "Template for UnityComponent<T>")]
|
||||||
[MetaID("DragonECS_13DAACF9910155DD27F822442987E0AE")]
|
[MetaID("DragonECS_13DAACF9910155DD27F822442987E0AE")]
|
||||||
|
[MetaProxy(typeof(UnityComponentTemplate<>.UnityComponentMetaProxy))]
|
||||||
public abstract class UnityComponentTemplate<T> : ComponentTemplateBase<UnityComponent<T>> where T : Component
|
public abstract class UnityComponentTemplate<T> : ComponentTemplateBase<UnityComponent<T>> where T : Component
|
||||||
{
|
{
|
||||||
public override string Name
|
|
||||||
{
|
|
||||||
get { return typeof(T).Name; }
|
|
||||||
}
|
|
||||||
public override MetaGroup Group
|
|
||||||
{
|
|
||||||
get { return UnityComponentConsts.BaseGroup; }
|
|
||||||
}
|
|
||||||
public sealed override void Apply(short worldID, int entityID)
|
public sealed override void Apply(short worldID, int entityID)
|
||||||
{
|
{
|
||||||
EcsWorld.GetPoolInstance<EcsPool<UnityComponent<T>>>(worldID).TryAddOrGet(entityID) = component;
|
EcsWorld.GetPoolInstance<EcsPool<UnityComponent<T>>>(worldID).TryAddOrGet(entityID) = component;
|
||||||
@ -69,5 +62,11 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
protected class UnityComponentMetaProxy : ComponentTemplateMetaProxy
|
||||||
|
{
|
||||||
|
public override string Name { get { return typeof(T).GetMeta().Name; } }
|
||||||
|
public override MetaGroup Group { get { return UnityComponentConsts.BaseGroup; } }
|
||||||
|
public UnityComponentMetaProxy(Type type) : base(type) { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,7 +186,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
protected override float GetCustomHeight(SerializedProperty property, GUIContent label)
|
||||||
{
|
{
|
||||||
const float UNITY_HEIGHT_CONSTANT = 18f;
|
const float UNITY_HEIGHT_CONSTANT = 18f;
|
||||||
if (property.hasMultipleDifferentValues)
|
if (property.hasMultipleDifferentValues)
|
||||||
|
|||||||
@ -12,6 +12,74 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
internal class WorldQueriesMonitorEditor : ExtendedEditor<WorldQueriesMonitor>
|
internal class WorldQueriesMonitorEditor : ExtendedEditor<WorldQueriesMonitor>
|
||||||
{
|
{
|
||||||
private GUIStyle _headerStyle;
|
private GUIStyle _headerStyle;
|
||||||
|
private const char _searchPatternSeparator = '/';
|
||||||
|
|
||||||
|
public readonly struct SearchPattern
|
||||||
|
{
|
||||||
|
private readonly string _pattern;
|
||||||
|
private readonly char _separator;
|
||||||
|
public SearchPattern(string pattern, char separator)
|
||||||
|
{
|
||||||
|
_pattern = pattern ?? throw new ArgumentNullException(nameof(pattern));
|
||||||
|
_separator = separator;
|
||||||
|
}
|
||||||
|
public Enumerator GetEnumerator() => new Enumerator(_pattern, _separator);
|
||||||
|
public ref struct Enumerator
|
||||||
|
{
|
||||||
|
private readonly string _pattern;
|
||||||
|
private readonly char _separator;
|
||||||
|
private int _start;
|
||||||
|
private int _currentStart;
|
||||||
|
private int _currentLength;
|
||||||
|
|
||||||
|
public Enumerator(string pattern, char separator)
|
||||||
|
{
|
||||||
|
_pattern = pattern;
|
||||||
|
_separator = separator;
|
||||||
|
_start = 0;
|
||||||
|
_currentStart = -1;
|
||||||
|
_currentLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReadOnlySpan<char> Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_currentStart < 0)
|
||||||
|
throw new InvalidOperationException("Enumeration not started or already finished");
|
||||||
|
return _pattern.AsSpan(_currentStart, _currentLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
if (_pattern == null || _start > _pattern.Length)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int len = _pattern.Length;
|
||||||
|
while (_start <= len)
|
||||||
|
{
|
||||||
|
int i = _start;
|
||||||
|
while (i < len && _pattern[i] != _separator)
|
||||||
|
i++;
|
||||||
|
|
||||||
|
int subLen = i - _start;
|
||||||
|
if (subLen > 0) // возвращаем только непустые подстроки
|
||||||
|
{
|
||||||
|
_currentStart = _start;
|
||||||
|
_currentLength = subLen;
|
||||||
|
_start = i + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// пустая подстрока — пропускаем разделитель и продолжаем
|
||||||
|
_start = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void CopyToClipboard()
|
private void CopyToClipboard()
|
||||||
{
|
{
|
||||||
@ -148,21 +216,42 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var executor in executors)
|
foreach (var executor in executors)
|
||||||
{
|
{
|
||||||
bool cheack(ReadOnlySpan<Type> types, string searchPattern)
|
bool cheack(ReadOnlySpan<Type> types, ReadOnlySpan<char> searchPatternRaw)
|
||||||
{
|
{
|
||||||
foreach (var type in types)
|
foreach (var type in types)
|
||||||
{
|
{
|
||||||
if(type.Name.Contains(searchPattern, StringComparison.OrdinalIgnoreCase))
|
if(type.Name.AsSpan().Contains(searchPatternRaw, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!HasSearchPattern ||
|
|
||||||
cheack(executor.Mask.GetIncTypes_Debug(), searchPattern) ||
|
bool isDraw = false;
|
||||||
cheack(executor.Mask.GetExcTypes_Debug(), searchPattern) ||
|
if (HasSearchPattern)
|
||||||
cheack(executor.Mask.GetAnyTypes_Debug(), searchPattern))
|
{
|
||||||
|
int subPuttornsCount = 0;
|
||||||
|
int checkPassesCount = 0;
|
||||||
|
foreach (var subPattern in new SearchPattern(searchPattern, _searchPatternSeparator))
|
||||||
|
{
|
||||||
|
subPuttornsCount++;
|
||||||
|
if (cheack(executor.Mask.GetIncTypes_Debug(), subPattern) ||
|
||||||
|
cheack(executor.Mask.GetExcTypes_Debug(), subPattern) ||
|
||||||
|
cheack(executor.Mask.GetAnyTypes_Debug(), subPattern))
|
||||||
|
{
|
||||||
|
checkPassesCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isDraw = subPuttornsCount <= checkPassesCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isDraw = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(isDraw)
|
||||||
{
|
{
|
||||||
DrawQueryInfo(executor, i++);
|
DrawQueryInfo(executor, i++);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,8 +29,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
{ (byte)AddParamsFlags.NoImport | 7, "NoImport, Layer, Order, IsUnique" },
|
{ (byte)AddParamsFlags.NoImport | 7, "NoImport, Layer, Order, IsUnique" },
|
||||||
{ byte.MaxValue, "NoImport, Layer, Order, IsUnique" },
|
{ byte.MaxValue, "NoImport, Layer, Order, IsUnique" },
|
||||||
};
|
};
|
||||||
|
protected override float GetCustomHeight(SerializedProperty property, GUIContent label)
|
||||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
|
||||||
{
|
{
|
||||||
//return !property.isExpanded ?
|
//return !property.isExpanded ?
|
||||||
// EditorGUIUtility.singleLineHeight + Spacing :
|
// EditorGUIUtility.singleLineHeight + Spacing :
|
||||||
|
|||||||
@ -18,6 +18,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
[CustomPropertyDrawer(typeof(CustomToggleAttribute))]
|
[CustomPropertyDrawer(typeof(CustomToggleAttribute))]
|
||||||
internal class LeftToggleAttributeDrawer : ExtendedPropertyDrawer<CustomToggleAttribute>
|
internal class LeftToggleAttributeDrawer : ExtendedPropertyDrawer<CustomToggleAttribute>
|
||||||
{
|
{
|
||||||
|
protected override float GetCustomHeight(SerializedProperty property, GUIContent label)
|
||||||
|
{
|
||||||
|
return OneLineHeight + Spacing;
|
||||||
|
}
|
||||||
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
|
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
|
||||||
{
|
{
|
||||||
if (property.propertyType != SerializedPropertyType.Boolean)
|
if (property.propertyType != SerializedPropertyType.Boolean)
|
||||||
|
|||||||
@ -426,8 +426,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
using (SetAlpha(0))
|
using (SetAlpha(0))
|
||||||
{
|
{
|
||||||
bool result = GUI.Button(position, string.Empty, EditorStyles.miniButtonMid);
|
bool result = GUI.Button(position, string.Empty, EditorStyles.miniButtonMid);
|
||||||
var current = Event.current;
|
var currentEvent = Event.current;
|
||||||
return (GUI.enabled && HitTest(position, current), result);
|
return (GUI.enabled && HitTest(position, currentEvent), result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static bool IconHoverScan(Rect position, Event current)
|
public static bool IconHoverScan(Rect position, Event current)
|
||||||
@ -486,11 +486,13 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
if (current.type == EventType.MouseUp)
|
if (current.type == EventType.MouseUp)
|
||||||
{
|
{
|
||||||
EditorGUIUtility.PingObject(script);
|
EditorGUIUtility.PingObject(script);
|
||||||
|
Event.current.Use();
|
||||||
}
|
}
|
||||||
else if (current.type == EventType.MouseDown && current.clickCount >= 2)
|
else if (current.type == EventType.MouseDown && current.clickCount >= 2)
|
||||||
{
|
{
|
||||||
//UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(); //TODO
|
//UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(); //TODO
|
||||||
AssetDatabase.OpenAsset(script);
|
AssetDatabase.OpenAsset(script);
|
||||||
|
Event.current.Use();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -715,23 +717,23 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
return DrawTypeMetaBlockPadding * 2 + contentHeight;
|
return DrawTypeMetaBlockPadding * 2 + contentHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool DrawTypeMetaElementBlock(ref Rect rect, SerializedProperty arrayProperty, int elementIndex, SerializedProperty elementRootProperty, ITypeMeta meta)
|
public static (bool skip, float optionsWidth) DrawTypeMetaElementBlock(ref Rect rect, SerializedProperty arrayProperty, int elementIndex, SerializedProperty elementRootProperty, ITypeMeta meta)
|
||||||
{
|
{
|
||||||
var result = DrawTypeMetaBlock_Internal(ref rect, elementRootProperty, meta, elementIndex, arrayProperty.arraySize);
|
var result = DrawTypeMetaBlock_Internal(ref rect, elementRootProperty, meta, elementIndex, arrayProperty.arraySize);
|
||||||
if (result.HasFlag(DrawTypeMetaBlockResultFlags.CloseButtonClicked))
|
if (result.flags.HasFlag(DrawTypeMetaBlockResultFlags.CloseButtonClicked))
|
||||||
{
|
{
|
||||||
arrayProperty.DeleteArrayElementAtIndex(elementIndex);
|
arrayProperty.DeleteArrayElementAtIndex(elementIndex);
|
||||||
}
|
}
|
||||||
return result != DrawTypeMetaBlockResultFlags.None;
|
return (result.flags != DrawTypeMetaBlockResultFlags.None, result.optionsWidth);
|
||||||
}
|
}
|
||||||
public static bool DrawTypeMetaBlock(ref Rect rect, SerializedProperty rootProperty, ITypeMeta meta, int index = -1, int total = -1)
|
public static (bool skip, float optionsWidth) DrawTypeMetaBlock(ref Rect rect, SerializedProperty rootProperty, ITypeMeta meta, int index = -1, int total = -1)
|
||||||
{
|
{
|
||||||
var result = DrawTypeMetaBlock_Internal(ref rect, rootProperty, meta, index, total);
|
var result = DrawTypeMetaBlock_Internal(ref rect, rootProperty, meta, index, total);
|
||||||
if (result.HasFlag(DrawTypeMetaBlockResultFlags.CloseButtonClicked))
|
if (result.flags.HasFlag(DrawTypeMetaBlockResultFlags.CloseButtonClicked))
|
||||||
{
|
{
|
||||||
rootProperty.ResetValues();
|
rootProperty.ResetValues();
|
||||||
}
|
}
|
||||||
return result.HasFlag(DrawTypeMetaBlockResultFlags.DropExpanded);
|
return (result.flags.HasFlag(DrawTypeMetaBlockResultFlags.DropExpanded), result.optionsWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
@ -743,12 +745,12 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static DrawTypeMetaBlockResultFlags DrawTypeMetaBlock_Internal(ref Rect rect, SerializedProperty rootProperty, ITypeMeta meta, int index = -1, int total = -1)
|
private static (DrawTypeMetaBlockResultFlags flags, float optionsWidth) DrawTypeMetaBlock_Internal(ref Rect rect, SerializedProperty rootProperty, ITypeMeta meta, int index = -1, int total = -1)
|
||||||
{
|
{
|
||||||
if (meta == null)
|
if (meta == null)
|
||||||
{
|
{
|
||||||
EditorGUI.DrawRect(rect, Color.black.SetAlpha(EscEditorConsts.COMPONENT_DRAWER_ALPHA));
|
EditorGUI.DrawRect(rect, Color.black.SetAlpha(EscEditorConsts.COMPONENT_DRAWER_ALPHA));
|
||||||
return DrawTypeMetaBlockResultFlags.None;
|
return (DrawTypeMetaBlockResultFlags.None, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
//string name = meta.Name;
|
//string name = meta.Name;
|
||||||
@ -772,6 +774,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
|
|
||||||
EditorGUI.DrawRect(rect, panelColor);
|
EditorGUI.DrawRect(rect, panelColor);
|
||||||
|
|
||||||
|
float optionsWidth = 0f;
|
||||||
Rect optionRect = rect;
|
Rect optionRect = rect;
|
||||||
rect = rect.AddPadding(DrawTypeMetaBlockPadding * 2f);
|
rect = rect.AddPadding(DrawTypeMetaBlockPadding * 2f);
|
||||||
|
|
||||||
@ -781,38 +784,45 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
optionRect.xMin = optionRect.xMax - 64;
|
optionRect.xMin = optionRect.xMax - 64;
|
||||||
optionRect.center += Vector2.up * DrawTypeMetaBlockPadding;
|
optionRect.center += Vector2.up * DrawTypeMetaBlockPadding;
|
||||||
|
|
||||||
|
|
||||||
DrawTypeMetaBlockResultFlags result = DrawTypeMetaBlockResultFlags.None;
|
DrawTypeMetaBlockResultFlags result = DrawTypeMetaBlockResultFlags.None;
|
||||||
using (CheckChanged())
|
using (CheckChanged())
|
||||||
{
|
{
|
||||||
//Canceling isExpanded
|
//Canceling isExpanded
|
||||||
bool oldIsExpanded = rootProperty.isExpanded;
|
//bool oldIsExpanded = rootProperty.isExpanded;
|
||||||
if (ClickTest(optionRect))
|
//if (ClickTest(optionRect))
|
||||||
{
|
//{
|
||||||
rootProperty.isExpanded = oldIsExpanded;
|
// rootProperty.isExpanded = oldIsExpanded;
|
||||||
result |= DrawTypeMetaBlockResultFlags.DropExpanded;
|
// result |= DrawTypeMetaBlockResultFlags.DropExpanded;
|
||||||
}
|
//}
|
||||||
|
|
||||||
//Close button
|
//Close button
|
||||||
optionRect.xMin = optionRect.xMax - HeadIconsRect.width;
|
optionRect.xMin = optionRect.xMax - HeadIconsRect.width;
|
||||||
|
optionsWidth += optionRect.width;
|
||||||
|
|
||||||
if (CloseButton(optionRect))
|
if (CloseButton(optionRect))
|
||||||
{
|
{
|
||||||
result |= DrawTypeMetaBlockResultFlags.CloseButtonClicked;
|
result |= DrawTypeMetaBlockResultFlags.CloseButtonClicked;
|
||||||
return result;
|
return (result, optionsWidth);
|
||||||
}
|
}
|
||||||
//Edit script button
|
//Edit script button
|
||||||
if (ScriptsCache.TryGetScriptAsset(meta.FindRootTypeMeta(), out MonoScript script))
|
if (ScriptsCache.TryGetScriptAsset(meta.FindRootTypeMeta(), out MonoScript script))
|
||||||
{
|
{
|
||||||
optionRect = HeadIconsRect.MoveTo(optionRect.center - (Vector2.right * optionRect.width));
|
optionRect = HeadIconsRect.MoveTo(optionRect.center - (Vector2.right * optionRect.width));
|
||||||
|
optionsWidth += optionRect.width;
|
||||||
|
|
||||||
ScriptAssetButton(optionRect, script);
|
ScriptAssetButton(optionRect, script);
|
||||||
}
|
}
|
||||||
//Description icon
|
//Description icon
|
||||||
if (string.IsNullOrEmpty(description) == false)
|
if (string.IsNullOrEmpty(description) == false)
|
||||||
{
|
{
|
||||||
optionRect = HeadIconsRect.MoveTo(optionRect.center - (Vector2.right * optionRect.width));
|
optionRect = HeadIconsRect.MoveTo(optionRect.center - (Vector2.right * optionRect.width));
|
||||||
|
optionsWidth += optionRect.width;
|
||||||
|
|
||||||
DescriptionIcon(optionRect, description);
|
DescriptionIcon(optionRect, description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return (result, optionsWidth);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -978,11 +988,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
#region Init
|
#region Init
|
||||||
private static ReferenceDropDown GetReferenceDropDown(Type[] predicatTypes, Type[] sortedWithOutTypes)
|
private static ReferenceDropDown GetReferenceDropDown(Type[] predicatTypes, Type[] sortedWithOutTypes)
|
||||||
{
|
{
|
||||||
if (_predicatTypesMenus.TryGetValue((predicatTypes, sortedWithOutTypes), out ReferenceDropDown menu) == false)
|
if (_predicatTypesMenus.TryGetValue(new PredicateTypesKey(predicatTypes[0], predicatTypes, sortedWithOutTypes), out ReferenceDropDown menu) == false)
|
||||||
{
|
{
|
||||||
menu = new ReferenceDropDown(predicatTypes, sortedWithOutTypes);
|
menu = new ReferenceDropDown(predicatTypes, sortedWithOutTypes);
|
||||||
menu.OnSelected += SelectComponent;
|
menu.OnSelected += SelectComponent;
|
||||||
_predicatTypesMenus.Add((predicatTypes, sortedWithOutTypes), menu);
|
_predicatTypesMenus.Add(new PredicateTypesKey(predicatTypes[0], predicatTypes, sortedWithOutTypes), menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
|
|||||||
@ -17,6 +17,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.UIElements;
|
||||||
using UnityObject = UnityEngine.Object;
|
using UnityObject = UnityEngine.Object;
|
||||||
|
|
||||||
|
|
||||||
@ -213,21 +214,30 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
_isStaticInit = true;
|
_isStaticInit = true;
|
||||||
OnStaticInit();
|
OnStaticInit();
|
||||||
}
|
}
|
||||||
public void Init()
|
public void Init(SerializedProperty property)
|
||||||
{
|
{
|
||||||
if (IsInit) { return; }
|
if (IsInit) { return; }
|
||||||
_isInit = true;
|
_isInit = true;
|
||||||
OnInit();
|
OnInit(property);
|
||||||
}
|
}
|
||||||
protected virtual void OnStaticInit() { }
|
protected virtual void OnStaticInit() { }
|
||||||
protected virtual void OnInit() { }
|
protected virtual void OnInit(SerializedProperty property) { }
|
||||||
|
|
||||||
|
|
||||||
|
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||||
|
{
|
||||||
|
StaticInit();
|
||||||
|
Init(property);
|
||||||
|
return GetCustomHeight(property, label);
|
||||||
|
}
|
||||||
|
protected abstract float GetCustomHeight(SerializedProperty property, GUIContent label);
|
||||||
|
|
||||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||||
{
|
{
|
||||||
using (EcsGUI.CheckChanged(property.serializedObject))
|
using (EcsGUI.CheckChanged(property.serializedObject))
|
||||||
{
|
{
|
||||||
StaticInit();
|
StaticInit();
|
||||||
Init();
|
Init(property);
|
||||||
DrawCustom(position, property, label);
|
DrawCustom(position, property, label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,93 +86,94 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal class ComponentTemplatesDropDown : MetaObjectsDropDown<ComponentTemplateTypeCache>
|
//internal class ComponentTemplatesDropDown : MetaObjectsDropDown<ComponentTemplateTypeCache>
|
||||||
{
|
//{
|
||||||
private ComponentTemplatesDropDown() { }
|
// private ComponentTemplatesDropDown() { }
|
||||||
|
//
|
||||||
private bool _isCheckUnique;
|
// private bool _isCheckUnique;
|
||||||
private SerializedProperty _arrayProperty;
|
// private SerializedProperty _arrayProperty;
|
||||||
private SerializedProperty _fieldProperty;
|
// private SerializedProperty _fieldProperty;
|
||||||
|
//
|
||||||
public static Dictionary<PredicateTypesKey, ComponentTemplatesDropDown> _dropDownsCache = new Dictionary<PredicateTypesKey, ComponentTemplatesDropDown>(32);
|
// public static Dictionary<PredicateTypesKey, ComponentTemplatesDropDown> _dropDownsCache = new Dictionary<PredicateTypesKey, ComponentTemplatesDropDown>(32);
|
||||||
public static ComponentTemplatesDropDown Get(PredicateTypesKey key)
|
// public static ComponentTemplatesDropDown Get(PredicateTypesKey key)
|
||||||
{
|
// {
|
||||||
if(_dropDownsCache.TryGetValue(key, out var result) == false)
|
// if(_dropDownsCache.TryGetValue(key, out var result) == false)
|
||||||
{
|
// {
|
||||||
result = new ComponentTemplatesDropDown();
|
// result = new ComponentTemplatesDropDown();
|
||||||
IEnumerable<(ComponentTemplateTypeCache template, ITypeMeta meta)> itemMetaPairs = ComponentTemplateTypeCache.All.ToArray()
|
// IEnumerable<(ComponentTemplateTypeCache template, ITypeMeta meta)> itemMetaPairs = ComponentTemplateTypeCache.All.ToArray()
|
||||||
.Where(o =>
|
// .Where(o =>
|
||||||
{
|
// {
|
||||||
return key.Check(o.Type);
|
// return key.Check(o.Type);
|
||||||
})
|
// })
|
||||||
.Select(o =>
|
// .Select(o =>
|
||||||
{
|
// {
|
||||||
return (o, o.Meta);
|
// return (o, o.Meta);
|
||||||
});
|
// });
|
||||||
//TODO оптимизировать или вырезать
|
//
|
||||||
itemMetaPairs = itemMetaPairs.OrderBy(o => o.meta.Group.Name);
|
// //TODO оптимизировать или вырезать
|
||||||
result.Setup(itemMetaPairs);
|
// itemMetaPairs = itemMetaPairs.OrderBy(o => o.meta.Group.Name);
|
||||||
_dropDownsCache[key] = result;
|
// result.Setup(itemMetaPairs);
|
||||||
}
|
// _dropDownsCache[key] = result;
|
||||||
return result;
|
// }
|
||||||
}
|
// return result;
|
||||||
|
// }
|
||||||
public void OpenForArray(Rect position, SerializedProperty arrayProperty, bool isCheckUnique)
|
//
|
||||||
{
|
// public void OpenForArray(Rect position, SerializedProperty arrayProperty, bool isCheckUnique)
|
||||||
_isCheckUnique = isCheckUnique;
|
// {
|
||||||
_arrayProperty = arrayProperty;
|
// _isCheckUnique = isCheckUnique;
|
||||||
_fieldProperty = null;
|
// _arrayProperty = arrayProperty;
|
||||||
Show(position);
|
// _fieldProperty = null;
|
||||||
}
|
// Show(position);
|
||||||
public void OpenForField(Rect position, SerializedProperty fieldProperty)
|
// }
|
||||||
{
|
// public void OpenForField(Rect position, SerializedProperty fieldProperty)
|
||||||
_isCheckUnique = false;
|
// {
|
||||||
_arrayProperty = null;
|
// _isCheckUnique = false;
|
||||||
_fieldProperty = fieldProperty;
|
// _arrayProperty = null;
|
||||||
Show(position);
|
// _fieldProperty = fieldProperty;
|
||||||
}
|
// Show(position);
|
||||||
|
// }
|
||||||
protected override void ItemSelected(Item item)
|
//
|
||||||
{
|
// protected override void ItemSelected(Item item)
|
||||||
base.ItemSelected(item);
|
// {
|
||||||
|
// base.ItemSelected(item);
|
||||||
if (item.Obj == null)
|
//
|
||||||
{
|
// if (item.Obj == null)
|
||||||
_fieldProperty.managedReferenceValue = null;
|
// {
|
||||||
_fieldProperty.serializedObject.ApplyModifiedProperties();
|
// _fieldProperty.managedReferenceValue = null;
|
||||||
return;
|
// _fieldProperty.serializedObject.ApplyModifiedProperties();
|
||||||
}
|
// return;
|
||||||
|
// }
|
||||||
Type componentType = item.Obj.GetType();
|
//
|
||||||
var data = item.Obj;
|
// Type componentType = item.Obj.GetType();
|
||||||
|
// var data = item.Obj;
|
||||||
if (_arrayProperty != null && data != null)
|
//
|
||||||
{
|
// if (_arrayProperty != null && data != null)
|
||||||
int index = _arrayProperty.arraySize;
|
// {
|
||||||
if (_isCheckUnique)
|
// int index = _arrayProperty.arraySize;
|
||||||
{
|
// if (_isCheckUnique)
|
||||||
if (data.IsUnique)
|
// {
|
||||||
{
|
// if (data.IsUnique)
|
||||||
for (int i = 0, iMax = _arrayProperty.arraySize; i < iMax; i++)
|
// {
|
||||||
{
|
// for (int i = 0, iMax = _arrayProperty.arraySize; i < iMax; i++)
|
||||||
if (_arrayProperty.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType)
|
// {
|
||||||
{
|
// if (_arrayProperty.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType)
|
||||||
return;
|
// {
|
||||||
}
|
// return;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
_arrayProperty.arraySize += 1;
|
// }
|
||||||
_fieldProperty = _arrayProperty.GetArrayElementAtIndex(index);
|
// _arrayProperty.arraySize += 1;
|
||||||
}
|
// _fieldProperty = _arrayProperty.GetArrayElementAtIndex(index);
|
||||||
|
// }
|
||||||
if (_fieldProperty != null)
|
//
|
||||||
{
|
// if (_fieldProperty != null)
|
||||||
_fieldProperty.managedReferenceValue = data.CreateInstance();
|
// {
|
||||||
_fieldProperty.serializedObject.ApplyModifiedProperties();
|
// _fieldProperty.managedReferenceValue = data.CreateInstance();
|
||||||
}
|
// _fieldProperty.serializedObject.ApplyModifiedProperties();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//}
|
||||||
internal class RuntimeComponentsDropDown : MetaObjectsDropDown<IEcsPool>
|
internal class RuntimeComponentsDropDown : MetaObjectsDropDown<IEcsPool>
|
||||||
{
|
{
|
||||||
public RuntimeComponentsDropDown(IEnumerable<IEcsPool> pools)
|
public RuntimeComponentsDropDown(IEnumerable<IEcsPool> pools)
|
||||||
@ -215,6 +216,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
private bool _isContainsNull;
|
private bool _isContainsNull;
|
||||||
public IEnumerable<(T, ITypeMeta)> _itemMetaPairs;
|
public IEnumerable<(T, ITypeMeta)> _itemMetaPairs;
|
||||||
|
|
||||||
|
public virtual bool IsStaticList { get { return true; } }
|
||||||
public MetaObjectsDropDown() : base(new AdvancedDropdownState())
|
public MetaObjectsDropDown() : base(new AdvancedDropdownState())
|
||||||
{
|
{
|
||||||
minimumSize = new Vector2(220f, EditorGUIUtility.singleLineHeight * 20);
|
minimumSize = new Vector2(220f, EditorGUIUtility.singleLineHeight * 20);
|
||||||
@ -225,6 +227,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
_name = name;
|
_name = name;
|
||||||
_isContainsNull = isContainsNull;
|
_isContainsNull = isContainsNull;
|
||||||
_itemMetaPairs = itemMetaPairs;
|
_itemMetaPairs = itemMetaPairs;
|
||||||
|
if (IsStaticList)
|
||||||
|
{
|
||||||
|
_itemMetaPairs = _itemMetaPairs.ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
protected override AdvancedDropdownItem BuildRoot()
|
protected override AdvancedDropdownItem BuildRoot()
|
||||||
{
|
{
|
||||||
@ -235,10 +241,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
{
|
{
|
||||||
root.AddChild(new Item(default, "<NULL>", increment++));
|
root.AddChild(new Item(default, "<NULL>", increment++));
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<Key, Item> dict = new Dictionary<Key, Item>();
|
Dictionary<Key, Item> dict = new Dictionary<Key, Item>();
|
||||||
|
|
||||||
|
var list = _itemMetaPairs.ToArray();
|
||||||
foreach (var pair in _itemMetaPairs)
|
foreach (var pair in _itemMetaPairs)
|
||||||
{
|
{
|
||||||
ITypeMeta meta = pair.Item2;
|
ITypeMeta meta = pair.Item2;
|
||||||
|
|||||||
@ -1,117 +1,109 @@
|
|||||||
using System;
|
//using System;
|
||||||
|
//
|
||||||
namespace DCFApixels.DragonECS.Unity.Editors
|
//#if UNITY_EDITOR
|
||||||
{
|
//namespace DCFApixels.DragonECS.Unity.Internal
|
||||||
internal interface IReferenceButtonAttribute
|
//{
|
||||||
{
|
// using DCFApixels.DragonECS.Unity.Editors;
|
||||||
Type[] PredicateTypes { get; }
|
// using UnityEditor;
|
||||||
bool IsHideButtonIfNotNull { get; }
|
// internal partial class UnityReflectionCache
|
||||||
}
|
// {
|
||||||
}
|
// public bool IsReferenceButtonCacheInit_Editor;
|
||||||
|
// public bool InitReferenceButtonCache_Editor(SerializedProperty sp)
|
||||||
#if UNITY_EDITOR
|
// {
|
||||||
namespace DCFApixels.DragonECS.Unity.Internal
|
// if (IsReferenceButtonCacheInit_Editor) { return false; }
|
||||||
{
|
//
|
||||||
using DCFApixels.DragonECS.Unity.Editors;
|
// HasSerializableData_Editor = sp.HasSerializableData();
|
||||||
using UnityEditor;
|
//
|
||||||
internal partial class UnityReflectionCache
|
// IsReferenceButtonCacheInit_Editor = true;
|
||||||
{
|
// return true;
|
||||||
public bool IsReferenceButtonCacheInit_Editor;
|
// }
|
||||||
public bool InitReferenceButtonCache_Editor(SerializedProperty sp)
|
// public bool HasSerializableData_Editor;
|
||||||
{
|
// }
|
||||||
if (IsReferenceButtonCacheInit_Editor) { return false; }
|
//}
|
||||||
|
//
|
||||||
HasSerializableData_Editor = sp.HasSerializableData();
|
//namespace DCFApixels.DragonECS.Unity.Editors
|
||||||
|
//{
|
||||||
IsReferenceButtonCacheInit_Editor = true;
|
// using DCFApixels.DragonECS.Unity.Internal;
|
||||||
return true;
|
// using System;
|
||||||
}
|
// using UnityEditor;
|
||||||
public bool HasSerializableData_Editor;
|
// using UnityEngine;
|
||||||
}
|
//
|
||||||
}
|
// [CustomPropertyDrawer(typeof(ReferenceButtonAttribute), true)]
|
||||||
|
// internal sealed class ReferenceButtonAttributeDrawer : ExtendedPropertyDrawer<IReferenceButtonAttribute>
|
||||||
namespace DCFApixels.DragonECS.Unity.Editors
|
// {
|
||||||
{
|
// private Type[] _withOutTypes;
|
||||||
using DCFApixels.DragonECS.Unity.Internal;
|
//
|
||||||
using System;
|
// protected override void OnInit(SerializedProperty property)
|
||||||
using UnityEditor;
|
// {
|
||||||
using UnityEngine;
|
// Type fieldType = fieldInfo.FieldType;
|
||||||
|
// _withOutTypes = fieldType.TryGetAttribute(out ReferenceButtonWithOutAttribute a) ? a.PredicateTypes : Array.Empty<Type>();
|
||||||
[CustomPropertyDrawer(typeof(ReferenceButtonAttribute), true)]
|
// //if (fieldType.IsGenericType)
|
||||||
internal sealed class ReferenceButtonAttributeDrawer : ExtendedPropertyDrawer<IReferenceButtonAttribute>
|
// //{
|
||||||
{
|
// // if (fieldType.IsGenericTypeDefinition == false)
|
||||||
private Type[] _withOutTypes;
|
// // {
|
||||||
protected override void OnInit()
|
// // fieldType = fieldType.GetGenericTypeDefinition();
|
||||||
{
|
// // }
|
||||||
Type fieldType = fieldInfo.FieldType;
|
// //}
|
||||||
_withOutTypes = fieldType.TryGetAttribute(out ReferenceButtonWithOutAttribute a) ? a.PredicateTypes : Array.Empty<Type>();
|
// }
|
||||||
//if (fieldType.IsGenericType)
|
//
|
||||||
//{
|
// private UnityReflectionCache _reflectionCache;
|
||||||
// if (fieldType.IsGenericTypeDefinition == false)
|
// private UnityReflectionCache Cahce(SerializedProperty sp)
|
||||||
// {
|
// {
|
||||||
// fieldType = fieldType.GetGenericTypeDefinition();
|
// if (UnityReflectionCache.InitLocal(sp.managedReferenceValue.GetType(), ref _reflectionCache))
|
||||||
// }
|
// {
|
||||||
//}
|
// _reflectionCache.InitReferenceButtonCache_Editor(sp);
|
||||||
}
|
// }
|
||||||
|
// return _reflectionCache;
|
||||||
private UnityReflectionCache _reflectionCache;
|
// }
|
||||||
private UnityReflectionCache Cahce(SerializedProperty sp)
|
//
|
||||||
{
|
// public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||||
if (UnityReflectionCache.InitLocal(sp.managedReferenceValue.GetType(), ref _reflectionCache))
|
// {
|
||||||
{
|
// Init(property);
|
||||||
_reflectionCache.InitReferenceButtonCache_Editor(sp);
|
// if (property.propertyType == SerializedPropertyType.ManagedReference &&
|
||||||
}
|
// property.managedReferenceValue != null &&
|
||||||
return _reflectionCache;
|
// Cahce(property).HasSerializableData_Editor)
|
||||||
}
|
// {
|
||||||
|
// return EditorGUI.GetPropertyHeight(property, label, true);
|
||||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
// }
|
||||||
{
|
// else
|
||||||
Init();
|
// {
|
||||||
if (property.propertyType == SerializedPropertyType.ManagedReference &&
|
// return OneLineHeight;
|
||||||
property.managedReferenceValue != null &&
|
// }
|
||||||
Cahce(property).HasSerializableData_Editor)
|
// }
|
||||||
{
|
//
|
||||||
return EditorGUI.GetPropertyHeight(property, label, true);
|
// protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
|
||||||
}
|
// {
|
||||||
else
|
// if(property.propertyType != SerializedPropertyType.ManagedReference)
|
||||||
{
|
// {
|
||||||
return OneLineHeight;
|
// GUI.Label(position, label);
|
||||||
}
|
// return;
|
||||||
}
|
// }
|
||||||
|
// if (IsArrayElement)
|
||||||
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
|
// {
|
||||||
{
|
// label = UnityEditorUtility.GetLabelTemp();
|
||||||
if(property.propertyType != SerializedPropertyType.ManagedReference)
|
// }
|
||||||
{
|
// Rect selButtnoRect = position;
|
||||||
GUI.Label(position, label);
|
// selButtnoRect.height = OneLineHeight;
|
||||||
return;
|
// DrawSelectionPopupButton(selButtnoRect, property);
|
||||||
}
|
//
|
||||||
if (IsArrayElement)
|
// if (property.managedReferenceValue != null &&
|
||||||
{
|
// Cahce(property).HasSerializableData_Editor)
|
||||||
label = UnityEditorUtility.GetLabelTemp();
|
// {
|
||||||
}
|
// EditorGUI.PropertyField(position, property, label, true);
|
||||||
Rect selButtnoRect = position;
|
// }
|
||||||
selButtnoRect.height = OneLineHeight;
|
// else
|
||||||
DrawSelectionPopupButton(selButtnoRect, property);
|
// {
|
||||||
|
// EditorGUI.BeginProperty(position, label, property);
|
||||||
if (property.managedReferenceValue != null &&
|
// EditorGUI.LabelField(position, label);
|
||||||
Cahce(property).HasSerializableData_Editor)
|
// EditorGUI.EndProperty();
|
||||||
{
|
// }
|
||||||
EditorGUI.PropertyField(position, property, label, true);
|
// }
|
||||||
}
|
//
|
||||||
else
|
// private void DrawSelectionPopupButton(Rect position, SerializedProperty property)
|
||||||
{
|
// {
|
||||||
EditorGUI.BeginProperty(position, label, property);
|
// Rect buttonRect = IsArrayElement ? position : position.AddPadding(EditorGUIUtility.labelWidth, 0f, 0f, 0f); ;
|
||||||
EditorGUI.LabelField(position, label);
|
// EcsGUI.DrawSelectReferenceButton(buttonRect, property, Attribute.PredicateTypes.Length == 0 ? new Type[1] { fieldInfo.FieldType } : Attribute.PredicateTypes, _withOutTypes, Attribute.IsHideButtonIfNotNull);
|
||||||
EditorGUI.EndProperty();
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//#endif
|
||||||
private void DrawSelectionPopupButton(Rect position, SerializedProperty property)
|
|
||||||
{
|
|
||||||
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, _withOutTypes, Attribute.IsHideButtonIfNotNull);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -105,10 +105,6 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
|||||||
}
|
}
|
||||||
return _memberwiseCloneMethdo.Invoke(obj, null);
|
return _memberwiseCloneMethdo.Invoke(obj, null);
|
||||||
}
|
}
|
||||||
internal static object Clone_Reflection<T>(this T obj)
|
|
||||||
{
|
|
||||||
return Clone_Reflection((object)obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal partial class UnityReflectionCache
|
internal partial class UnityReflectionCache
|
||||||
|
|||||||
@ -1,24 +1,30 @@
|
|||||||
using System;
|
using System;
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS.Unity.Internal
|
namespace DCFApixels.DragonECS.Unity.Internal
|
||||||
{
|
{
|
||||||
internal readonly struct PredicateTypesKey : IEquatable<PredicateTypesKey>
|
internal readonly struct PredicateTypesKey : IEquatable<PredicateTypesKey>
|
||||||
{
|
{
|
||||||
public readonly Type[] Types;
|
public readonly Type TargetType;
|
||||||
|
public readonly Type[] AllowTypes;
|
||||||
public readonly Type[] WithoutTypes;
|
public readonly Type[] WithoutTypes;
|
||||||
public PredicateTypesKey(Type[] types) : this(types, Type.EmptyTypes) { }
|
public PredicateTypesKey(Type signleType) : this(signleType, new Type[] { signleType } , Type.EmptyTypes) { }
|
||||||
public PredicateTypesKey(Type[] types, Type[] withoutTypes)
|
public PredicateTypesKey(Type targetType, Type[] types) : this(targetType, types, Type.EmptyTypes) { }
|
||||||
|
public PredicateTypesKey(Type targetType, Type[] types, Type[] withoutTypes)
|
||||||
{
|
{
|
||||||
Types = types;
|
if(targetType == null)
|
||||||
|
{
|
||||||
|
Throw.ArgumentNullException();
|
||||||
|
}
|
||||||
|
TargetType = targetType;
|
||||||
|
AllowTypes = types;
|
||||||
WithoutTypes = withoutTypes;
|
WithoutTypes = withoutTypes;
|
||||||
}
|
}
|
||||||
public bool Check(Type type)
|
public bool Check(Type type)
|
||||||
{
|
{
|
||||||
bool isAssignable = false;
|
bool isAssignable = AllowTypes.Length == 0;
|
||||||
foreach (Type predicateTypes in Types)
|
foreach (Type allowType in AllowTypes)
|
||||||
{
|
{
|
||||||
if (predicateTypes.IsAssignableFrom(type))
|
if (allowType.IsAssignableFrom(type))
|
||||||
{
|
{
|
||||||
isAssignable = true;
|
isAssignable = true;
|
||||||
break;
|
break;
|
||||||
@ -37,15 +43,20 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return isAssignable;
|
return isAssignable && TargetType.IsAssignableFrom(type);
|
||||||
}
|
}
|
||||||
public bool Equals(PredicateTypesKey other)
|
public bool Equals(PredicateTypesKey other)
|
||||||
{
|
{
|
||||||
if (Types.Length != other.Types.Length) { return false; }
|
if (AllowTypes.Length != other.AllowTypes.Length) { return false; }
|
||||||
if (WithoutTypes.Length != other.WithoutTypes.Length) { return false; }
|
if (WithoutTypes.Length != other.WithoutTypes.Length) { return false; }
|
||||||
for (int i = 0; i < Types.Length; i++)
|
|
||||||
|
if (TargetType != other.TargetType)
|
||||||
{
|
{
|
||||||
if (Types[i] != other.Types[i])
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < AllowTypes.Length; i++)
|
||||||
|
{
|
||||||
|
if (AllowTypes[i] != other.AllowTypes[i])
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -65,8 +76,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
|||||||
}
|
}
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return HashCode.Combine(Types, WithoutTypes);
|
return HashCode.Combine(TargetType, AllowTypes, WithoutTypes);
|
||||||
}
|
}
|
||||||
public static implicit operator PredicateTypesKey((Type[], Type[]) types) { return new PredicateTypesKey(types.Item1, types.Item2); }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,6 +8,10 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
|||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
internal static void ArgumentNullException()
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException();
|
||||||
|
}
|
||||||
internal static void Argument(string message)
|
internal static void Argument(string message)
|
||||||
{
|
{
|
||||||
throw new ArgumentException(message);
|
throw new ArgumentException(message);
|
||||||
|
|||||||
@ -12,7 +12,10 @@ namespace DCFApixels.DragonECS
|
|||||||
public struct ComponentTemplateProperty : IEquatable<ComponentTemplateProperty>
|
public struct ComponentTemplateProperty : IEquatable<ComponentTemplateProperty>
|
||||||
{
|
{
|
||||||
[SerializeReference]
|
[SerializeReference]
|
||||||
|
[ReferenceDropDown]
|
||||||
|
[TypeMetaBlock]
|
||||||
private ITemplateNode _template;
|
private ITemplateNode _template;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ComponentTemplateProperty(ITemplateNode template)
|
public ComponentTemplateProperty(ITemplateNode template)
|
||||||
{
|
{
|
||||||
@ -28,7 +31,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public Type Type
|
public Type Type
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get { return _template is IComponentTemplate tml ? tml.Type : _template.GetType(); }
|
get { return _template is IComponentTemplate tml ? tml.ComponentType : _template.GetType(); }
|
||||||
}
|
}
|
||||||
public bool IsNull
|
public bool IsNull
|
||||||
{
|
{
|
||||||
@ -83,12 +86,19 @@ namespace DCFApixels.DragonECS
|
|||||||
public readonly struct Null { }
|
public readonly struct Null { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ComponentTemplateFieldAttribute : PropertyAttribute, IReferenceButtonAttribute
|
public sealed class ComponentTemplateFieldAttribute : PropertyAttribute, IReferenceDropDownAttribute
|
||||||
{
|
{
|
||||||
public Type[] PredicateTypes;
|
public Type[] PredicateTypes;
|
||||||
Type[] IReferenceButtonAttribute.PredicateTypes { get { return PredicateTypes; } }
|
public readonly bool IsHideButtonIfNotNull = true;
|
||||||
bool IReferenceButtonAttribute.IsHideButtonIfNotNull { get { return true; } }
|
Type[] IReferenceDropDownAttribute.PredicateTypes { get { return PredicateTypes; } }
|
||||||
public ComponentTemplateFieldAttribute() { }
|
bool IReferenceDropDownAttribute.IsHideButtonIfNotNull { get { return IsHideButtonIfNotNull; } }
|
||||||
|
public ComponentTemplateFieldAttribute(bool isHideButtonIfNotNull = false) : this(isHideButtonIfNotNull, Array.Empty<Type>()) { }
|
||||||
|
public ComponentTemplateFieldAttribute(params Type[] predicateTypes) : this(false, predicateTypes) { }
|
||||||
|
public ComponentTemplateFieldAttribute(bool isHideButtonIfNotNull, params Type[] predicateTypes)
|
||||||
|
{
|
||||||
|
IsHideButtonIfNotNull = isHideButtonIfNotNull;
|
||||||
|
PredicateTypes = predicateTypes;
|
||||||
|
Array.Sort(predicateTypes, (a, b) => string.Compare(a.AssemblyQualifiedName, b.AssemblyQualifiedName, StringComparison.Ordinal));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public sealed class ComponentTemplateAttribute : PropertyAttribute { }
|
|
||||||
}
|
}
|
||||||
@ -9,200 +9,222 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
[CustomPropertyDrawer(typeof(ComponentTemplateProperty), true)]
|
[CustomPropertyDrawer(typeof(ComponentTemplateProperty), true)]
|
||||||
internal class ComponentTemplatePropertyDrawer : ExtendedPropertyDrawer
|
internal class ComponentTemplatePropertyDrawer : ExtendedPropertyDrawer
|
||||||
{
|
{
|
||||||
private ComponentTemplateReferenceDrawer _drawer = new ComponentTemplateReferenceDrawer(new PredicateTypesKey(new Type[] { typeof(ITemplateNode) }));
|
//private EcsDragonFieldDrawer _drawer = new EcsDragonFieldDrawer(new PredicateTypesKey(typeof(ITemplateNode)));
|
||||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
//protected override float GetCustomHeight(SerializedProperty property, GUIContent label)
|
||||||
|
//{
|
||||||
|
// property.Next(true);
|
||||||
|
// _drawer.StaticInit();
|
||||||
|
// _drawer.Init(property);
|
||||||
|
// return _drawer.GetPropertyHeight(property, label);
|
||||||
|
//}
|
||||||
|
//protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
|
||||||
|
//{
|
||||||
|
// var root = property.Copy();
|
||||||
|
// property.Next(true);
|
||||||
|
// _drawer.StaticInit();
|
||||||
|
// _drawer.Init(property);
|
||||||
|
// _drawer.Draw(position, root, property, label);
|
||||||
|
//}
|
||||||
|
|
||||||
|
protected override float GetCustomHeight(SerializedProperty property, GUIContent label)
|
||||||
{
|
{
|
||||||
property.Next(true);
|
property.Next(true);
|
||||||
_drawer.StaticInit();
|
return EditorGUI.GetPropertyHeight(property, label);
|
||||||
_drawer.Init();
|
|
||||||
return _drawer.GetPropertyHeight(property, label);
|
|
||||||
}
|
}
|
||||||
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
|
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
|
||||||
{
|
{
|
||||||
var root = property.Copy();
|
var root = property.Copy();
|
||||||
property.Next(true);
|
property.Next(true);
|
||||||
_drawer.StaticInit();
|
EditorGUI.PropertyField(position, property, label);
|
||||||
_drawer.Init();
|
|
||||||
_drawer.Draw(position, root, property, label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[CustomPropertyDrawer(typeof(ComponentTemplateFieldAttribute), true)]
|
|
||||||
internal class ComponentTemplateReferenceDrawer : ExtendedPropertyDrawer<ComponentTemplateFieldAttribute>
|
|
||||||
{
|
|
||||||
private const float DamagedComponentHeight = 18f * 2f;
|
|
||||||
private ComponentTemplatesDropDown _componentDropDown;
|
|
||||||
private PredicateTypesKey? _predicateOverride;
|
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
private float Padding => Spacing;
|
|
||||||
protected override bool IsInit => _componentDropDown != null;
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public ComponentTemplateReferenceDrawer() { }
|
|
||||||
public ComponentTemplateReferenceDrawer(PredicateTypesKey key)
|
|
||||||
{
|
|
||||||
_predicateOverride = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Init
|
|
||||||
protected override void OnInit()
|
|
||||||
{
|
|
||||||
PredicateTypesKey key;
|
|
||||||
if(_predicateOverride == null)
|
|
||||||
{
|
|
||||||
Type[] withOutTypes = Type.EmptyTypes;
|
|
||||||
if (fieldInfo != null)
|
|
||||||
{
|
|
||||||
withOutTypes = fieldInfo.TryGetAttribute(out ReferenceButtonWithOutAttribute a) ? a.PredicateTypes : Array.Empty<Type>();
|
|
||||||
}
|
|
||||||
if (Attribute != null)
|
|
||||||
{
|
|
||||||
var types = Attribute.PredicateTypes;
|
|
||||||
if(types == null || types.Length == 0)
|
|
||||||
{
|
|
||||||
types = new Type[] { typeof(ITemplateNode) };
|
|
||||||
}
|
|
||||||
key = new PredicateTypesKey(types, withOutTypes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
key = new PredicateTypesKey(new Type[] { typeof(object) }, withOutTypes);
|
|
||||||
}
|
|
||||||
_predicateOverride = key;
|
|
||||||
}
|
|
||||||
_componentDropDown = ComponentTemplatesDropDown.Get(_predicateOverride.Value);
|
|
||||||
_componentDropDown.OnSelected += SelectComponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
[ThreadStatic]
|
|
||||||
private static SerializedProperty currentProperty;
|
|
||||||
private static void SelectComponent(ComponentTemplatesDropDown.Item item)
|
|
||||||
{
|
|
||||||
//EcsGUI.Changed = true;
|
|
||||||
object inst = item.Obj.CreateInstance();
|
|
||||||
currentProperty.managedReferenceValue = inst;
|
|
||||||
currentProperty.isExpanded = false;
|
|
||||||
currentProperty.serializedObject.ApplyModifiedProperties();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
|
||||||
{
|
|
||||||
bool isSerializeReference = property.propertyType == SerializedPropertyType.ManagedReference;
|
|
||||||
//#region No SerializeReference
|
|
||||||
//if (property.propertyType != SerializedPropertyType.ManagedReference)
|
|
||||||
//{
|
|
||||||
// return EditorGUI.GetPropertyHeight(property, label);
|
|
||||||
//}
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
if (isSerializeReference)
|
|
||||||
{
|
|
||||||
var instance = property.managedReferenceValue;
|
|
||||||
IComponentTemplate template = instance as IComponentTemplate;
|
|
||||||
if (instance == null)
|
|
||||||
{
|
|
||||||
return EditorGUIUtility.singleLineHeight + Padding * 2f;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (instance is ComponentTemplateBase customTemplate)
|
|
||||||
{
|
|
||||||
property = property.FindPropertyRelative("component");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
property = null;
|
|
||||||
}
|
|
||||||
if (property == null)
|
|
||||||
{
|
|
||||||
return DamagedComponentHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int propCount = EcsGUI.GetChildPropertiesCount(property);
|
|
||||||
|
|
||||||
return (propCount <= 0 ? EditorGUIUtility.singleLineHeight : EditorGUI.GetPropertyHeight(property, label)) + Padding * 4f;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
|
|
||||||
{
|
|
||||||
Draw(position, property, property, label);
|
|
||||||
}
|
|
||||||
public void Draw(Rect rect, SerializedProperty rootProperty, SerializedProperty property, GUIContent label)
|
|
||||||
{
|
|
||||||
bool isSerializeReference = property.propertyType == SerializedPropertyType.ManagedReference;
|
|
||||||
//#region No SerializeReference
|
|
||||||
//if (isSerializeReference == false)
|
|
||||||
//{
|
|
||||||
// EditorGUI.PropertyField(position, property, label, true);
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
ITypeMeta meta = null;
|
|
||||||
SerializedProperty componentProp = property;
|
|
||||||
if (isSerializeReference)
|
|
||||||
{
|
|
||||||
var instance = property.managedReferenceValue;
|
|
||||||
if (instance == null)
|
|
||||||
{
|
|
||||||
DrawSelectionPopup(rect, property, label);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IComponentTemplate template = instance as IComponentTemplate;
|
|
||||||
if (componentProp.managedReferenceValue is ComponentTemplateBase customTemplate)
|
|
||||||
{
|
|
||||||
componentProp = property.FindPropertyRelative("component");
|
|
||||||
}
|
|
||||||
if (componentProp == null)
|
|
||||||
{
|
|
||||||
DrawDamagedComponent(rect, "Damaged component template.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta = template is ITypeMeta metaOverride ? metaOverride : _predicateOverride.Value.Types[0].GetMeta();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
meta = fieldInfo.FieldType.GetMeta();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (EcsGUI.DrawTypeMetaBlock(ref rect, rootProperty, meta))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
label.text = meta.Name;
|
|
||||||
if (componentProp.propertyType == SerializedPropertyType.Generic)
|
|
||||||
{
|
|
||||||
EditorGUI.PropertyField(rect, componentProp, label, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EditorGUI.PropertyField(rect.AddPadding(0, 20f, 0, 0), componentProp, label, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = property;
|
|
||||||
_componentDropDown.Show(buttonRect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void DrawDamagedComponent(Rect position, string message)
|
|
||||||
{
|
|
||||||
EditorGUI.HelpBox(position, message, MessageType.Warning);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//[CustomPropertyDrawer(typeof(ComponentTemplateFieldAttribute), true)]
|
||||||
|
//internal class ComponentTemplateFieldDrawer : ExtendedPropertyDrawer<ComponentTemplateFieldAttribute>
|
||||||
|
//{
|
||||||
|
// private const float DamagedComponentHeight = 18f * 2f;
|
||||||
|
// private ComponentTemplatesDropDown _componentDropDown;
|
||||||
|
// private PredicateTypesKey? _predicateOverride;
|
||||||
|
//
|
||||||
|
// #region Properties
|
||||||
|
// private float Padding => Spacing;
|
||||||
|
// protected override bool IsInit => _componentDropDown != null;
|
||||||
|
// #endregion
|
||||||
|
//
|
||||||
|
// public ComponentTemplateFieldDrawer() { }
|
||||||
|
// public ComponentTemplateFieldDrawer(PredicateTypesKey key)
|
||||||
|
// {
|
||||||
|
// _predicateOverride = key;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// #region Init
|
||||||
|
// protected override void OnInit(SerializedProperty property)
|
||||||
|
// {
|
||||||
|
// PredicateTypesKey key;
|
||||||
|
// if(_predicateOverride == null)
|
||||||
|
// {
|
||||||
|
// Type[] withOutTypes = Type.EmptyTypes;
|
||||||
|
// if (fieldInfo != null)
|
||||||
|
// {
|
||||||
|
// withOutTypes = fieldInfo.TryGetAttribute(out ReferenceButtonWithOutAttribute a) ? a.PredicateTypes : Array.Empty<Type>();
|
||||||
|
// }
|
||||||
|
// if (Attribute != null)
|
||||||
|
// {
|
||||||
|
// var types = Attribute.PredicateTypes;
|
||||||
|
// if(types == null || types.Length == 0)
|
||||||
|
// {
|
||||||
|
// types = new Type[] { typeof(ITemplateNode) };
|
||||||
|
// }
|
||||||
|
// key = new PredicateTypesKey(typeof(ITemplateNode), types, withOutTypes);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// key = new PredicateTypesKey(typeof(object), withOutTypes);
|
||||||
|
// }
|
||||||
|
// _predicateOverride = key;
|
||||||
|
// }
|
||||||
|
// _componentDropDown = ComponentTemplatesDropDown.Get(_predicateOverride.Value);
|
||||||
|
// _componentDropDown.OnSelected += SelectComponent;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// [ThreadStatic]
|
||||||
|
// private static SerializedProperty currentProperty;
|
||||||
|
// private static void SelectComponent(ComponentTemplatesDropDown.Item item)
|
||||||
|
// {
|
||||||
|
// //EcsGUI.Changed = true;
|
||||||
|
// object inst = item.Obj.CreateInstance();
|
||||||
|
// currentProperty.managedReferenceValue = inst;
|
||||||
|
// currentProperty.isExpanded = false;
|
||||||
|
// currentProperty.serializedObject.ApplyModifiedProperties();
|
||||||
|
// }
|
||||||
|
// #endregion
|
||||||
|
//
|
||||||
|
// public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||||
|
// {
|
||||||
|
// bool isSerializeReference = property.propertyType == SerializedPropertyType.ManagedReference;
|
||||||
|
// //#region No SerializeReference
|
||||||
|
// //if (property.propertyType != SerializedPropertyType.ManagedReference)
|
||||||
|
// //{
|
||||||
|
// // return EditorGUI.GetPropertyHeight(property, label);
|
||||||
|
// //}
|
||||||
|
// //#endregion
|
||||||
|
//
|
||||||
|
// if (isSerializeReference)
|
||||||
|
// {
|
||||||
|
// var instance = property.managedReferenceValue;
|
||||||
|
// IComponentTemplate template = instance as IComponentTemplate;
|
||||||
|
// if (instance == null)
|
||||||
|
// {
|
||||||
|
// return EditorGUIUtility.singleLineHeight + Padding * 2f;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// if (instance is ComponentTemplateBase customTemplate)
|
||||||
|
// {
|
||||||
|
// property = property.FindPropertyRelative("component");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch
|
||||||
|
// {
|
||||||
|
// property = null;
|
||||||
|
// }
|
||||||
|
// if (property == null)
|
||||||
|
// {
|
||||||
|
// return DamagedComponentHeight;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// int propCount = EcsGUI.GetChildPropertiesCount(property);
|
||||||
|
//
|
||||||
|
// return (propCount <= 0 ? EditorGUIUtility.singleLineHeight : EditorGUI.GetPropertyHeight(property, label)) + Padding * 4f;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
|
||||||
|
// {
|
||||||
|
// Draw(position, property, property, label);
|
||||||
|
// }
|
||||||
|
// public void Draw(Rect rect, SerializedProperty rootProperty, SerializedProperty property, GUIContent label)
|
||||||
|
// {
|
||||||
|
// bool isSerializeReference = property.propertyType == SerializedPropertyType.ManagedReference;
|
||||||
|
// //#region No SerializeReference
|
||||||
|
// //if (isSerializeReference == false)
|
||||||
|
// //{
|
||||||
|
// // EditorGUI.PropertyField(position, property, label, true);
|
||||||
|
// // return;
|
||||||
|
// //}
|
||||||
|
// //#endregion
|
||||||
|
//
|
||||||
|
// ITypeMeta meta = null;
|
||||||
|
// SerializedProperty componentProp = property;
|
||||||
|
// if (isSerializeReference)
|
||||||
|
// {
|
||||||
|
// var template = property.managedReferenceValue;
|
||||||
|
// if (template == null)
|
||||||
|
// {
|
||||||
|
// DrawSelectionPopup(rect, property, label);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// IComponentTemplate componentTemplate = template as IComponentTemplate;
|
||||||
|
// if (componentProp.managedReferenceValue is ComponentTemplateBase customTemplate)
|
||||||
|
// {
|
||||||
|
// componentProp = property.FindPropertyRelative("component");
|
||||||
|
// }
|
||||||
|
// if (componentProp == null)
|
||||||
|
// {
|
||||||
|
// DrawDamagedComponent(rect, "Damaged component template.");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// meta = template as ITypeMeta;
|
||||||
|
// if (meta == null)
|
||||||
|
// {
|
||||||
|
// if (componentTemplate != null)
|
||||||
|
// {
|
||||||
|
// meta = componentTemplate.ComponentType.GetMeta();
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// meta = template.GetMeta();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// meta = fieldInfo.FieldType.GetMeta();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// if (EcsGUI.DrawTypeMetaBlock(ref rect, rootProperty, meta).skip)
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// label.text = meta.Name;
|
||||||
|
// if (componentProp.propertyType == SerializedPropertyType.Generic)
|
||||||
|
// {
|
||||||
|
// EditorGUI.PropertyField(rect, componentProp, label, true);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// EditorGUI.PropertyField(rect.AddPadding(0, 20f, 0, 0), componentProp, label, true);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// 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 = property;
|
||||||
|
// _componentDropDown.Show(buttonRect);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// private void DrawDamagedComponent(Rect position, string message)
|
||||||
|
// {
|
||||||
|
// EditorGUI.HelpBox(position, message, MessageType.Warning);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -10,13 +10,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
{
|
{
|
||||||
internal abstract class EntityTemplateEditorBase : ExtendedEditor
|
internal abstract class EntityTemplateEditorBase : ExtendedEditor
|
||||||
{
|
{
|
||||||
private ComponentTemplatesDropDown _componentDropDown;
|
private DragonFieldDropDown _componentDropDown;
|
||||||
|
|
||||||
private SerializedProperty _componentsProp;
|
private SerializedProperty _componentTemplatesProp;
|
||||||
|
private SerializedProperty _templatesProp;
|
||||||
private ReorderableList _reorderableComponentsList;
|
private ReorderableList _reorderableComponentsList;
|
||||||
private int _reorderableComponentsListLastCount;
|
private int _reorderableComponentsListLastCount;
|
||||||
|
|
||||||
private static readonly Type[] _predicateTypes = new Type[] { typeof(ITemplateNode) };
|
private static readonly Type[] _predicateTypes = new Type[] { typeof(IComponentTemplate), typeof(IEcsComponentMember) };
|
||||||
|
|
||||||
protected abstract bool IsSO { get; }
|
protected abstract bool IsSO { get; }
|
||||||
|
|
||||||
@ -24,11 +25,12 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
protected override bool IsInit { get { return _componentDropDown != null; } }
|
protected override bool IsInit { get { return _componentDropDown != null; } }
|
||||||
protected override void OnInit()
|
protected override void OnInit()
|
||||||
{
|
{
|
||||||
_componentDropDown = ComponentTemplatesDropDown.Get(new PredicateTypesKey(_predicateTypes, Type.EmptyTypes));
|
_componentDropDown = DragonFieldDropDown.Get(new PredicateTypesKey(typeof(ITemplateNode), _predicateTypes, Type.EmptyTypes));
|
||||||
|
|
||||||
_componentsProp = serializedObject.FindProperty("_componentTemplates");
|
_componentTemplatesProp = serializedObject.FindProperty("_componentTemplates");
|
||||||
|
_templatesProp = serializedObject.FindProperty("_templates");
|
||||||
|
|
||||||
_reorderableComponentsList = new ReorderableList(serializedObject, _componentsProp, true, false, false, false);
|
_reorderableComponentsList = new ReorderableList(serializedObject, _componentTemplatesProp, true, false, false, false);
|
||||||
_reorderableComponentsList.onAddCallback += OnReorderableComponentsListAdd;
|
_reorderableComponentsList.onAddCallback += OnReorderableComponentsListAdd;
|
||||||
_reorderableComponentsList.onRemoveCallback += OnReorderableListRemove;
|
_reorderableComponentsList.onRemoveCallback += OnReorderableListRemove;
|
||||||
_reorderableComponentsList.drawElementCallback += OnReorderableListDrawEmptyElement;
|
_reorderableComponentsList.drawElementCallback += OnReorderableListDrawEmptyElement;
|
||||||
@ -73,48 +75,67 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
|
|
||||||
private float OnReorderableComponentsListElementHeight(int index)
|
private float OnReorderableComponentsListElementHeight(int index)
|
||||||
{
|
{
|
||||||
var componentProperty = GetTargetProperty(_componentsProp.GetArrayElementAtIndex(index));
|
SerializedProperty prop = _componentTemplatesProp.GetArrayElementAtIndex(index);
|
||||||
float result = EditorGUI.GetPropertyHeight(componentProperty);
|
GUIContent label = UnityEditorUtility.GetLabelTemp();
|
||||||
return EcsGUI.GetTypeMetaBlockHeight(result) + Spacing * 2f;
|
return EditorGUI.GetPropertyHeight(prop, label) + Spacing * 2f;
|
||||||
|
//var componentProperty = GetTargetProperty(_componentTemplatesProp.GetArrayElementAtIndex(index));
|
||||||
|
//float result = EditorGUI.GetPropertyHeight(componentProperty);
|
||||||
|
//return EcsGUI.GetTypeMetaBlockHeight(result) + Spacing * 2f;
|
||||||
}
|
}
|
||||||
private void OnReorderableComponentsListDrawElement(Rect rect, int index, bool isActive, bool isFocused)
|
private void OnReorderableComponentsListDrawElement(Rect rect, int index, bool isActive, bool isFocused)
|
||||||
{
|
{
|
||||||
if (index < 0 || Event.current.type == EventType.Used) { return; }
|
SerializedProperty prop = _componentTemplatesProp.GetArrayElementAtIndex(index);
|
||||||
|
GUIContent label = UnityEditorUtility.GetLabelTemp();
|
||||||
rect = rect.AddPadding(OneLineHeight + Spacing, Spacing * 2f, Spacing, Spacing);
|
rect = rect.AddPadding(OneLineHeight + Spacing, Spacing * 2f, Spacing, Spacing);
|
||||||
using (EcsGUI.CheckChanged())
|
|
||||||
{
|
|
||||||
SerializedProperty prop = _componentsProp.GetArrayElementAtIndex(index);
|
|
||||||
|
|
||||||
IComponentTemplate template = prop.managedReferenceValue as IComponentTemplate;
|
EditorGUI.PropertyField(rect, prop, label);
|
||||||
if (template == null || prop.managedReferenceValue == null)
|
return;
|
||||||
{
|
//if (index < 0 || Event.current.type == EventType.Used) { return; }
|
||||||
//DrawDamagedComponent_Replaced(prop, index);
|
//rect = rect.AddPadding(OneLineHeight + Spacing, Spacing * 2f, Spacing, Spacing);
|
||||||
EditorGUI.PropertyField(rect, prop, UnityEditorUtility.GetLabel(prop.displayName), true);
|
//using (EcsGUI.CheckChanged())
|
||||||
return;
|
//{
|
||||||
}
|
// SerializedProperty prop = _componentTemplatesProp.GetArrayElementAtIndex(index);
|
||||||
|
//
|
||||||
var componentProp = GetTargetProperty(prop);
|
// var template = prop.managedReferenceValue;
|
||||||
|
// if (template == null)
|
||||||
|
// {
|
||||||
ITypeMeta meta = template is ITypeMeta metaOverride ? metaOverride : template.Type.GetMeta();
|
// //DrawDamagedComponent_Replaced(prop, index);
|
||||||
|
// EditorGUI.PropertyField(rect, prop, UnityEditorUtility.GetLabel(prop.displayName), true);
|
||||||
if (EcsGUI.DrawTypeMetaElementBlock(ref rect, _componentsProp, index, componentProp, meta))
|
// return;
|
||||||
{
|
// }
|
||||||
return;
|
// IComponentTemplate componentTemplate = template as IComponentTemplate;
|
||||||
}
|
// var componentProp = GetTargetProperty(prop);
|
||||||
|
//
|
||||||
|
// ITypeMeta meta = template as ITypeMeta;
|
||||||
GUIContent label = UnityEditorUtility.GetLabel(meta.Name);
|
// if(meta == null)
|
||||||
if (componentProp.propertyType == SerializedPropertyType.Generic)
|
// {
|
||||||
{
|
// if (componentTemplate != null)
|
||||||
EditorGUI.PropertyField(rect, componentProp, label, true);
|
// {
|
||||||
}
|
// meta = componentTemplate.ComponentType.GetMeta();
|
||||||
else
|
// }
|
||||||
{
|
// else
|
||||||
EditorGUI.PropertyField(rect.AddPadding(0, 20f, 0, 0), componentProp, label, true);
|
// {
|
||||||
}
|
// meta = template.GetMeta();
|
||||||
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// if (EcsGUI.DrawTypeMetaElementBlock(ref rect, _componentTemplatesProp, index, componentProp, meta).skip)
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// GUIContent label = UnityEditorUtility.GetLabel(meta.Name);
|
||||||
|
// if (componentProp.propertyType == SerializedPropertyType.Generic)
|
||||||
|
// {
|
||||||
|
// EditorGUI.PropertyField(rect, componentProp, label, true);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// EditorGUI.PropertyField(rect.AddPadding(0, 20f, 0, 0), componentProp, label, true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnReorderableComponentsListAdd(ReorderableList list)
|
private void OnReorderableComponentsListAdd(ReorderableList list)
|
||||||
@ -147,6 +168,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (IsSO)
|
if (IsSO)
|
||||||
{
|
{
|
||||||
EcsGUI.Layout.ManuallySerializeButton(targets);
|
EcsGUI.Layout.ManuallySerializeButton(targets);
|
||||||
@ -186,21 +209,32 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
|
|
||||||
SerializedProperty iterator = serializedObject.GetIterator();
|
SerializedProperty iterator = serializedObject.GetIterator();
|
||||||
iterator.NextVisible(true);
|
iterator.NextVisible(true);
|
||||||
|
using (EcsGUI.Disable)
|
||||||
|
{
|
||||||
|
EditorGUILayout.PropertyField(iterator, true);
|
||||||
|
}
|
||||||
while (iterator.NextVisible(false))
|
while (iterator.NextVisible(false))
|
||||||
{
|
{
|
||||||
if (_componentsProp != null && iterator.name == _componentsProp.name)
|
if ((_componentTemplatesProp != null && iterator.name == _componentTemplatesProp.name) ||
|
||||||
|
(_templatesProp != null && iterator.name == _templatesProp.name))
|
||||||
{
|
{
|
||||||
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetTransperentBlackBackgrounStyle()))
|
|
||||||
{
|
|
||||||
DrawTop(_componentsProp);
|
|
||||||
_reorderableComponentsList.DoLayoutList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EditorGUILayout.PropertyField(iterator, true);
|
EditorGUILayout.PropertyField(iterator, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_templatesProp != null)
|
||||||
|
{
|
||||||
|
EditorGUILayout.PropertyField(_templatesProp, true);
|
||||||
|
}
|
||||||
|
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetTransperentBlackBackgrounStyle()))
|
||||||
|
{
|
||||||
|
DrawTop(_componentTemplatesProp);
|
||||||
|
_reorderableComponentsList.DoLayoutList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private void DrawTop(SerializedProperty componentsProp)
|
private void DrawTop(SerializedProperty componentsProp)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
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 System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -14,7 +15,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public interface IComponentTemplate : ITemplateNode
|
public interface IComponentTemplate : ITemplateNode
|
||||||
{
|
{
|
||||||
#region Properties
|
#region Properties
|
||||||
Type Type { get; }
|
Type ComponentType { get; }
|
||||||
bool IsUnique { get; }
|
bool IsUnique { get; }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -33,16 +34,11 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public abstract class ComponentTemplateBase : IComponentTemplate, ITypeMeta
|
[MetaProxy(typeof(ComponentTemplateMetaProxy))]
|
||||||
|
public abstract class ComponentTemplateBase : IComponentTemplate
|
||||||
{
|
{
|
||||||
#region Properties
|
#region Properties
|
||||||
public abstract Type Type { get; }
|
public abstract Type ComponentType { get; }
|
||||||
public virtual ITypeMeta BaseMeta { get { return null; } }
|
|
||||||
public virtual string Name { get { return string.Empty; } }
|
|
||||||
public virtual MetaColor Color { get { return new MetaColor(MetaColor.Black); } }
|
|
||||||
public virtual MetaGroup Group { get { return MetaGroup.Empty; } }
|
|
||||||
public virtual MetaDescription Description { get { return MetaDescription.Empty; } }
|
|
||||||
public virtual IReadOnlyList<string> Tags { get { return Array.Empty<string>(); } }
|
|
||||||
public virtual bool IsUnique { get { return true; } }
|
public virtual bool IsUnique { get { return true; } }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -54,67 +50,136 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
public abstract void Apply(short worldID, int entityID);
|
public abstract void Apply(short worldID, int entityID);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
protected class ComponentTemplateMetaProxy : MetaProxy
|
||||||
|
{
|
||||||
|
protected static TypeMeta Meta;
|
||||||
|
public override string Name { get { return Meta?.Name; } }
|
||||||
|
public override MetaColor? Color { get { return Meta?.Color; } }
|
||||||
|
public override MetaGroup Group { get { return Meta?.Group; } }
|
||||||
|
public override MetaDescription Description { get { return Meta?.Description; } }
|
||||||
|
public override IEnumerable<string> Tags { get { return Meta?.Tags; } }
|
||||||
|
public ComponentTemplateMetaProxy(Type type) : base(type)
|
||||||
|
{
|
||||||
|
if (type.IsGenericType && type.ContainsGenericParameters == false)
|
||||||
|
{
|
||||||
|
var g = type.GetGenericArguments();
|
||||||
|
if (g.Length == 1)
|
||||||
|
{
|
||||||
|
Meta = g[0].GetMeta();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
[Serializable]
|
[Serializable]
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public abstract class ComponentTemplateBase<T> : ComponentTemplateBase, ICloneable
|
public abstract class ComponentTemplateBase<T> : ComponentTemplateBase, ICloneable
|
||||||
where T : struct
|
|
||||||
{
|
{
|
||||||
protected static readonly TypeMeta Meta = EcsDebugUtility.GetTypeMeta<T>();
|
protected static readonly TypeMeta Meta = EcsDebugUtility.GetTypeMeta<T>();
|
||||||
|
|
||||||
private static bool _defaultValueTypeInit = false;
|
private static bool _defaultValueInit = false;
|
||||||
private static T _defaultValueType;
|
private static bool _hasDefaultValue = false;
|
||||||
protected static T DefaultValueType
|
private static T _defaultValue;
|
||||||
|
private static ICloneable _defaultValueCloneable;
|
||||||
|
private static CloneMethod _defaultValueCloneMethod;
|
||||||
|
private enum CloneMethod
|
||||||
|
{
|
||||||
|
Set,
|
||||||
|
Clone_Reflection,
|
||||||
|
ICloneable,
|
||||||
|
}
|
||||||
|
protected static void InitStatic()
|
||||||
|
{
|
||||||
|
if (_defaultValueInit == false)
|
||||||
|
{
|
||||||
|
_hasDefaultValue = false;
|
||||||
|
Type type = typeof(T);
|
||||||
|
FieldInfo field;
|
||||||
|
field = type.GetField("Default", BindingFlags.Static | BindingFlags.Public);
|
||||||
|
if (field != null && field.FieldType == type)
|
||||||
|
{
|
||||||
|
_defaultValue = (T)field.GetValue(null);
|
||||||
|
_hasDefaultValue = true;
|
||||||
|
}
|
||||||
|
if(_hasDefaultValue == false)
|
||||||
|
{
|
||||||
|
field = type.GetField("Empty", BindingFlags.Static | BindingFlags.Public);
|
||||||
|
if (field != null && field.FieldType == type)
|
||||||
|
{
|
||||||
|
_defaultValue = (T)field.GetValue(null);
|
||||||
|
_hasDefaultValue = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_defaultValue == null)
|
||||||
|
{
|
||||||
|
_hasDefaultValue = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_hasDefaultValue)
|
||||||
|
{
|
||||||
|
_defaultValueCloneable = _defaultValue as ICloneable;
|
||||||
|
_defaultValueCloneMethod = CloneMethod.Set;
|
||||||
|
|
||||||
|
if (type.IsValueType == false)
|
||||||
|
{
|
||||||
|
_defaultValueCloneMethod = CloneMethod.Clone_Reflection;
|
||||||
|
}
|
||||||
|
if (_defaultValueCloneable != null)
|
||||||
|
{
|
||||||
|
_defaultValueCloneMethod = CloneMethod.ICloneable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_defaultValueInit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected virtual T DefaultComponent
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_defaultValueTypeInit == false)
|
if (_hasDefaultValue)
|
||||||
{
|
{
|
||||||
Type type = typeof(T);
|
return CloneComponent(_defaultValue);
|
||||||
if (type.IsValueType)
|
|
||||||
{
|
|
||||||
FieldInfo field;
|
|
||||||
field = type.GetField("Default", BindingFlags.Static | BindingFlags.Public);
|
|
||||||
if (field != null && field.FieldType == type)
|
|
||||||
{
|
|
||||||
_defaultValueType = (T)field.GetValue(null);
|
|
||||||
}
|
|
||||||
field = type.GetField("Empty", BindingFlags.Static | BindingFlags.Public);
|
|
||||||
if (field != null && field.FieldType == type)
|
|
||||||
{
|
|
||||||
_defaultValueType = (T)field.GetValue(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_defaultValueTypeInit = true;
|
|
||||||
}
|
}
|
||||||
return _defaultValueType;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
protected T component = DefaultValueType;
|
protected T component;
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
[HideInInspector]
|
[HideInInspector]
|
||||||
private byte _offset; // Avoids the error "Cannot get managed reference index with out bounds offset"
|
private byte _offset; // Avoids the error "Cannot get managed reference index with out bounds offset"
|
||||||
|
|
||||||
#region Properties
|
public ComponentTemplateBase()
|
||||||
public sealed override ITypeMeta BaseMeta { get { return Meta; } }
|
{
|
||||||
public sealed override Type Type { get { return typeof(T); } }
|
InitStatic();
|
||||||
public override string Name { get { return Meta.Name; } }
|
component = DefaultComponent;
|
||||||
public override MetaColor Color { get { return Meta.Color; } }
|
}
|
||||||
public override MetaGroup Group { get { return Meta.Group; } }
|
|
||||||
public override MetaDescription Description { get { return Meta.Description; } }
|
public sealed override Type ComponentType { get { return typeof(T); } }
|
||||||
public override IReadOnlyList<string> Tags { get { return Meta.Tags; } }
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
public sealed override object GetRaw() { return component; }
|
public sealed override object GetRaw() { return component; }
|
||||||
public sealed override void SetRaw(object raw) { component = (T)raw; }
|
public sealed override void SetRaw(object raw) { component = (T)raw; }
|
||||||
protected virtual T CloneComponent() { return component; }
|
protected virtual T CloneComponent(T component)
|
||||||
|
{
|
||||||
|
switch (_defaultValueCloneMethod)
|
||||||
|
{
|
||||||
|
case CloneMethod.Set:
|
||||||
|
return component;
|
||||||
|
case CloneMethod.Clone_Reflection:
|
||||||
|
return (T)component.Clone_Reflection();
|
||||||
|
case CloneMethod.ICloneable:
|
||||||
|
return (T)_defaultValueCloneable.Clone();
|
||||||
|
}
|
||||||
|
return default;
|
||||||
|
}
|
||||||
object ICloneable.Clone()
|
object ICloneable.Clone()
|
||||||
{
|
{
|
||||||
ComponentTemplateBase<T> templateClone = (ComponentTemplateBase<T>)MemberwiseClone();
|
ComponentTemplateBase<T> templateClone = (ComponentTemplateBase<T>)MemberwiseClone();
|
||||||
templateClone.component = CloneComponent();
|
templateClone.component = CloneComponent(component);
|
||||||
return templateClone;
|
return templateClone;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -175,7 +240,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
{
|
{
|
||||||
if (_meta == null)
|
if (_meta == null)
|
||||||
{
|
{
|
||||||
_meta = ComponentType.GetMeta();
|
{
|
||||||
|
_meta = ComponentType.GetMeta();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return _meta;
|
return _meta;
|
||||||
}
|
}
|
||||||
@ -194,7 +261,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
field = Type.GetField("Default", BindingFlags.Static | BindingFlags.Public);
|
field = Type.GetField("Default", BindingFlags.Static | BindingFlags.Public);
|
||||||
if (field != null && field.FieldType == Type)
|
if (field != null && field.FieldType == Type)
|
||||||
{
|
{
|
||||||
_defaultValueDummy = field.GetValue(null);
|
_defaultValueDummy = field.GetValue(null).Clone_Reflection();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_defaultValueDummy == null)
|
if(_defaultValueDummy == null)
|
||||||
@ -202,7 +269,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
field = Type.GetField("Empty", BindingFlags.Static | BindingFlags.Public);
|
field = Type.GetField("Empty", BindingFlags.Static | BindingFlags.Public);
|
||||||
if (field != null && field.FieldType == Type)
|
if (field != null && field.FieldType == Type)
|
||||||
{
|
{
|
||||||
_defaultValueDummy = field.GetValue(null);
|
_defaultValueDummy = field.GetValue(null).Clone_Reflection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,15 +283,17 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
Type = type;
|
Type = type;
|
||||||
|
|
||||||
IsUnique = false;
|
IsUnique = false;
|
||||||
if (typeof(IComponentTemplate).IsAssignableFrom(type))
|
if (type.GetInterfaces().Contains(typeof(ITypeMeta)))
|
||||||
|
{
|
||||||
|
var metaOverride = (ITypeMeta)Activator.CreateInstance(type);
|
||||||
|
_meta = metaOverride;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.GetInterfaces().Contains(typeof(IComponentTemplate)))
|
||||||
{
|
{
|
||||||
var ct = (IComponentTemplate)Activator.CreateInstance(type);
|
var ct = (IComponentTemplate)Activator.CreateInstance(type);
|
||||||
IsUnique = ct.IsUnique;
|
IsUnique = ct.IsUnique;
|
||||||
ComponentType = ct.Type;
|
ComponentType = ct.ComponentType;
|
||||||
if (ct is ITypeMeta metaOverride)
|
|
||||||
{
|
|
||||||
_meta = metaOverride;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
#endif
|
#endif
|
||||||
using DCFApixels.DragonECS.Unity;
|
using DCFApixels.DragonECS.Unity;
|
||||||
|
using DCFApixels.DragonECS.Unity.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -24,8 +25,10 @@ namespace DCFApixels.DragonECS
|
|||||||
public class MonoEntityTemplate : MonoEntityTemplateBase, ITemplateNode
|
public class MonoEntityTemplate : MonoEntityTemplateBase, ITemplateNode
|
||||||
{
|
{
|
||||||
[SerializeReference]
|
[SerializeReference]
|
||||||
[ReferenceButton(true, typeof(ITemplateNode))]
|
[ReferenceDropDown(true)]
|
||||||
|
[TypeMetaBlock]
|
||||||
[FormerlySerializedAs("_components")]
|
[FormerlySerializedAs("_components")]
|
||||||
|
[ArrayElement]
|
||||||
private ITemplateNode[] _componentTemplates;
|
private ITemplateNode[] _componentTemplates;
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|||||||
@ -25,7 +25,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[SerializeField]
|
[SerializeField]
|
||||||
private ScriptableEntityTemplateBase[] _templates;
|
private ScriptableEntityTemplateBase[] _templates;
|
||||||
[SerializeReference]
|
[SerializeReference]
|
||||||
[ReferenceButton(true, typeof(ITemplateNode))]
|
[ReferenceDropDown(true)]
|
||||||
[FormerlySerializedAs("_components")]
|
[FormerlySerializedAs("_components")]
|
||||||
private ITemplateNode[] _componentTemplates;
|
private ITemplateNode[] _componentTemplates;
|
||||||
|
|
||||||
|
|||||||
@ -119,7 +119,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
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.DrawTypeMetaElementBlock(ref rect, _recordsProp, index, prop, meta))
|
if (EcsGUI.DrawTypeMetaElementBlock(ref rect, _recordsProp, index, prop, meta).skip)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
protected override float GetCustomHeight(SerializedProperty property, GUIContent label)
|
||||||
{
|
{
|
||||||
float result = 0f;
|
float result = 0f;
|
||||||
if (IsArrayElement == false)
|
if (IsArrayElement == false)
|
||||||
|
|||||||
@ -103,8 +103,8 @@ namespace DCFApixels.DragonECS.Unity
|
|||||||
public struct Record
|
public struct Record
|
||||||
{
|
{
|
||||||
[SerializeReference]
|
[SerializeReference]
|
||||||
[ReferenceButton(true, typeof(IEcsModule), typeof(IEcsProcess))]
|
[ReferenceDropDown(true, typeof(IEcsModule), typeof(IEcsProcess))]
|
||||||
[ReferenceButtonWithOut(typeof(IEcsRunner))]
|
[ReferenceDropDownWithout(typeof(IEcsRunner))]
|
||||||
[ArrayElement]
|
[ArrayElement]
|
||||||
public object target;// нельзя менять поярдок полей, иначе это поломает отрисовку в инспекторе изза применения property.Next(bool);
|
public object target;// нельзя менять поярдок полей, иначе это поломает отрисовку в инспекторе изза применения property.Next(bool);
|
||||||
public AddParams parameters;
|
public AddParams parameters;
|
||||||
|
|||||||
@ -2,35 +2,637 @@
|
|||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
#endif
|
#endif
|
||||||
using DCFApixels.DragonECS.Unity.Editors;
|
using DCFApixels.DragonECS.Unity.Editors;
|
||||||
|
using DCFApixels.DragonECS.Unity.Internal;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
public sealed class ReferenceButtonAttribute : PropertyAttribute, IReferenceButtonAttribute
|
internal interface IReferenceDropDownAttribute
|
||||||
{
|
{
|
||||||
public readonly Type[] PredicateTypes;
|
Type[] PredicateTypes { get; }
|
||||||
|
bool IsHideButtonIfNotNull { get; }
|
||||||
|
}
|
||||||
|
//public sealed class ReferenceButtonAttribute : PropertyAttribute, IReferenceDropDownAttribute
|
||||||
|
//{
|
||||||
|
// public readonly Type[] PredicateTypes;
|
||||||
|
// public readonly bool IsHideButtonIfNotNull;
|
||||||
|
// Type[] IReferenceDropDownAttribute.PredicateTypes { get { return PredicateTypes; } }
|
||||||
|
// bool IReferenceDropDownAttribute.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)
|
||||||
|
// {
|
||||||
|
// IsHideButtonIfNotNull = isHideButtonIfNotNull;
|
||||||
|
// PredicateTypes = predicateTypes;
|
||||||
|
// 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));
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
public sealed class ReferenceDropDownAttribute : PropertyAttribute, IReferenceDropDownAttribute
|
||||||
|
{
|
||||||
|
public readonly Type[] AllowTypes;
|
||||||
public readonly bool IsHideButtonIfNotNull;
|
public readonly bool IsHideButtonIfNotNull;
|
||||||
Type[] IReferenceButtonAttribute.PredicateTypes { get { return PredicateTypes; } }
|
Type[] IReferenceDropDownAttribute.PredicateTypes { get { return AllowTypes; } }
|
||||||
bool IReferenceButtonAttribute.IsHideButtonIfNotNull { get { return IsHideButtonIfNotNull; } }
|
bool IReferenceDropDownAttribute.IsHideButtonIfNotNull { get { return IsHideButtonIfNotNull; } }
|
||||||
public ReferenceButtonAttribute(bool isHideButtonIfNotNull = false) : this(isHideButtonIfNotNull, Array.Empty<Type>()) { }
|
public ReferenceDropDownAttribute(bool isHideButtonIfNotNull = false) : this(isHideButtonIfNotNull, Array.Empty<Type>()) { }
|
||||||
public ReferenceButtonAttribute(params Type[] predicateTypes) : this(false, predicateTypes) { }
|
public ReferenceDropDownAttribute(params Type[] predicateTypes) : this(false, predicateTypes) { }
|
||||||
public ReferenceButtonAttribute(bool isHideButtonIfNotNull, params Type[] predicateTypes)
|
public ReferenceDropDownAttribute(bool isHideButtonIfNotNull, params Type[] predicateTypes)
|
||||||
{
|
{
|
||||||
IsHideButtonIfNotNull = isHideButtonIfNotNull;
|
IsHideButtonIfNotNull = isHideButtonIfNotNull;
|
||||||
PredicateTypes = predicateTypes;
|
AllowTypes = predicateTypes;
|
||||||
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 sealed class ReferenceDropDownWithoutAttribute : Attribute
|
||||||
{
|
{
|
||||||
public readonly Type[] PredicateTypes;
|
public readonly Type[] PredicateTypes;
|
||||||
[Obsolete("With empty parameters, this attribute makes no sense.", true)]
|
[Obsolete("With empty parameters, this attribute makes no sense.", true)]
|
||||||
public ReferenceButtonWithOutAttribute() : this(Array.Empty<Type>()) { }
|
public ReferenceDropDownWithoutAttribute() : this(Array.Empty<Type>()) { }
|
||||||
public ReferenceButtonWithOutAttribute(params Type[] predicateTypes)
|
public ReferenceDropDownWithoutAttribute(params Type[] predicateTypes)
|
||||||
{
|
{
|
||||||
PredicateTypes = predicateTypes;
|
PredicateTypes = predicateTypes;
|
||||||
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 TypeMetaBlockAttribute : PropertyAttribute { }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
namespace DCFApixels.DragonECS.Unity.Editors
|
||||||
|
{
|
||||||
|
[CustomPropertyDrawer(typeof(ReferenceDropDownAttribute), true)]
|
||||||
|
[CustomPropertyDrawer(typeof(TypeMetaBlockAttribute), true)]
|
||||||
|
internal class EcsDragonFieldDrawer : ExtendedPropertyDrawer
|
||||||
|
{
|
||||||
|
private const float DamagedComponentHeight = 18f * 2f;
|
||||||
|
private DragonFieldDropDown _dropDown;
|
||||||
|
private PredicateTypesKey? _predicateOverride;
|
||||||
|
|
||||||
|
private ReferenceDropDownAttribute ReferenceDropDownAttribute;
|
||||||
|
private ReferenceDropDownWithoutAttribute ReferenceDropDownWithoutAttribute;
|
||||||
|
private TypeMetaBlockAttribute TypeMetaBlockAttribute;
|
||||||
|
|
||||||
|
private bool _isInit = false;
|
||||||
|
private bool _hasSerializableData;
|
||||||
|
|
||||||
|
[ThreadStatic]
|
||||||
|
private static int _skips = 0;
|
||||||
|
private bool CheckSkip()
|
||||||
|
{
|
||||||
|
if (_skips > 0)
|
||||||
|
{
|
||||||
|
_skips--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
|
if (ReferenceDropDownAttribute != null) { count++; }
|
||||||
|
if (TypeMetaBlockAttribute != null) { count++; }
|
||||||
|
|
||||||
|
_skips = count - 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
private float Padding => Spacing;
|
||||||
|
protected override bool IsInit => _isInit;
|
||||||
|
private bool IsDrawDropDown => ReferenceDropDownAttribute != null;
|
||||||
|
private bool IsDrawMetaBlock => TypeMetaBlockAttribute != null;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public EcsDragonFieldDrawer() { }
|
||||||
|
public EcsDragonFieldDrawer(PredicateTypesKey key)
|
||||||
|
{
|
||||||
|
_predicateOverride = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Init
|
||||||
|
protected override void OnInit(SerializedProperty property)
|
||||||
|
{
|
||||||
|
PredicateTypesKey key;
|
||||||
|
_hasSerializableData = true;
|
||||||
|
|
||||||
|
if (fieldInfo != null)
|
||||||
|
{
|
||||||
|
if (property.propertyType == SerializedPropertyType.ManagedReference)
|
||||||
|
{
|
||||||
|
_hasSerializableData = property.HasSerializableData();
|
||||||
|
}
|
||||||
|
foreach (var atrRaw in Attributes)
|
||||||
|
{
|
||||||
|
switch (atrRaw)
|
||||||
|
{
|
||||||
|
case ReferenceDropDownAttribute atr: ReferenceDropDownAttribute = atr; break;
|
||||||
|
case ReferenceDropDownWithoutAttribute atr: ReferenceDropDownWithoutAttribute = atr; break;
|
||||||
|
case TypeMetaBlockAttribute atr: TypeMetaBlockAttribute = atr; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_predicateOverride == null && fieldInfo != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
var targetType = fieldInfo.FieldType;
|
||||||
|
if (ReferenceDropDownAttribute != null)
|
||||||
|
{
|
||||||
|
Type[] withOutTypes = ReferenceDropDownWithoutAttribute != null ? ReferenceDropDownWithoutAttribute.PredicateTypes : Type.EmptyTypes;
|
||||||
|
|
||||||
|
bool allAssignableTypes = targetType != typeof(ITemplateNode);
|
||||||
|
|
||||||
|
var types = ReferenceDropDownAttribute.AllowTypes;
|
||||||
|
if (types == null || types.Length == 0)
|
||||||
|
{
|
||||||
|
if (allAssignableTypes)
|
||||||
|
{
|
||||||
|
types = new Type[] { targetType };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
types = new Type[] { typeof(IComponentTemplate), typeof(IEcsComponentMember) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
key = new PredicateTypesKey(targetType, types, withOutTypes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
key = new PredicateTypesKey(targetType, new Type[] { targetType });
|
||||||
|
}
|
||||||
|
_predicateOverride = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsDrawDropDown)
|
||||||
|
{
|
||||||
|
_dropDown = DragonFieldDropDown.Get(_predicateOverride.Value);
|
||||||
|
_dropDown.OnSelected += SelectComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isInit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ThreadStatic]
|
||||||
|
private static SerializedProperty currentProperty;
|
||||||
|
private static void SelectComponent(DragonFieldDropDown.Item item)
|
||||||
|
{
|
||||||
|
//EcsGUI.Changed = true;
|
||||||
|
if (item.Obj == null)
|
||||||
|
{
|
||||||
|
currentProperty.managedReferenceValue = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentProperty.managedReferenceValue = item.Obj.CreateInstance();
|
||||||
|
currentProperty.isExpanded = false;
|
||||||
|
}
|
||||||
|
currentProperty.serializedObject.ApplyModifiedProperties();
|
||||||
|
EcsGUI.DelayedChanged = true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
protected override float GetCustomHeight(SerializedProperty property, GUIContent label)
|
||||||
|
{
|
||||||
|
if (CheckSkip()) { return EditorGUI.GetPropertyHeight(property, label); }
|
||||||
|
bool isSerializeReference = property.propertyType == SerializedPropertyType.ManagedReference;
|
||||||
|
|
||||||
|
SerializedProperty componentProp = property;
|
||||||
|
if (isSerializeReference)
|
||||||
|
{
|
||||||
|
var instance = property.managedReferenceValue;
|
||||||
|
if (instance == null)
|
||||||
|
{
|
||||||
|
float result = EditorGUIUtility.singleLineHeight;
|
||||||
|
if (IsDrawMetaBlock)
|
||||||
|
{
|
||||||
|
result += Padding * 2f;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (instance is ComponentTemplateBase customTemplate)
|
||||||
|
{
|
||||||
|
componentProp = property.FindPropertyRelative("component");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
componentProp = property;
|
||||||
|
}
|
||||||
|
if (componentProp == null)
|
||||||
|
{
|
||||||
|
return DamagedComponentHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
float result = EditorGUIUtility.singleLineHeight;
|
||||||
|
if (_hasSerializableData)
|
||||||
|
{
|
||||||
|
result = EditorGUI.GetPropertyHeight(componentProp, label);
|
||||||
|
}
|
||||||
|
if (IsDrawMetaBlock)
|
||||||
|
{
|
||||||
|
result += Padding * 4f;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
|
||||||
|
{
|
||||||
|
Draw(position, property, property, label);
|
||||||
|
}
|
||||||
|
public void Draw(Rect rect, SerializedProperty rootProperty, SerializedProperty property, GUIContent label)
|
||||||
|
{
|
||||||
|
if (CheckSkip()) { EditorGUI.PropertyField(rect, property, label, true); return; }
|
||||||
|
bool isSerializeReference = property.propertyType == SerializedPropertyType.ManagedReference;
|
||||||
|
var e = Event.current;
|
||||||
|
|
||||||
|
ITypeMeta meta = null;
|
||||||
|
SerializedProperty componentProp = property;
|
||||||
|
bool isDrawProperty = true;
|
||||||
|
bool isDrawDropDown = IsDrawDropDown && isSerializeReference;
|
||||||
|
|
||||||
|
if (isSerializeReference)
|
||||||
|
{
|
||||||
|
var template = property.managedReferenceValue;
|
||||||
|
|
||||||
|
if (template is ComponentTemplateBase)
|
||||||
|
{
|
||||||
|
componentProp = property.FindPropertyRelative("component");
|
||||||
|
}
|
||||||
|
if (componentProp == null)
|
||||||
|
{
|
||||||
|
DrawDamagedComponent(rect, "Damaged component template.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (template == null)
|
||||||
|
{
|
||||||
|
isDrawProperty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//meta = template as ITypeMeta;
|
||||||
|
if (meta == null)
|
||||||
|
{
|
||||||
|
if (template is IComponentTemplate componentTemplate)
|
||||||
|
{
|
||||||
|
meta = componentTemplate.ComponentType.GetMeta();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta = template.GetMeta();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDrawDropDown && template != null && ReferenceDropDownAttribute.IsHideButtonIfNotNull)
|
||||||
|
{
|
||||||
|
isDrawDropDown = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta = fieldInfo.FieldType.GetMeta();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float selectionButtonRightOffset = 0f;
|
||||||
|
|
||||||
|
if (isDrawProperty)
|
||||||
|
{
|
||||||
|
if (IsDrawMetaBlock)
|
||||||
|
{
|
||||||
|
ref var r = ref rect;
|
||||||
|
var (skip, optionsWidth) = EcsGUI.DrawTypeMetaBlock(ref r, rootProperty, meta);
|
||||||
|
selectionButtonRightOffset = optionsWidth;
|
||||||
|
if (skip)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (isDrawProperty)
|
||||||
|
{
|
||||||
|
if (IsArrayElement)
|
||||||
|
{
|
||||||
|
label.text = meta.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fieldRect = rect;
|
||||||
|
|
||||||
|
if (property != componentProp &&
|
||||||
|
componentProp.propertyType != SerializedPropertyType.Generic &&
|
||||||
|
componentProp.propertyType != SerializedPropertyType.ManagedReference)
|
||||||
|
{
|
||||||
|
fieldRect.xMax -= selectionButtonRightOffset;
|
||||||
|
isDrawDropDown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var et = e.type;
|
||||||
|
|
||||||
|
if (_hasSerializableData)
|
||||||
|
{
|
||||||
|
EditorGUI.PropertyField(fieldRect, componentProp, label, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorGUI.LabelField(rect, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
var labelRect = rect;
|
||||||
|
labelRect.width = EditorGUIUtility.labelWidth;
|
||||||
|
labelRect.xMin -= 20f;
|
||||||
|
if (e.type == EventType.Used && EcsGUI.HitTest(labelRect, e) == false)
|
||||||
|
{
|
||||||
|
e.type = et;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorGUI.LabelField(rect, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (isDrawDropDown)
|
||||||
|
{
|
||||||
|
rect.xMax -= selectionButtonRightOffset;
|
||||||
|
DrawSelectionDropDown(rect, property, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void DrawSelectionDropDown(Rect rect, SerializedProperty property, GUIContent label)
|
||||||
|
{
|
||||||
|
if (rect.width < 0) { return; }
|
||||||
|
|
||||||
|
var position = IsArrayElement ? rect : rect.AddPadding(EditorGUIUtility.labelWidth, 0f, 0f, 0f);
|
||||||
|
position.height = OneLineHeight;
|
||||||
|
|
||||||
|
bool isHideButtonIfNotNull = ReferenceDropDownAttribute.IsHideButtonIfNotNull;
|
||||||
|
object obj = property.hasMultipleDifferentValues ? null : property.managedReferenceValue;
|
||||||
|
|
||||||
|
string text = obj == null ? "Select..." : obj.GetMeta().Name;
|
||||||
|
if (!isHideButtonIfNotNull || obj == null)
|
||||||
|
{
|
||||||
|
if (GUI.Button(position, text, EditorStyles.layerMaskField))
|
||||||
|
{
|
||||||
|
currentProperty = property;
|
||||||
|
_dropDown.OpenForField(position, property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GUI.Label(position, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void DrawDamagedComponent(Rect position, string message)
|
||||||
|
{
|
||||||
|
EditorGUI.HelpBox(position, message, MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal class DragonFieldDropDown : MetaObjectsDropDown<DragonFieldCahce>
|
||||||
|
{
|
||||||
|
private DragonFieldDropDown() { }
|
||||||
|
|
||||||
|
private bool _isCheckUnique;
|
||||||
|
private SerializedProperty _arrayProperty;
|
||||||
|
private SerializedProperty _fieldProperty;
|
||||||
|
|
||||||
|
public static Dictionary<PredicateTypesKey, DragonFieldDropDown> _dropDownsCache = new Dictionary<PredicateTypesKey, DragonFieldDropDown>(32);
|
||||||
|
public static DragonFieldDropDown Get(PredicateTypesKey key)
|
||||||
|
{
|
||||||
|
if (_dropDownsCache.TryGetValue(key, out var result) == false)
|
||||||
|
{
|
||||||
|
result = new DragonFieldDropDown();
|
||||||
|
IEnumerable<(DragonFieldCahce template, ITypeMeta meta)> itemMetaPairs = DragonFieldCahce.All.ToArray()
|
||||||
|
.Where(o =>
|
||||||
|
{
|
||||||
|
return key.Check(o.Type);
|
||||||
|
|
||||||
|
})
|
||||||
|
.Select(o =>
|
||||||
|
{
|
||||||
|
return (o, (ITypeMeta)o.Meta);
|
||||||
|
});
|
||||||
|
|
||||||
|
//TODO оптимизировать или вырезать
|
||||||
|
itemMetaPairs = itemMetaPairs.OrderBy(o => o.meta.Group.Name);
|
||||||
|
result.Setup(itemMetaPairs);
|
||||||
|
_dropDownsCache[key] = result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (item.Obj == null)
|
||||||
|
{
|
||||||
|
_fieldProperty.managedReferenceValue = null;
|
||||||
|
_fieldProperty.serializedObject.ApplyModifiedProperties();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type componentType = item.Obj.GetType();
|
||||||
|
var data = item.Obj;
|
||||||
|
|
||||||
|
if (_arrayProperty != null && data != null)
|
||||||
|
{
|
||||||
|
int index = _arrayProperty.arraySize;
|
||||||
|
if (_isCheckUnique)
|
||||||
|
{
|
||||||
|
if (data.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 = data.CreateInstance();
|
||||||
|
_fieldProperty.serializedObject.ApplyModifiedProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Event.current.Use();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal class DragonFieldCahce
|
||||||
|
{
|
||||||
|
private static DragonFieldCahce[] _all;
|
||||||
|
internal static IReadOnlyList<DragonFieldCahce> All
|
||||||
|
{
|
||||||
|
get { return _all; }
|
||||||
|
}
|
||||||
|
static DragonFieldCahce() { StaticInit(); }
|
||||||
|
|
||||||
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||||
|
private static void StaticInit()
|
||||||
|
{
|
||||||
|
List<DragonFieldCahce> list = new List<DragonFieldCahce>(UnityEditorUtility._serializableTypes.Length);
|
||||||
|
foreach (var type in UnityEditorUtility._serializableTypes)
|
||||||
|
{
|
||||||
|
DragonFieldCahce element = new DragonFieldCahce(type);
|
||||||
|
list.Add(element);
|
||||||
|
}
|
||||||
|
_all = list.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public readonly Type Type;
|
||||||
|
public readonly Type ComponentType;
|
||||||
|
public readonly bool IsUnique;
|
||||||
|
private TypeMeta _meta;
|
||||||
|
public TypeMeta Meta
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_meta == null)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
_meta = Type.GetMeta();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _meta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private bool _defaultValueTypeInit = false;
|
||||||
|
private object _defaultValueDummy;
|
||||||
|
public object DefaultValue
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_defaultValueTypeInit == false)
|
||||||
|
{
|
||||||
|
if (Type.IsValueType)
|
||||||
|
{
|
||||||
|
FieldInfo field;
|
||||||
|
field = Type.GetField("Default", BindingFlags.Static | BindingFlags.Public);
|
||||||
|
if (field != null && field.FieldType == Type)
|
||||||
|
{
|
||||||
|
_defaultValueDummy = field.GetValue(null).Clone_Reflection();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_defaultValueDummy == null)
|
||||||
|
{
|
||||||
|
field = Type.GetField("Empty", BindingFlags.Static | BindingFlags.Public);
|
||||||
|
if (field != null && field.FieldType == Type)
|
||||||
|
{
|
||||||
|
_defaultValueDummy = field.GetValue(null).Clone_Reflection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_defaultValueTypeInit = true;
|
||||||
|
}
|
||||||
|
return _defaultValueDummy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public DragonFieldCahce(Type type)
|
||||||
|
{
|
||||||
|
Type = type;
|
||||||
|
IsUnique = false;
|
||||||
|
|
||||||
|
if (type.GetInterfaces().Contains(typeof(IComponentTemplate)))
|
||||||
|
{
|
||||||
|
var ct = (IComponentTemplate)Activator.CreateInstance(type);
|
||||||
|
IsUnique = ct.IsUnique;
|
||||||
|
ComponentType = ct.ComponentType;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ComponentType = Type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public object CreateInstance()
|
||||||
|
{
|
||||||
|
if (DefaultValue != null)
|
||||||
|
{
|
||||||
|
return DefaultValue.Clone_Reflection();
|
||||||
|
}
|
||||||
|
return Activator.CreateInstance(Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Type.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Loading…
Reference in New Issue
Block a user