From 0aaffd0240df091e589344c79df559b04204ee2e Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 8 Dec 2024 15:38:04 +0800 Subject: [PATCH] stash --- src/Buildin/EcsDefaultWorldProvider.cs | 2 +- .../EcsDefaultWorldSingletonProvider.cs | 2 +- src/Buildin/EcsRootUnity.cs | 1 + src/Buildin/EcsWorldProvider.cs | 2 +- src/Internal/ArrayUtility.cs | 71 +++++ src/Internal/Editor/EcsGUI.cs | 293 +++++++++++++++++- src/Internal/Editor/ExtendedEditor.cs | 27 +- src/Internal/Editor/UnityEditorUtility.cs | 4 + src/Internal/Icons/Color_Icon.png | Bin 0 -> 13139 bytes src/Internal/Icons/Color_Icon.png.meta | 122 ++++++++ src/Internal/Icons/Gray_Icon.png | Bin 0 -> 12860 bytes src/Internal/Icons/Gray_Icon.png.meta | 122 ++++++++ src/Internal/Utils/StructList.cs | 165 ++++++++++ src/Internal/Utils/StructList.cs.meta | 11 + src/Internal/Utils/Throw.cs | 12 + src/Internal/Utils/Throw.cs.meta | 11 + .../Editor/EntityTemplateEditor.cs | 2 + .../Templates/MonoEntityTemplate.cs | 1 + 18 files changed, 840 insertions(+), 8 deletions(-) create mode 100644 src/Internal/Icons/Color_Icon.png create mode 100644 src/Internal/Icons/Color_Icon.png.meta create mode 100644 src/Internal/Icons/Gray_Icon.png create mode 100644 src/Internal/Icons/Gray_Icon.png.meta create mode 100644 src/Internal/Utils/StructList.cs create mode 100644 src/Internal/Utils/StructList.cs.meta create mode 100644 src/Internal/Utils/Throw.cs create mode 100644 src/Internal/Utils/Throw.cs.meta diff --git a/src/Buildin/EcsDefaultWorldProvider.cs b/src/Buildin/EcsDefaultWorldProvider.cs index 4892e3f..21cf271 100644 --- a/src/Buildin/EcsDefaultWorldProvider.cs +++ b/src/Buildin/EcsDefaultWorldProvider.cs @@ -5,6 +5,6 @@ namespace DCFApixels.DragonECS [CreateAssetMenu(fileName = nameof(EcsDefaultWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsDefaultWorldProvider), order = 1)] public class EcsDefaultWorldProvider : EcsWorldProvider { - protected override EcsDefaultWorld BuildWorld(ConfigContainer configs) { return new EcsDefaultWorld(configs, WorldID); } + protected override EcsDefaultWorld BuildWorld(ConfigContainer configs) { return new EcsDefaultWorld(configs, null, WorldID); } } } diff --git a/src/Buildin/EcsDefaultWorldSingletonProvider.cs b/src/Buildin/EcsDefaultWorldSingletonProvider.cs index fbd0b25..2f2abc2 100644 --- a/src/Buildin/EcsDefaultWorldSingletonProvider.cs +++ b/src/Buildin/EcsDefaultWorldSingletonProvider.cs @@ -14,6 +14,6 @@ return _instance; } } - protected override EcsDefaultWorld BuildWorld(ConfigContainer configs) { return new EcsDefaultWorld(configs, WorldID); } + protected override EcsDefaultWorld BuildWorld(ConfigContainer configs) { return new EcsDefaultWorld(configs, null, WorldID); } } } diff --git a/src/Buildin/EcsRootUnity.cs b/src/Buildin/EcsRootUnity.cs index fbf4531..d859dab 100644 --- a/src/Buildin/EcsRootUnity.cs +++ b/src/Buildin/EcsRootUnity.cs @@ -77,6 +77,7 @@ namespace DCFApixels.DragonECS private void OnDrawGizmos() { + Gizmos.DrawIcon(transform.position, "", false); _pipeline?.DrawGizmos(); } diff --git a/src/Buildin/EcsWorldProvider.cs b/src/Buildin/EcsWorldProvider.cs index 45e2735..8f4f35e 100644 --- a/src/Buildin/EcsWorldProvider.cs +++ b/src/Buildin/EcsWorldProvider.cs @@ -5,6 +5,6 @@ namespace DCFApixels.DragonECS [CreateAssetMenu(fileName = nameof(EcsWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsWorldProvider), order = 1)] public class EcsWorldProvider : EcsWorldProvider { - protected override EcsWorld BuildWorld(ConfigContainer configs) { return new EcsWorld(configs, WorldID); } + protected override EcsWorld BuildWorld(ConfigContainer configs) { return new EcsWorld(configs, null, WorldID); } } } diff --git a/src/Internal/ArrayUtility.cs b/src/Internal/ArrayUtility.cs index f55393e..b17c463 100644 --- a/src/Internal/ArrayUtility.cs +++ b/src/Internal/ArrayUtility.cs @@ -71,4 +71,75 @@ namespace DCFApixels.DragonECS.Unity.Internal void IEnumerator.Reset() { throw new NotSupportedException(); } } } + + internal static class ArrayUtility + { + private static int GetHighBitNumber(uint bits) + { + if (bits == 0) + { + return -1; + } + int bit = 0; + if ((bits & 0xFFFF0000) != 0) + { + bits >>= 16; + bit |= 16; + } + if ((bits & 0xFF00) != 0) + { + bits >>= 8; + bit |= 8; + } + if ((bits & 0xF0) != 0) + { + bits >>= 4; + bit |= 4; + } + if ((bits & 0xC) != 0) + { + bits >>= 2; + bit |= 2; + } + if ((bits & 0x2) != 0) + { + bit |= 1; + } + return bit; + } + public static int NormalizeSizeToPowerOfTwo(int minSize) + { + unchecked + { + return 1 << (GetHighBitNumber((uint)minSize - 1u) + 1); + } + } + public static int NormalizeSizeToPowerOfTwo_ClampOverflow(int minSize) + { + unchecked + { + int hibit = (GetHighBitNumber((uint)minSize - 1u) + 1); + if (hibit >= 32) + { + return int.MaxValue; + } + return 1 << hibit; + } + } + public static void Fill(T[] array, T value, int startIndex = 0, int length = -1) + { + if (length < 0) + { + length = array.Length; + } + else + { + length = startIndex + length; + } + for (int i = startIndex; i < length; i++) + { + array[i] = value; + } + } + } } \ No newline at end of file diff --git a/src/Internal/Editor/EcsGUI.cs b/src/Internal/Editor/EcsGUI.cs index 9649305..8dac123 100644 --- a/src/Internal/Editor/EcsGUI.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -3,8 +3,10 @@ using DCFApixels.DragonECS.Unity.Internal; using System; using System.Collections.Generic; + //using System.Drawing; using System.Reflection; +using System.Runtime.InteropServices; using Unity.Collections.LowLevel.Unsafe; using UnityEditor; using UnityEditor.IMGUI.Controls; @@ -15,7 +17,7 @@ using UnityObject = UnityEngine.Object; namespace DCFApixels.DragonECS.Unity.Editors { - internal static class EcsGUI + internal static partial class EcsGUI { #region Scores private static int _changedCounter = 0; @@ -1013,7 +1015,6 @@ namespace DCFApixels.DragonECS.Unity.Editors /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - public static partial class Layout { public static void ScriptAssetButton(MonoScript script, params GUILayoutOption[] options) @@ -1302,12 +1303,14 @@ namespace DCFApixels.DragonECS.Unity.Editors GUILayout.EndVertical(); } } + + #region Default DrawRuntimeData [InitializeOnLoadMethod] private static void ResetRuntimeComponentReflectionCache() { _runtimeComponentReflectionCaches.Clear(); } - private class RuntimeComponentReflectionCache + internal class RuntimeComponentReflectionCache { public readonly Type Type; @@ -1481,6 +1484,290 @@ namespace DCFApixels.DragonECS.Unity.Editors expandMatrix.Up(); return changed; } + #endregion + + #region FactMode DrawRuntimeData + private class InspectorTypeInfo + { + #region cahce + private static Dictionary _typeInfosCache = new Dictionary(); + public static InspectorTypeInfo Get(Type type) + { + if (_typeInfosCache.TryGetValue(type, out InspectorTypeInfo info) == false) + { + info = new InspectorTypeInfo(type); + _typeInfosCache.Add(type, info); + } + + return info; + } + #endregion + + public readonly Type Type; + public readonly InspectorFieldInfo[] Fields; + + #region Constructors + private static StructList CnstrBuffer = new StructList(32); + private static readonly char[] VectorFields = new char[] { 'x', 'y', 'z', 'w' }; + private static readonly char[] ColorFields = new char[] { 'r', 'g', 'b', 'a' }; + public InspectorTypeInfo(Type type) + { + CnstrBuffer.FastClear(); + Type = type; + var fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + foreach (var fieldInfo in fieldInfos) + { + InspectorFieldInfo.Union infoUniton = default; + ref InspectorFieldInfo.Constructor infocstr = ref infoUniton.Constructor; + + var fieldType = fieldInfo.FieldType; + + infocstr.FieldInfo = fieldInfo; + infocstr.Offset = UnsafeUtility.GetFieldOffset(fieldInfo); ; + infocstr.Size = UnsafeUtility.SizeOf(fieldType); ; + infocstr.Name = UnityEditorUtility.TransformFieldName(fieldType.Name); + infocstr.TypeID = FieldTypeIDUtitlity.GetFieldTypeIDFor(fieldType); + + #region Def custom types + if (infocstr.TypeID == FieldTypeID.Struct) + { + InspectorTypeInfo preDefinedTypeInfo = Get(fieldType); + infocstr.PreDefinedType = preDefinedTypeInfo; + int length = preDefinedTypeInfo.Fields.Length; + if (length >= 2 && length <= 3) + { + bool isCheck = true; + for (int i = 0; i < length; i++) + { + ref var field = ref preDefinedTypeInfo.Fields[i]; + if (char.ToLower(field.Name[0]) != VectorFields[i]) + { + isCheck = false; + break; + } + } + if (isCheck) + { + infocstr.TypeID = FieldTypeID.StructVector; + } + else + { + isCheck = true; + for (int i = 0; i < length; i++) + { + ref var field = ref preDefinedTypeInfo.Fields[i]; + if (char.ToLower(field.Name[0]) != ColorFields[i]) + { + isCheck = false; + break; + } + } + if (isCheck) + { + infocstr.TypeID = FieldTypeID.StructColor; + } + } + } + } + #endregion + + CnstrBuffer.Add(infoUniton.Result); + } + + Fields = CnstrBuffer.ToArray(); + Array.Sort(Fields); + } + #endregion + } + + private static class FieldTypeIDUtitlity + { + #region GetFieldTypeIDFor + public static FieldTypeID GetFieldTypeIDFor(Type type) + { + var size = UnsafeUtility.SizeOf(type); + if (type.IsClass) + { + if (typeof(UnityObject).IsAssignableFrom(type)) + { + return FieldTypeID.UnityObject; + } + if (type == typeof(string)) + { + return FieldTypeID.String; + } + if (type == typeof(AnimationCurve)) + { + return FieldTypeID.AnimationCurve; + } + if (type == typeof(Gradient)) + { + return FieldTypeID.Gradient; + } + if (type == typeof(Array)) + { + return FieldTypeID.RefArray; + } + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) + { + return FieldTypeID.RefArray; + } + + return FieldTypeID.Ref; + } + else + { + if (type.IsPrimitive) + { + if (UnsafeUtility.IsBlittable(type)) + { + switch (size) + { + case 1: + if (type == typeof(byte)) + { + return FieldTypeID.UInt; + } + if (type == typeof(sbyte)) + { + return FieldTypeID.Int; + } + break; + case 2: + if (type == typeof(ushort)) + { + return FieldTypeID.UInt; + } + if (type == typeof(short)) + { + return FieldTypeID.Int; + } + break; + case 4: + if (type == typeof(uint)) + { + return FieldTypeID.UInt; + } + if (type == typeof(int)) + { + return FieldTypeID.Int; + } + if (type == typeof(float)) + { + return FieldTypeID.Real; + } + break; + case 8: + if (type == typeof(ulong)) + { + return FieldTypeID.UInt; + } + if (type == typeof(long)) + { + return FieldTypeID.Int; + } + if (type == typeof(double)) + { + return FieldTypeID.Real; + } + break; + } + } + else + { + if (type == typeof(bool)) + { + return FieldTypeID.Bool; + } + } + } + else if (type.IsEnum) + { + return FieldTypeID.Enum; + } + + if (type == typeof(LayerMask)) + { + return FieldTypeID.LayerMask; + } + + return FieldTypeID.Struct; + } + } + #endregion + } + private enum FieldTypeID : byte + { + None = 0, + CantDisplayed, + + // leaf types + Bool, + Int, + UInt, + Real, + String, + Enum, + + UnityObject, + LayerMask, + Gradient, + AnimationCurve, + + // struct types + Struct, + Ref, + + // custom struct types + StructVector, + StructColor, + RefArray, + RefList, + } + + [StructLayout(LayoutKind.Sequential)] + private unsafe readonly struct InspectorFieldInfo : IEquatable, IComparable + { + public readonly FieldInfo FieldInfo; + public readonly InspectorTypeInfo PreDefinedType; + public readonly string Name; + public readonly int Offset; + public readonly int Size; + public readonly FieldTypeID ID; + + public int CompareTo(InspectorFieldInfo other) + { + return other.Offset - Offset; + } + public bool Equals(InspectorFieldInfo other) + { + return EqualityComparer.Default.Equals(this, other); + } + [StructLayout(LayoutKind.Sequential)] + public unsafe struct Constructor + { + public FieldInfo FieldInfo; + public InspectorTypeInfo PreDefinedType; + public string Name; + public int Offset; + public int Size; + public byte AxisCount; + public FieldTypeID TypeID; + } + [StructLayout(LayoutKind.Explicit)] + public struct Union + { + [FieldOffset(0)] + public Constructor Constructor; + [FieldOffset(0)] + public InspectorFieldInfo Result; + } + } + private unsafe static bool FastDrawRuntimeData(void* data, InspectorTypeInfo cache) + { + throw new NotImplementedException(); + } + #endregion } } } diff --git a/src/Internal/Editor/ExtendedEditor.cs b/src/Internal/Editor/ExtendedEditor.cs index 5648dc7..f9d4e6c 100644 --- a/src/Internal/Editor/ExtendedEditor.cs +++ b/src/Internal/Editor/ExtendedEditor.cs @@ -92,12 +92,35 @@ namespace DCFApixels.DragonECS.Unity.Editors { base.OnInspectorGUI(); } - - protected SerializedProperty FindProperty(string name) { return serializedObject.FindProperty(name); } + + + //Color proColor = (Color)new Color32(56, 56, 56, 255); + //Color plebColor = (Color)new Color32(194, 194, 194, 255); + //protected override void OnHeaderGUI() + //{ + // //base.OnHeaderGUI(); + // var rect = EditorGUILayout.GetControlRect(false, 0f); + // rect.height = EditorGUIUtility.singleLineHeight; + // rect.y -= rect.height; + // rect.x = 48; + // rect.xMax -= rect.x * 2f; + // + // //GUI.skin.settings + // EditorGUI.DrawRect(rect, EditorGUIUtility.isProSkin ? proColor : plebColor); + // + // //string header = (target as ComponentFolder).folderName; // <--- your variable + // string header = ""; + // if (string.IsNullOrEmpty(header)) + // { + // header = target.ToString() + 1; + // } + // + // EditorGUI.LabelField(rect, header, EditorStyles.boldLabel); + //} } internal abstract class ExtendedEditor : ExtendedEditor { diff --git a/src/Internal/Editor/UnityEditorUtility.cs b/src/Internal/Editor/UnityEditorUtility.cs index 4ec3289..7df6d82 100644 --- a/src/Internal/Editor/UnityEditorUtility.cs +++ b/src/Internal/Editor/UnityEditorUtility.cs @@ -103,12 +103,15 @@ namespace DCFApixels.DragonECS.Unity.Editors namespace DCFApixels.DragonECS.Unity.Editors { using UnityEditor; + using Assembly = System.Reflection.Assembly; [InitializeOnLoad] internal static partial class UnityEditorUtility { static UnityEditorUtility() { + _integrationAssembly = typeof(UnityEditorUtility).Assembly; + colorBoxeStyles = new SparseArray(); List serializableTypes = new List(); @@ -144,6 +147,7 @@ namespace DCFApixels.DragonECS.Unity.Editors //}).ToArray(); } + internal static readonly Assembly _integrationAssembly; internal static readonly Type[] _serializableTypes; internal static readonly TypeMeta[] _serializableTypeWithMetaIDMetas; private static readonly Dictionary _metaIDTypePairs = new Dictionary(); diff --git a/src/Internal/Icons/Color_Icon.png b/src/Internal/Icons/Color_Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..69278be0e0c0ef665c5155c9a970bf9adff9a537 GIT binary patch literal 13139 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 + { + internal T[] _items; + internal int _count; + public int Count + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _count; } + } + public int Capacity + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _items.Length; } + set + { + if (value <= _items.Length) { return; } + value = ArrayUtility.NormalizeSizeToPowerOfTwo(value); + Array.Resize(ref _items, value); + } + } + public T this[int index] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { +#if DEBUG + if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); } +#endif + return _items[index]; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set + { +#if DEBUG + if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); } +#endif + _items[index] = value; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public StructList(int capacity) + { + _items = new T[ArrayUtility.NormalizeSizeToPowerOfTwo(capacity)]; + _count = 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Add(T item) + { + if (_count >= _items.Length) + { + Array.Resize(ref _items, _items.Length << 1); + } + _items[_count++] = item; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int IndexOf(T item) + { + return Array.IndexOf(_items, item, 0, _count); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void SwapAt(int idnex1, int idnex2) + { + T tmp = _items[idnex1]; + _items[idnex1] = _items[idnex2]; + _items[idnex2] = tmp; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void FastRemoveAt(int index) + { +#if DEBUG + if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); } +#endif + _items[index] = _items[--_count]; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RemoveAt(int index) + { +#if DEBUG + if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); } +#endif + _items[index] = _items[--_count]; + _items[_count] = default; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RemoveAtWithOrder(int index) + { +#if DEBUG + if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); } +#endif + for (int i = index; i < _count;) + { + _items[i++] = _items[i]; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Remove(T item) + { + int index = IndexOf(item); + if (index >= 0) + { + RemoveAt(index); + return true; + } + return false; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool RemoveWithOrder(T item) + { + int index = IndexOf(item); + if (index >= 0) + { + RemoveAtWithOrder(index); + return true; + } + return false; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void FastClear() + { + _count = 0; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Clear() + { + for (int i = 0; i < _count; i++) + { + _items[i] = default; + } + _count = 0; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan.Enumerator GetEnumerator() + { + return new ReadOnlySpan(_items, 0, _count).GetEnumerator(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan ToReadOnlySpan() + { + return new ReadOnlySpan(_items, 0, _count); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IEnumerable ToEnumerable() + { + return _items.Take(_count); + } + + public T[] ToArray() + { + T[] result = new T[_count]; + Array.Copy(_items, result, _count); + return _items; + } + } +} \ No newline at end of file diff --git a/src/Internal/Utils/StructList.cs.meta b/src/Internal/Utils/StructList.cs.meta new file mode 100644 index 0000000..1aeea41 --- /dev/null +++ b/src/Internal/Utils/StructList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 366ced1c4c1442c4db00c5a2b8c5787d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Internal/Utils/Throw.cs b/src/Internal/Utils/Throw.cs new file mode 100644 index 0000000..03aa65d --- /dev/null +++ b/src/Internal/Utils/Throw.cs @@ -0,0 +1,12 @@ +using System; + +namespace DCFApixels.DragonECS.Unity.Internal +{ + internal static class Throw + { + internal static void ArgumentOutOfRange() + { + throw new ArgumentOutOfRangeException(); + } + } +} diff --git a/src/Internal/Utils/Throw.cs.meta b/src/Internal/Utils/Throw.cs.meta new file mode 100644 index 0000000..4b32348 --- /dev/null +++ b/src/Internal/Utils/Throw.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 525c4a5bc83fb3343b3b93a02d3caf59 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Templates/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/Templates/EntityTemplate/Editor/EntityTemplateEditor.cs index 24f4085..96e2f52 100644 --- a/src/Templates/EntityTemplate/Editor/EntityTemplateEditor.cs +++ b/src/Templates/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -1,7 +1,9 @@ #if UNITY_EDITOR using DCFApixels.DragonECS.Unity.Internal; using DCFApixels.DragonECS.Unity.RefRepairer.Editors; +using System; using UnityEditor; +using UnityEditor.Graphs; using UnityEditorInternal; using UnityEngine; diff --git a/src/Templates/EntityTemplate/Templates/MonoEntityTemplate.cs b/src/Templates/EntityTemplate/Templates/MonoEntityTemplate.cs index d5b7811..3f84c8f 100644 --- a/src/Templates/EntityTemplate/Templates/MonoEntityTemplate.cs +++ b/src/Templates/EntityTemplate/Templates/MonoEntityTemplate.cs @@ -2,6 +2,7 @@ using DCFApixels.DragonECS.Unity.Internal; using System; using UnityEngine; +using static UnityEngine.GraphicsBuffer; namespace DCFApixels.DragonECS {