update editor utils, update EcsPipelineTemplateSO

This commit is contained in:
Mikhail 2024-09-14 18:33:54 +08:00
parent a43d1df7aa
commit 2229ee0f5d
10 changed files with 847 additions and 99 deletions

View File

@ -11,6 +11,7 @@ namespace DCFApixels.DragonECS
public class UnityDebugService : DebugService
{
private ProfilerMarker[] _profilerMarkers = new ProfilerMarker[64];
static UnityDebugService()
{
Activate();
@ -28,22 +29,30 @@ namespace DCFApixels.DragonECS
return;
}
string msg = AutoConvertObjectToString(v);
bool hasTag = string.IsNullOrEmpty(tag) == false;
if (hasTag)
{
log = $"[{tag}] {v}";
string taglower = tag.ToLower();
if (taglower.Contains("warning"))
switch (taglower)
{
Debug.LogWarning(log);
return;
}
if (taglower.Contains("error"))
{
Debug.LogError(log);
return;
}
case "pass":
log = $"[<color=#00ff00>{tag}</color>] {msg}";
Debug.Log(log);
break;
case "warning":
log = $"[<color=#ffff00>{tag}</color>] {msg}";
Debug.LogWarning(log);
break;
case "error":
log = $"[<color=#ff4028>{tag}</color>] {msg}";
Debug.LogError(log);
break;
default:
log = $"[{tag}] {msg}";
Debug.Log(log);
break;
}
return;
}
Debug.Log(v);

View File

@ -19,15 +19,26 @@ namespace DCFApixels.DragonECS
};
[SerializeField]
[ArrayElement]
private string[] _layers = _defaultLayers.ToArray();
[SerializeField]
private Record[] _systems;
[ArrayElement]
private Record[] _records;
public ReadOnlySpan<string> Layers
{
get { return _layers; }
}
public ReadOnlySpan<Record> Records
{
get { return _records; }
}
void IEcsModule.Import(EcsPipeline.Builder b)
{
b.Layers.MergeWith(_layers);
foreach (var s in _systems)
foreach (var s in _records)
{
if (s.target == null) { continue; }
@ -40,10 +51,10 @@ namespace DCFApixels.DragonECS
EcsPipelineTemplate result = new EcsPipelineTemplate();
result.layers = new string[_layers.Length];
Array.Copy(_layers, result.layers, _layers.Length);
result.systems = new EcsPipelineTemplate.AddCommand[_systems.Length];
result.systems = new EcsPipelineTemplate.AddCommand[_records.Length];
for (int i = 0; i < result.systems.Length; i++)
{
ref var s = ref _systems[i];
ref var s = ref _records[i];
result.systems[i] = new EcsPipelineTemplate.AddCommand(s.target, s.parameters);
}
return result;
@ -53,21 +64,23 @@ namespace DCFApixels.DragonECS
{
_layers = new string[template.layers.Length];
Array.Copy(template.layers, _layers, template.layers.Length);
_systems = new Record[template.systems.Length];
for (int i = 0; i < _systems.Length; i++)
_records = new Record[template.systems.Length];
for (int i = 0; i < _records.Length; i++)
{
ref var s = ref template.systems[i];
_systems[i] = new Record(s.target, s.parameters);
_records[i] = new Record(s.target, s.parameters);
}
}
public void Validate()
public bool Validate()
{
ValidateLayers();
ValidateSystems();
bool resutl = ValidateLayers();
resutl |= ValidateSystems();
return resutl;
}
private void ValidateLayers()
private bool ValidateLayers()
{
bool result = false;
Dictionary<string, int> builtinLayerIndexes = new Dictionary<string, int>();
foreach (var item in _defaultLayers)
{
@ -101,17 +114,22 @@ namespace DCFApixels.DragonECS
{
int i = 0;
foreach (var pair in builtinLayerIndexes.OrderBy(o => o.Value))
{
if (newLayers[pair.Value] != _defaultLayers[i])
{
newLayers[pair.Value] = _defaultLayers[i];
result = true;
}
i++;
}
}
_layers = newLayers.ToArray();
return result;
}
private void ValidateSystems()
private bool ValidateSystems()
{
return false;
}
[Serializable]

View File

@ -1,31 +1,220 @@
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomEditor(typeof(EcsPipelineTemplateSO))]
internal class EcsPipelineTemplateSOEditor : Editor
[CustomPropertyDrawer(typeof(EcsPipelineTemplateSO.Record))]
internal class EcsPipelineTemplateSORecordDrawer : ExtendedPropertyDrawer
{
public override void OnInspectorGUI()
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
{
if (IsArrayElement == false)
{
Rect foldoutRect;
(foldoutRect, position) = position.VerticalSliceTop(OneLineHeight + Spacing);
property.isExpanded = EditorGUI.Foldout(foldoutRect, property.isExpanded, label);
if (property.isExpanded == false)
{
return;
}
}
using (EcsGUI.SetIndentLevel(IsArrayElement ? EditorGUI.indentLevel : EditorGUI.indentLevel + 1))
{
Rect subPosition = position;
int depth = -1;
property.Next(true);
float height = 0f;
do
{
subPosition.y += height;
height = EditorGUI.GetPropertyHeight(property);
subPosition.height = height;
EditorGUI.PropertyField(subPosition, property, true);
} while (property.NextDepth(false, ref depth));
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
float result = 0f;
if (IsArrayElement == false)
{
result += OneLineHeight;
if (property.isExpanded == false)
{
return result;
}
}
property.Next(true);
int depth = -1;
do
{
result += EditorGUI.GetPropertyHeight(property, true);
} while (property.NextDepth(false, ref depth));
return result;
}
}
[CustomEditor(typeof(EcsPipelineTemplateSO))]
internal class EcsPipelineTemplateSOEditor : ExtendedEditor<EcsPipelineTemplateSO>
{
private SerializedProperty _layersProp;
private SerializedProperty _recordsProp;
private ReorderableList _reorderableLayersList;
private ReorderableList _reorderableRecordsList;
protected override bool IsInit
{
get => _reorderableLayersList != null && _reorderableRecordsList != null;
}
protected override void OnStaticInit() { }
protected override void OnInit()
{
_layersProp = FindProperty("_layers");
_recordsProp = FindProperty("_records");
CreateLists();
}
private void CreateLists()
{
_reorderableLayersList = new ReorderableList(serializedObject, _layersProp, true, false, true, true);
_reorderableLayersList.onAddCallback += OnReorderableLayersListAdd;
_reorderableLayersList.onRemoveCallback += OnReorderableListRemove;
_reorderableLayersList.drawElementCallback += OnReorderableLayersListDrawElement;
_reorderableLayersList.onReorderCallback += OnReorderableListReorder;
_reorderableRecordsList = new ReorderableList(serializedObject, _recordsProp, true, false, true, true);
_reorderableRecordsList.onAddCallback += OnReorderableRecordsListAdd;
_reorderableRecordsList.onRemoveCallback += OnReorderableListRemove;
_reorderableRecordsList.drawElementCallback += OnReorderableRecordsListDrawElement;
_reorderableRecordsList.elementHeightCallback += OnReorderableRecordsListElementHeight;
_reorderableRecordsList.onReorderCallback += OnReorderableListReorder;
}
private void OnReorderableListReorder(ReorderableList list)
{
EcsGUI.Changed = true;
}
#region _reorderableList
private void OnReorderableListRemove(ReorderableList list)
{
if (list.selectedIndices.Count <= 0)
{
if (list.serializedProperty.arraySize > 0)
{
list.serializedProperty.DeleteArrayElementAtIndex(list.serializedProperty.arraySize - 1);
}
return;
}
for (int i = list.selectedIndices.Count - 1; i >= 0; i--)
{
list.serializedProperty.DeleteArrayElementAtIndex(list.selectedIndices[i]);
}
EcsGUI.Changed = true;
}
#endregion
#region _reorderableLayersList
private void OnReorderableLayersListDrawElement(Rect rect, int index, bool isActive, bool isFocused)
{
using (EcsGUI.CheckChanged())
{
var elementProp = _layersProp.GetArrayElementAtIndex(index);
elementProp.stringValue = EditorGUI.TextField(rect, elementProp.stringValue);
}
}
private void OnReorderableLayersListAdd(ReorderableList list)
{
list.serializedProperty.InsertArrayElementAtIndex(list.serializedProperty.arraySize);
var added = list.serializedProperty.GetArrayElementAtIndex(list.serializedProperty.arraySize - 1);
added.stringValue = $"Layer-{DateTime.Now.Ticks}";
added.serializedObject.ApplyModifiedProperties();
EcsGUI.Changed = true;
}
#endregion
#region _reorderableRecordsList
private void OnReorderableRecordsListDrawElement(Rect rect, int index, bool isActive, bool isFocused)
{
using (EcsGUI.CheckChanged())
{
var prop = _recordsProp.GetArrayElementAtIndex(index);
var mrProp = prop.FindPropertyRelative(nameof(EcsPipelineTemplateSO.Record.target));
ITypeMeta meta = mrProp.managedReferenceValue == null ? null : mrProp.managedReferenceValue.GetMeta();
EcsGUI.DrawTypeMetaBlock(ref rect, prop, meta);
EditorGUI.PropertyField(rect, prop, true);
}
}
private float OnReorderableRecordsListElementHeight(int index)
{
return EcsGUI.GetTypeMetaBlockHeight(EditorGUI.GetPropertyHeight(_recordsProp.GetArrayElementAtIndex(index)));
}
private void OnReorderableRecordsListAdd(ReorderableList list)
{
list.serializedProperty.arraySize += 1;
list.serializedProperty.GetArrayElementAtIndex(list.serializedProperty.arraySize - 1).ResetValues();
EcsGUI.Changed = true;
}
#endregion
protected override void DrawCustom()
{
using (EcsGUI.CheckChanged())
{
EditorGUI.BeginChangeCheck();
base.OnInspectorGUI();
if (EditorGUI.EndChangeCheck())
DrawLayoutNameList(_layersProp);
DrawRecordList(_recordsProp);
EcsGUI.Changed = GUILayout.Button("Validate");
if (EcsGUI.Changed)
{
serializedObject.ApplyModifiedProperties();
Validate();
Repaint();
}
if (GUILayout.Button("Validate"))
{
Validate();
}
}
private void Validate()
{
foreach (var target in targets)
foreach (var target in Targets)
{
((EcsPipelineTemplateSO)target).Validate();
target.Validate();
EditorUtility.SetDirty(target);
}
serializedObject.Update();
}
private void DrawLayoutNameList(SerializedProperty layersProp)
{
using (EcsGUI.SetVerticalLayout())
{
GUILayout.Label(UnityEditorUtility.GetLabel(layersProp.displayName), EditorStyles.boldLabel);
_reorderableLayersList.DoLayoutList();
}
}
private void DrawRecordList(SerializedProperty recordsProp)
{
using (EcsGUI.SetVerticalLayout())
{
GUILayout.Label(UnityEditorUtility.GetLabel(recordsProp.displayName), EditorStyles.boldLabel);
_reorderableRecordsList.DoLayoutList();
//EditorGUILayout.PropertyField(recordsProp, UnityEditorUtility.GetLabel(recordsProp.displayName));
}
}
}

View File

@ -247,6 +247,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
currentProperty.serializedObject.ApplyModifiedProperties();
EcsGUI.Changed = true;
}
#endregion

View File

@ -1,43 +1,84 @@
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomPropertyDrawer(typeof(AddParams))]
internal class AddParamsDrawer : PropertyDrawer
internal class AddParamsDrawer : ExtendedPropertyDrawer
{
private float SingleLineHeight => EditorGUIUtility.singleLineHeight;
private float Spacing => EditorGUIUtility.standardVerticalSpacing;
private static Dictionary<byte, string> _labelCache = new Dictionary<byte, string>()
{
{ 0, "" },
{ 1, "Layer" },
{ 2, "Order" },
{ 3, "Layer, Order" },
{ 4, "IsUnique" },
{ 5, "Layer, IsUnique" },
{ 6, "Order, IsUnique" },
{ 7, "Layer, Order, IsUnique" },
{ (byte)AddParamsFlags.NoImport | 0, "NoImport" },
{ (byte)AddParamsFlags.NoImport | 1, "NoImport, Layer" },
{ (byte)AddParamsFlags.NoImport | 2, "NoImport, Order" },
{ (byte)AddParamsFlags.NoImport | 3, "NoImport, Layer, Order" },
{ (byte)AddParamsFlags.NoImport | 4, "NoImport, IsUnique" },
{ (byte)AddParamsFlags.NoImport | 5, "NoImport, Layer, IsUnique" },
{ (byte)AddParamsFlags.NoImport | 6, "NoImport, Order, IsUnique" },
{ (byte)AddParamsFlags.NoImport | 7, "NoImport, Layer, Order, IsUnique" },
{ byte.MaxValue, "NoImport, Layer, Order, IsUnique" },
};
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return !property.isExpanded ? EditorGUIUtility.singleLineHeight + Spacing : EditorGUIUtility.singleLineHeight * 4f + Spacing * 3f;
//return !property.isExpanded ?
// EditorGUIUtility.singleLineHeight + Spacing :
// EditorGUIUtility.singleLineHeight * 5f + Spacing * 4f;
return EditorGUI.GetPropertyHeight(property);
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
{
Event e = Event.current;
var flagsProp = property.FindPropertyRelative("flags");
AddParamsFlags flags = (AddParamsFlags)flagsProp.enumValueFlag;
var (foldoutRect, contentRect) = position.VerticalSliceTop(SingleLineHeight + Spacing);
var (foldoutRect, contentRect) = position.VerticalSliceTop(OneLineHeight + Spacing);
var (fieldsRects, checkboxRects) = contentRect.HorizontalSliceRight(OneLineHeight);
var (fieldsRects, checkboxRects) = contentRect.HorizontalSliceRight(SingleLineHeight);
Rect labelField;
(foldoutRect, labelField) = foldoutRect.HorizontalSliceLeft(EditorGUIUtility.labelWidth);
using (EcsGUI.CheckChanged())
{
property.isExpanded = EditorGUI.Foldout(foldoutRect, property.isExpanded, label);
using (EcsGUI.SetAlignment(EditorStyles.miniLabel, TextAnchor.MiddleRight))
{
if (_labelCache.TryGetValue((byte)(flags.Normalize()), out string str) == false)
{
str = _labelCache[0];
}
GUI.Label(labelField, str, EditorStyles.miniLabel);
}
if (property.isExpanded == false)
{
goto exti;
}
//property.isExpanded = true;
using (EcsGUI.UpIndentLevel())
{
EditorGUI.BeginChangeCheck();
checkboxRects = checkboxRects.Move(EditorGUIUtility.standardVerticalSpacing, 0);
Rect checkboxRect = checkboxRects;
checkboxRect.height = SingleLineHeight;
checkboxRect.height = OneLineHeight;
Rect fieldRect = fieldsRects;
fieldRect.height = SingleLineHeight;
fieldRect.height = OneLineHeight;
//LayerName
property.Next(true);
@ -50,8 +91,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
EditorGUI.PropertyField(fieldRect, property, UnityEditorUtility.GetLabel(property.displayName), true);
}
checkboxRect = checkboxRect.Move(0, SingleLineHeight + Spacing);
fieldRect = fieldRect.Move(0, SingleLineHeight + Spacing);
checkboxRect = checkboxRect.Move(0, OneLineHeight + Spacing);
fieldRect = fieldRect.Move(0, OneLineHeight + Spacing);
//SortOrder
property.Next(false);
@ -64,8 +105,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
EditorGUI.PropertyField(fieldRect, property, UnityEditorUtility.GetLabel(property.displayName), true);
}
checkboxRect = checkboxRect.Move(0, SingleLineHeight + Spacing);
fieldRect = fieldRect.Move(0, SingleLineHeight + Spacing);
checkboxRect = checkboxRect.Move(0, OneLineHeight + Spacing);
fieldRect = fieldRect.Move(0, OneLineHeight + Spacing);
//IsUnique
property.Next(false);
@ -78,12 +119,25 @@ namespace DCFApixels.DragonECS.Unity.Editors
EditorGUI.PropertyField(fieldRect, property, UnityEditorUtility.GetLabel(property.displayName), true);
}
if (EditorGUI.EndChangeCheck())
if (EcsGUI.Changed)
{
flagsProp.enumValueFlag = (int)flags;
property.serializedObject.ApplyModifiedProperties();
}
checkboxRect = checkboxRect.Move(0, OneLineHeight + Spacing);
fieldRect = fieldRect.Move(0, OneLineHeight + Spacing);
fieldRect.xMax += OneLineHeight + Spacing;
property.Next(false);
EditorGUI.PropertyField(fieldRect, property, UnityEditorUtility.GetLabel(property.displayName), true);
}
exti:;
//EcsGUI.Changed = Event.current.type == EventType.MouseUp;
if (EcsGUI.Changed)
{
property.serializedObject.ApplyModifiedProperties();
}
}
}
}

View File

@ -35,6 +35,7 @@ namespace DCFApixels.DragonECS
{
#region Properties
public abstract Type Type { 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; } }
@ -63,6 +64,7 @@ namespace DCFApixels.DragonECS
private byte _offset; // Fucking Unity drove me crazy with the error "Cannot get managed reference index with out bounds offset". This workaround helps avoid that error.
#region Properties
public sealed override ITypeMeta BaseMeta { get { return Meta; } }
public sealed override Type Type { get { return typeof(T); } }
public override string Name { get { return Meta.Name; } }
public override MetaColor Color { get { return Meta.Color; } }

View File

@ -12,10 +12,65 @@ namespace DCFApixels.DragonECS.Unity.Editors
internal static class EcsGUI
{
#region Scores
public struct LabelWidthScore : IDisposable
private static int _changedCounter = 0;
private static bool _changed = false;
public static int ChangedCounter => _changedCounter;
public static bool Changed
{
get
{
_changed = _changed || GUI.changed;
return _changed;
}
set
{
_changed = _changed || GUI.changed || value;
GUI.changed = _changed;
}
}
public readonly struct CheckChangedScope : IDisposable
{
private readonly bool _value;
public CheckChangedScope(bool value)
{
_value = value;
_changedCounter++;
_changed = false;
}
public static CheckChangedScope New() { return new CheckChangedScope(Changed); }
public void Dispose()
{
Changed = Changed || _value;
_changedCounter--;
//if(_changedCounter <= 0 && Event.current.type == EventType.Repaint)
if (_changedCounter <= 0)
{
_changedCounter = 0;
_changed = false;
}
}
}
public struct VerticalLayoutScope : IDisposable
{
public static VerticalLayoutScope New() { GUILayout.BeginVertical(); return new VerticalLayoutScope(); }
public void Dispose() { GUILayout.EndVertical(); }
}
public struct HorizontalLayoutScope : IDisposable
{
public static HorizontalLayoutScope New() { GUILayout.BeginVertical(); return new HorizontalLayoutScope(); }
public void Dispose() { GUILayout.EndVertical(); }
}
public struct ScrollViewLayoutScope : IDisposable
{
public ScrollViewLayoutScope(ref Vector2 pos) { pos = GUILayout.BeginScrollView(pos); }
public void Dispose() { GUILayout.EndScrollView(); }
}
public readonly struct LabelWidthScope : IDisposable
{
private readonly float _value;
public LabelWidthScore(float value)
public LabelWidthScope(float value)
{
_value = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = value;
@ -116,13 +171,18 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
public void Dispose() { Target.fontStyle = _value; }
}
#endregion
public static CheckChangedScope CheckChanged() => CheckChangedScope.New();
public static ScrollViewLayoutScope SetScrollViewLayout(ref Vector2 pos) => new ScrollViewLayoutScope(ref pos);
public static HorizontalLayoutScope SetHorizontalLayout() => HorizontalLayoutScope.New();
public static VerticalLayoutScope SetVerticalLayout() => VerticalLayoutScope.New();
public static FontStyleScope SetFontStyle(GUIStyle target, FontStyle value) => new FontStyleScope(target, value);
public static FontStyleScope SetFontStyle(FontStyle value) => new FontStyleScope(GUI.skin.label, value);
public static FontStyleScope SetFontStyle(GUIStyle target) => new FontStyleScope(target);
public static FontSizeScope SetFontSize(GUIStyle target, int value) => new FontSizeScope(target, value);
public static FontSizeScope SetFontSize(GUIStyle target) => new FontSizeScope(target);
public static AlignmentScope SetAlignment(GUIStyle target, TextAnchor value) => new AlignmentScope(target, value);
public static AlignmentScope SetAlignment(TextAnchor value) => new AlignmentScope(GUI.skin.label, value);
public static AlignmentScope SetAlignment(GUIStyle target) => new AlignmentScope(target);
public static IndentLevelScope SetIndentLevel(int level) => new IndentLevelScope(level);
public static IndentLevelScope UpIndentLevel() => new IndentLevelScope(EditorGUI.indentLevel + 1);
@ -136,8 +196,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
public static EditorGUI.DisabledScope Enable => new EditorGUI.DisabledScope(false);
public static EditorGUI.DisabledScope Disable => new EditorGUI.DisabledScope(true);
public static EditorGUI.DisabledScope SetEnable(bool value) => new EditorGUI.DisabledScope(!value);
#endregion
private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
@ -320,7 +379,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
public static void EntityBar(Rect position, bool isPlaceholder, EntityStatus status, int id = 0, short gen = 0, short world = 0)
{
using (new LabelWidthScore(0f))
using (new LabelWidthScope(0f))
{
var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(position, 3f);
@ -346,7 +405,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
private static void EntityBar_Internal(Rect position, bool isPlaceHolder, int id = 0, short gen = 0, short world = 0)
{
using (new LabelWidthScore(0f))
using (new LabelWidthScope(0f))
{
Color w = Color.gray;
w.a = 0.6f;
@ -385,13 +444,122 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
#endregion
internal static int GetChildPropertiesCount(SerializedProperty property, Type type, out bool isEmpty)
#region DrawTypeMetaBlock
private static float DrawTypeMetaBlockPadding => EditorGUIUtility.standardVerticalSpacing;
private static float SingleLineWithPadding => EditorGUIUtility.singleLineHeight + DrawTypeMetaBlockPadding * 4f;
public static float GetTypeMetaBlockHeight(float contentHeight)
{
return DrawTypeMetaBlockPadding * 2 + contentHeight;
}
public static void DrawTypeMetaBlock(ref Rect position, SerializedProperty property, ITypeMeta meta)
{
if (meta == null)
{
return;
}
GUIContent label = UnityEditorUtility.GetLabel(property.displayName);
var counter = property.Copy();
int positionCountr = int.MaxValue;
int depth = -1;
while (counter.NextVisibleDepth(false, ref depth))
{
positionCountr--;
}
//var counter = property.Copy();
//int positionCountr = int.MaxValue;
//while (counter.NextVisible(false))
//{
// positionCountr--;
//}
string name = meta.Name;
string description = meta.Description.Text;
Color panelColor = EcsGUI.SelectPanelColor(meta, positionCountr, -1).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
Color alphaPanelColor = panelColor;
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
EditorGUI.BeginChangeCheck();
EditorGUI.DrawRect(position, alphaPanelColor);
Rect paddingPosition = RectUtility.AddPadding(position, DrawTypeMetaBlockPadding * 2f);
Rect optionButton = position;
optionButton.center -= new Vector2(0, optionButton.height);
optionButton.yMin = optionButton.yMax;
optionButton.yMax += HeadIconsRect.height;
optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * DrawTypeMetaBlockPadding * 1f;
//Canceling isExpanded
if (HitTest(optionButton) && Event.current.type == EventType.MouseUp)
{
property.isExpanded = !property.isExpanded;
}
//Close button
optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
if (CloseButton(optionButton))
{
property.ResetValues();
return;
}
//Edit script button
if (UnityEditorUtility.TryGetScriptAsset(meta.Type, out MonoScript script))
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
ScriptAssetButton(optionButton, script);
}
//Description icon
if (string.IsNullOrEmpty(description) == false)
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
DescriptionIcon(optionButton, description);
}
//if (string.IsNullOrEmpty(label.text))
//{
// EditorGUI.indentLevel++;
// EditorGUI.PrefixLabel(position.AddPadding(0, 0, 0, position.height - SingleLineWithPadding), UnityEditorUtility.GetLabel(name));
// EditorGUI.indentLevel--;
//}
//else
//{
// GUI.Label(position.AddPadding(EditorGUIUtility.labelWidth, 0, 0, position.height - SingleLineWithPadding), name);
//}
position = paddingPosition;
}
#endregion
#region NextDepth/GetChildPropertiesCount
internal static bool NextVisibleDepth(this SerializedProperty property, bool child, ref int depth)
{
if (depth < 0)
{
depth = property.depth;
}
return property.NextVisible(child) && property.depth >= depth;
}
internal static bool NextDepth(this SerializedProperty property, bool child, ref int depth)
{
if (depth < 0)
{
depth = property.depth;
}
return property.Next(child) && property.depth >= depth;
}
internal static int GetChildPropertiesCount(this SerializedProperty property, Type type, out bool isEmpty)
{
int result = GetChildPropertiesCount(property);
isEmpty = result <= 0 && type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0;
return result;
}
internal static int GetChildPropertiesCount(SerializedProperty property)
internal static int GetChildPropertiesCount(this SerializedProperty property)
{
var propsCounter = property.Copy();
int lastDepth = propsCounter.depth;
@ -404,6 +572,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
return result;
}
#endregion
#region SelectPanelColor
public static Color SelectPanelColor(ITypeMeta meta, int index, int total)
{
var trueMeta = meta.Type.ToMeta();
@ -431,6 +602,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
}
}
#endregion
#region Other Elements
public static bool AddComponentButton(Rect position, out Rect dropDownRect)
{
dropDownRect = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f);
@ -471,7 +645,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
EditorGUI.BeginProperty(position, label, property);
EditorGUI.EndProperty();
}
#endregion
#region SerializeReferenceFixer
#endregion
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,176 @@
namespace DCFApixels.DragonECS.Unity.Internal
{
using System;
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = true)]
internal sealed class ArrayElementAttribute : Attribute { }
}
#if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors
{
using DCFApixels.DragonECS.Unity.Internal;
using global::Unity.Collections.LowLevel.Unsafe;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityObject = UnityEngine.Object;
internal abstract class ExtendedEditor : Editor
{
private bool _isStaticInit = false;
private bool _isInit = false;
protected float SingleLineHeight
{
get => EditorGUIUtility.singleLineHeight;
}
protected float Spacing
{
get => EditorGUIUtility.standardVerticalSpacing;
}
protected virtual bool IsStaticInit { get { return _isStaticInit; } }
protected virtual bool IsInit { get { return _isInit; } }
protected void StaticInit()
{
if (IsStaticInit) { return; }
_isStaticInit = true;
OnStaticInit();
}
protected void Init()
{
if (IsInit) { return; }
_isInit = true;
OnInit();
}
protected virtual void OnStaticInit() { }
protected virtual void OnInit() { }
public sealed override void OnInspectorGUI()
{
using (EcsGUI.CheckChanged())
{
StaticInit();
Init();
DrawCustom();
}
}
protected abstract void DrawCustom();
protected void DrawDefault()
{
base.OnInspectorGUI();
}
protected SerializedProperty FindProperty(string name)
{
return serializedObject.FindProperty(name);
}
}
internal abstract class ExtendedEditor<T> : ExtendedEditor where T : UnityObject
{
public T Target
{
get
{
var obj = target;
return UnsafeUtility.As<UnityObject, T>(ref obj);
}
}
public T[] Targets
{
get
{
var obj = targets;
return UnsafeUtility.As<UnityObject[], T[]>(ref obj);
}
}
}
internal abstract class ExtendedPropertyDrawer : PropertyDrawer
{
private bool _isStaticInit = false;
private bool _isInit = false;
private IEnumerable<Attribute> _attributes = null;
private bool? _isArrayElement = null;
protected bool IsArrayElement
{
get
{
if (_isArrayElement == null)
{
_isArrayElement = Attributes.Any(o => o is ArrayElementAttribute);
}
return _isArrayElement.Value;
}
}
private IEnumerable<Attribute> Attributes
{
get
{
if (_attributes == null)
{
_attributes = fieldInfo.GetCustomAttributes();
}
return _attributes;
}
}
protected float OneLineHeight
{
get => EditorGUIUtility.singleLineHeight;
}
protected float Spacing
{
get => EditorGUIUtility.standardVerticalSpacing;
}
protected virtual bool IsStaticInit { get { return _isStaticInit; } }
protected virtual bool IsInit { get { return _isInit; } }
protected void StaticInit()
{
if (IsStaticInit) { return; }
_isStaticInit = true;
OnStaticInit();
}
protected void Init()
{
if (IsInit) { return; }
_isInit = true;
OnInit();
}
protected virtual void OnStaticInit() { }
protected virtual void OnInit() { }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
using (EcsGUI.CheckChanged())
{
StaticInit();
Init();
DrawCustom(position, property, label);
}
}
protected abstract void DrawCustom(Rect position, SerializedProperty property, GUIContent label);
}
internal abstract class ExtendedPropertyDrawer<TAttribute> : ExtendedPropertyDrawer
{
protected TAttribute Attribute
{
get
{
var obj = attribute;
return UnsafeUtility.As<PropertyAttribute, TAttribute>(ref obj);
}
}
}
}
#endif

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e9a6ec3374a23a441bc22494aca34430
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -116,6 +116,115 @@ namespace DCFApixels.DragonECS.Unity.Editors
private static Dictionary<Type, MonoScript> scriptsAssets = new Dictionary<Type, MonoScript>(256);
internal static void ResetValues(this SerializedProperty property, bool isExpand = false)
{
property.isExpanded = isExpand;
switch (property.propertyType)
{
case SerializedPropertyType.Generic:
try
//TODO хз как с этим работать, но это говно постоянно кидает
//InvalidOperationException: The operation is not possible when moved past all properties (Next returned false)
//и не дает инструментов и шансов этого избежать
{
while (property.Next(true))
{
property.ResetValues(isExpand);
}
}
catch (Exception) { }
break;
case SerializedPropertyType.Integer:
property.intValue = default;
break;
case SerializedPropertyType.Boolean:
property.boolValue = default;
break;
case SerializedPropertyType.Float:
property.floatValue = default;
break;
case SerializedPropertyType.String:
property.stringValue = string.Empty;
break;
case SerializedPropertyType.Color:
property.colorValue = default;
break;
case SerializedPropertyType.ObjectReference:
property.objectReferenceValue = null;
break;
case SerializedPropertyType.LayerMask:
property.intValue = default;
break;
case SerializedPropertyType.Enum:
property.enumValueIndex = default;
break;
case SerializedPropertyType.Vector2:
property.vector2Value = default;
break;
case SerializedPropertyType.Vector3:
property.vector3Value = default;
break;
case SerializedPropertyType.Vector4:
property.vector4Value = default;
break;
case SerializedPropertyType.Rect:
property.rectValue = default;
break;
case SerializedPropertyType.ArraySize:
property.ClearArray();
break;
case SerializedPropertyType.Character:
property.intValue = default;
break;
case SerializedPropertyType.AnimationCurve:
property.animationCurveValue = new AnimationCurve();
break;
case SerializedPropertyType.Bounds:
property.boundsValue = default;
break;
case SerializedPropertyType.Gradient:
#if UNITY_2022_1_OR_NEWER
property.gradientValue = new Gradient();;
#else
Debug.LogWarning($"Unsupported SerializedPropertyType: {property.propertyType}");
#endif
break;
case SerializedPropertyType.Quaternion:
property.quaternionValue = Quaternion.identity;
break;
case SerializedPropertyType.ExposedReference:
property.objectReferenceValue = null;
break;
case SerializedPropertyType.FixedBufferSize:
for (int i = 0, iMax = property.fixedBufferSize; i < iMax; i++)
{
property.GetFixedBufferElementAtIndex(i).intValue = default;
}
break;
case SerializedPropertyType.Vector2Int:
property.vector2IntValue = default;
break;
case SerializedPropertyType.Vector3Int:
property.vector3IntValue = default;
break;
case SerializedPropertyType.RectInt:
property.rectIntValue = default;
break;
case SerializedPropertyType.BoundsInt:
property.boundsIntValue = default;
break;
case SerializedPropertyType.ManagedReference:
property.managedReferenceValue = default;
break;
case SerializedPropertyType.Hash128:
property.hash128Value = default;
break;
default:
Debug.LogWarning($"Unsupported SerializedPropertyType: {property.propertyType}");
break;
}
}
internal static bool TryGetScriptAsset(Type type, out MonoScript script)
{
if (scriptsAssets.TryGetValue(type, out script) == false)