This commit is contained in:
ByteWarsJedi 2024-12-10 20:34:15 +08:00
parent 0aaffd0240
commit f1666d2fcb
12 changed files with 1465 additions and 1019 deletions

View File

@ -53,29 +53,25 @@ namespace DCFApixels.DragonECS.Unity.Editors
//using (prefs.DisableAutoSave())
{
GUILayout.BeginHorizontal();
prefs.IsShowHidden = EditorGUILayout.ToggleLeft(
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsShowHidden)),
prefs.IsShowHidden);
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
prefs.IsShowInterfaces = EditorGUILayout.ToggleLeft(
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsShowInterfaces)),
prefs.IsShowInterfaces);
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
prefs.IsShowRuntimeComponents = EditorGUILayout.ToggleLeft(
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsShowRuntimeComponents)),
prefs.IsShowRuntimeComponents);
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
prefs.IsUseCustomNames = EditorGUILayout.ToggleLeft(
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsUseCustomNames)),
prefs.IsUseCustomNames);
GUILayout.EndHorizontal();
prefs.IsFastModeRuntimeComponents = EditorGUILayout.ToggleLeft(
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsFastModeRuntimeComponents)),
prefs.IsFastModeRuntimeComponents);
prefs.ComponentColorMode = (ComponentColorMode)EditorGUILayout.EnumPopup(UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.ComponentColorMode)), prefs.ComponentColorMode);
}

View File

@ -69,6 +69,20 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
}
}
[SerializeField]
private bool _isFastModeRuntimeComponents = false;
public bool IsFastModeRuntimeComponents
{
get => _isFastModeRuntimeComponents;
set
{
if (_isFastModeRuntimeComponents != value)
{
_isFastModeRuntimeComponents = value;
AutoSave();
}
}
}
//[SerializeField]
//private bool _poolsToggle = false;

View File

@ -0,0 +1,502 @@
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Collections.Generic;
using System.Reflection;
using Unity.Collections.LowLevel.Unsafe;
using UnityEditor;
using UnityEngine;
using Color = UnityEngine.Color;
using UnityComponent = UnityEngine.Component;
using UnityObject = UnityEngine.Object;
namespace DCFApixels.DragonECS.Unity.Editors
{
internal static partial class EcsGUI
{
public static partial class Layout
{
public static void ScriptAssetButton(MonoScript script, params GUILayoutOption[] options)
{
EcsGUI.ScriptAssetButton(GUILayoutUtility.GetRect(UnityEditorUtility.GetLabelTemp(), EditorStyles.miniButton, options), script);
}
public static void CopyMetaIDButton(string metaID, params GUILayoutOption[] options)
{
Rect r = GUILayoutUtility.GetRect(UnityEditorUtility.GetLabelTemp(), EditorStyles.miniButton, options);
var current = Event.current;
var hover = IconHoverScan(r, current);
using (new ColorScope(new Color(1f, 1f, 1f, hover ? 1f : 0.8f)))
{
DrawIcon(r, Icons.Instance.MetaIDIcon, hover ? 1f : 2f, metaID);
if (hover && current.type == EventType.MouseUp)
{
GUIUtility.systemCopyBuffer = metaID;
}
}
}
public static bool IconButton(Texture icon, params GUILayoutOption[] options)
{
bool result = GUILayout.Button(UnityEditorUtility.GetLabel(string.Empty), options);
DrawIcon(GUILayoutUtility.GetLastRect(), icon, 0, null);
return result;
}
public static bool IconButton(Texture icon, float iconPadding = 0, string description = null)
{
bool result = GUILayout.Button(UnityEditorUtility.GetLabel(string.Empty));
DrawIcon(GUILayoutUtility.GetLastRect(), icon, iconPadding, description);
return result;
}
public static bool IconButton(Texture icon, float iconPadding = 0, string description = null, GUIStyle style = null, params GUILayoutOption[] options)
{
bool result;
if (style == null)
{
result = GUILayout.Button(UnityEditorUtility.GetLabel(string.Empty), options);
}
else
{
result = GUILayout.Button(UnityEditorUtility.GetLabel(string.Empty), style, options);
}
DrawIcon(GUILayoutUtility.GetLastRect(), icon, iconPadding, description);
return result;
}
public static void DrawEmptyComponentProperty(SerializedProperty property, string name, bool isDisplayEmpty)
{
EcsGUI.DrawEmptyComponentProperty(GUILayoutUtility.GetRect(UnityEditorUtility.GetLabel(name), EditorStyles.label), property, name, isDisplayEmpty);
}
public static void DrawEmptyComponentProperty(SerializedProperty property, GUIContent label, bool isDisplayEmpty)
{
EcsGUI.DrawEmptyComponentProperty(GUILayoutUtility.GetRect(label, EditorStyles.label), property, label, isDisplayEmpty);
}
public static void DrawWorldBaseInfo(EcsWorld world)
{
bool isNull = world == null || world.IsDestroyed || world.ID == 0;
int entitesCount = isNull ? 0 : world.Count;
int capacity = isNull ? 0 : world.Capacity;
long Version = isNull ? 0 : world.Version;
int leakedEntitesCount = isNull ? 0 : world.CountLeakedEntitesDebug();
EditorGUILayout.IntField("Entities", entitesCount, EditorStyles.boldLabel);
EditorGUILayout.IntField("Capacity", capacity, EditorStyles.boldLabel);
EditorGUILayout.LongField("Version", Version, EditorStyles.boldLabel);
Color color = leakedEntitesCount > 0 ? Color.yellow : GUI.contentColor;
using (new ContentColorScope(color))
{
EditorGUILayout.IntField("Leaked Entites", leakedEntitesCount, EditorStyles.boldLabel);
}
}
public static void DrawWorldComponents(EcsWorld world)
{
bool isNull = world == null || world.IsDestroyed || world.ID == 0;
if (isNull) { return; }
using (BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)))
{
IsShowRuntimeComponents = EditorGUILayout.BeginFoldoutHeaderGroup(IsShowRuntimeComponents, "RUNTIME COMPONENTS", EditorStyles.foldout);
EditorGUILayout.EndFoldoutHeaderGroup();
if (IsShowRuntimeComponents == false) { return; }
var worldID = world.ID;
var cmps = world.GetWorldComponents();
int index = -1;
int total = 9;
foreach (var cmp in cmps)
{
index++;
var meta = cmp.ComponentType.ToMeta();
if (meta.IsHidden == false || IsShowHidden)
{
Type componentType = cmp.ComponentType;
object data = cmp.GetRaw(worldID);
ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType);
float padding = EditorGUIUtility.standardVerticalSpacing;
Rect optionButton = GUILayoutUtility.GetLastRect();
optionButton.yMin = optionButton.yMax;
optionButton.yMax += HeadIconsRect.height;
optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * padding * 2f;
//Canceling isExpanded
if (ClickTest(optionButton))
{
ref bool isExpanded = ref expandMatrix.Down();
isExpanded = !isExpanded;
}
Color panelColor = SelectPanelColor(meta, index, total);
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(panelColor, EscEditorConsts.COMPONENT_DRAWER_ALPHA));
EditorGUI.BeginChangeCheck();
////Close button
//optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
//if (CloseButton(optionButton))
//{
// cmp.Del(worldID);
// return;
//}
//Edit script button
if (ScriptsCache.TryGetScriptAsset(meta, out MonoScript script))
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
EcsGUI.ScriptAssetButton(optionButton, script);
}
//Description icon
if (string.IsNullOrEmpty(meta.Description.Text) == false)
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
DescriptionIcon(optionButton, meta.Description.Text);
}
RuntimeComponentReflectionCache.FieldInfoData componentInfoData = new RuntimeComponentReflectionCache.FieldInfoData(null, componentType, meta.Name);
if (DrawRuntimeData(ref componentInfoData, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData))
{
cmp.SetRaw(worldID, resultData);
}
GUILayout.EndVertical();
}
}
}
}
#region entity bar
public static void EntityBarForAlive(EntityStatus status, int id, short gen, short world)
{
float width = EditorGUIUtility.currentViewWidth;
float height = EntityBarHeight;
EcsGUI.EntityBarForAlive(GUILayoutUtility.GetRect(width, height), status, id, gen, world);
}
public static void EntityBar(EntityStatus status, bool isPlaceholder, int id, short gen, short world)
{
float width = EditorGUIUtility.currentViewWidth;
float height = EntityBarHeight;
EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height), isPlaceholder, status, id, gen, world);
}
public static void EntityBar(int id, short gen, short world)
{
float width = EditorGUIUtility.currentViewWidth;
float height = EntityBarHeight;
EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height), id, gen, world);
}
public static void EntityBar()
{
float width = EditorGUIUtility.currentViewWidth;
float height = EntityBarHeight;
EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height));
}
#endregion
public static bool AddComponentButtons(out Rect dropDownRect)
{
return EcsGUI.AddComponentButton(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 24f), out dropDownRect);
}
public static AddClearButton AddClearComponentButtons(out Rect dropDownRect)
{
return EcsGUI.AddClearComponentButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 24f), out dropDownRect);
}
public static AddClearButton AddClearSystemButtons(out Rect dropDownRect)
{
return EcsGUI.AddClearSystemButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 24f), out dropDownRect);
}
public static void DrawRuntimeComponents(entlong entity, bool isWithFoldout = true)
{
if (entity.TryUnpackForUnityEditor(out int entityID, out _, out _, out EcsWorld world))
{
DrawRuntimeComponents(entityID, world, isWithFoldout);
}
}
[ThreadStatic]
private static List<IEcsPool> _componentPoolsBuffer;
public static void DrawRuntimeComponents(int entityID, EcsWorld world, bool isWithFoldout = true)
{
using (BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)))
{
if (isWithFoldout)
{
IsShowRuntimeComponents = EditorGUILayout.BeginFoldoutHeaderGroup(IsShowRuntimeComponents, "RUNTIME COMPONENTS", EditorStyles.foldout);
EditorGUILayout.EndFoldoutHeaderGroup();
}
if (isWithFoldout == false || IsShowRuntimeComponents)
{
if (AddComponentButtons(out Rect dropDownRect))
{
RuntimeComponentsUtility.GetAddComponentGenericMenu(world).Open(dropDownRect, entityID);
}
GUILayout.Box("", UnityEditorUtility.GetStyle(GUI.color, 0.16f), GUILayout.ExpandWidth(true));
IsShowHidden = EditorGUI.Toggle(GUILayoutUtility.GetLastRect(), "Show Hidden", IsShowHidden);
if (_componentPoolsBuffer == null)
{
_componentPoolsBuffer = new List<IEcsPool>(64);
}
world.GetComponentPoolsFor(entityID, _componentPoolsBuffer);
int i = 0;
//int iMax = _componentPoolsBuffer.Count;
foreach (var componentPool in _componentPoolsBuffer)
{
DrawRuntimeComponent(entityID, componentPool, 9, i++);
}
}
}
}
private static void DrawRuntimeComponent(int entityID, IEcsPool pool, int total, int index)
{
var meta = pool.ComponentType.ToMeta();
if (meta.IsHidden == false || IsShowHidden)
{
Type componentType = pool.ComponentType;
object data = pool.GetRaw(entityID);
ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType);
float padding = EditorGUIUtility.standardVerticalSpacing;
Rect optionButton = GUILayoutUtility.GetLastRect();
optionButton.yMin = optionButton.yMax;
optionButton.yMax += HeadIconsRect.height;
optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * padding * 2f;
//Canceling isExpanded
if (ClickTest(optionButton))
{
ref bool isExpanded = ref expandMatrix.Down();
isExpanded = !isExpanded;
}
Color panelColor = SelectPanelColor(meta, index, total);
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(panelColor, EscEditorConsts.COMPONENT_DRAWER_ALPHA));
EditorGUI.BeginChangeCheck();
//Close button
optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
if (CloseButton(optionButton))
{
pool.Del(entityID);
return;
}
//Edit script button
if (ScriptsCache.TryGetScriptAsset(meta, out MonoScript script))
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
EcsGUI.ScriptAssetButton(optionButton, script);
}
//Description icon
if (string.IsNullOrEmpty(meta.Description.Text) == false)
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
DescriptionIcon(optionButton, meta.Description.Text);
}
RuntimeComponentReflectionCache.FieldInfoData componentInfoData = new RuntimeComponentReflectionCache.FieldInfoData(null, componentType, meta.Name);
if (IsFastModeRuntimeComponents)
{
if (DrawRuntimeData(ref componentInfoData, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData))
{
pool.SetRaw(entityID, resultData);
}
}
else
{
if (DrawProperty(data))
{
pool.SetRaw(entityID, data);
}
}
GUILayout.EndVertical();
}
}
#region Default DrawRuntimeData
[InitializeOnLoadMethod]
private static void ResetRuntimeComponentReflectionCache()
{
_runtimeComponentReflectionCaches.Clear();
}
internal class RuntimeComponentReflectionCache
{
public readonly Type Type;
public readonly bool IsUnityObjectType;
public readonly bool IsUnitySerializable;
public readonly bool IsUnmanaged;
public readonly FieldInfoData[] Fields;
public readonly RefEditorWrapper Wrapper;
public RuntimeComponentReflectionCache(Type type)
{
Type = type;
IsUnmanaged = UnsafeUtility.IsUnmanaged(type);
IsUnityObjectType = typeof(UnityObject).IsAssignableFrom(type);
IsUnitySerializable = IsUnityObjectType || (!type.IsGenericType && type.IsSerializable);
Wrapper = RefEditorWrapper.Take();
if (type == typeof(void)) { return; }
if (IsUnitySerializable == false)
{
var fs = type.GetFields(fieldFlags);
Fields = new FieldInfoData[fs.Length];
for (int i = 0; i < fs.Length; i++)
{
var f = fs[i];
Fields[i] = new FieldInfoData(f);
}
}
}
public readonly struct FieldInfoData
{
public readonly FieldInfo FieldInfo;
public readonly Type FieldType;
public readonly string UnityFormatName;
public readonly bool IsUnityObjectField;
public FieldInfoData(FieldInfo fieldInfo)
{
FieldInfo = fieldInfo;
FieldType = fieldInfo.FieldType;
IsUnityObjectField = typeof(UnityObject).IsAssignableFrom(fieldInfo.FieldType);
UnityFormatName = UnityEditorUtility.TransformFieldName(fieldInfo.Name);
}
public FieldInfoData(FieldInfo fieldInfo, Type fieldType, string unityFormatName)
{
FieldInfo = fieldInfo;
FieldType = fieldType;
UnityFormatName = unityFormatName;
IsUnityObjectField = typeof(UnityObject).IsAssignableFrom(fieldType);
}
}
}
private static Dictionary<Type, RuntimeComponentReflectionCache> _runtimeComponentReflectionCaches = new Dictionary<Type, RuntimeComponentReflectionCache>();
private static RuntimeComponentReflectionCache GetRuntimeComponentReflectionCache(Type type)
{
if (_runtimeComponentReflectionCaches.TryGetValue(type, out RuntimeComponentReflectionCache result) == false)
{
result = new RuntimeComponentReflectionCache(type);
_runtimeComponentReflectionCaches.Add(type, result);
}
return result;
}
private static bool DrawRuntimeData(ref RuntimeComponentReflectionCache.FieldInfoData fieldInfoData, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData)
{
outData = data;
Type type = data == null ? typeof(void) : data.GetType();
RuntimeComponentReflectionCache cache = GetRuntimeComponentReflectionCache(type);
bool isUnityObjectField = fieldInfoData.IsUnityObjectField;
if (isUnityObjectField == false && data == null)
{
EditorGUILayout.TextField(label, "Null");
return false;
}
bool isUnityObjectType = cache.IsUnityObjectType;
ref bool isExpanded = ref expandMatrix.Down();
bool changed = false;
if (cache.IsUnitySerializable == false)
{
isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(isExpanded, label, EditorStyles.foldout);
EditorGUILayout.EndFoldoutHeaderGroup();
if (isExpanded)
{
using (UpIndentLevel())
{
for (int j = 0, jMax = cache.Fields.Length; j < jMax; j++)
{
var field = cache.Fields[j];
if (DrawRuntimeData(ref field, UnityEditorUtility.GetLabel(field.UnityFormatName), expandMatrix, field.FieldInfo.GetValue(data), out object fieldData))
{
field.FieldInfo.SetValue(data, fieldData);
outData = data;
changed = true;
}
}
}
}
}
else
{
Type fieldType = fieldInfoData.FieldType;
if (isUnityObjectType || isUnityObjectField)
{
EditorGUI.BeginChangeCheck();
var uobj = UnsafeUtility.As<object, UnityObject>(ref data);
bool isComponent = typeof(UnityComponent).IsAssignableFrom(fieldType);
if (isComponent)
{
uobj = EditorGUILayout.ObjectField(label, uobj, typeof(UnityObject), true);
}
else
{
uobj = EditorGUILayout.ObjectField(label, uobj, fieldType, true);
}
if (EditorGUI.EndChangeCheck())
{
if (isComponent && uobj is GameObject go)
{
uobj = go.GetComponent(fieldType);
}
outData = uobj;
changed = true;
}
}
else
{
EditorGUI.BeginChangeCheck();
//WrapperBase wrapper = RefEditorWrapper.Take(data);
RefEditorWrapper wrapper = cache.Wrapper;
wrapper.data = data;
wrapper.SO.Update();
wrapper.IsExpanded = isExpanded;
try
{
EditorGUILayout.PropertyField(wrapper.Property, label, true);
}
catch (ArgumentException)
{
if (Event.current.type != EventType.Repaint)
{
throw;
}
}
if (EditorGUI.EndChangeCheck())
{
isExpanded = wrapper.IsExpanded;
wrapper.SO.ApplyModifiedProperties();
outData = wrapper.Data;
changed = true;
}
//wrapper.Release();
}
}
expandMatrix.Up();
return changed;
}
#endregion
}
}
}
#endif

View File

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

View File

@ -0,0 +1,896 @@
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using Unity.Collections.LowLevel.Unsafe;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using Color = UnityEngine.Color;
using Debug = UnityEngine.Debug;
using UnityObject = UnityEngine.Object;
namespace DCFApixels.DragonECS.Unity.Editors
{
internal unsafe static partial class EcsGUI
{
[StructLayout(LayoutKind.Explicit)]
private struct PtrRefUnion
{
[FieldOffset(0)]
public void* Ptr;
[FieldOffset(0)]
public object Ref;
public PtrRefUnion(void* ptr) : this()
{
Ptr = ptr;
}
}
#region Value
private readonly unsafe struct Value
{
public readonly byte* FieldPtr;
public readonly byte* ValuePtr;
public Value(byte* fieldPtr, byte* valuePtr)
{
FieldPtr = fieldPtr;
ValuePtr = valuePtr;
}
public Value Read(in InspectorFieldInfo field)
{
return Read(in this, field.Offset, field.Flag == FieldFlag.Ref);
}
public Value Read(int fieldOffset, bool isRef)
{
return Read(in this, fieldOffset, isRef);
}
public static Value Read(in Value source, in InspectorFieldInfo field)
{
return Read(in source, field.Offset, field.Flag == FieldFlag.Ref);
}
public static Value Read(in Value source, int fieldOffset, bool isRef)
{
byte* fieldPtr = source.ValuePtr + fieldOffset;
byte* valuePtr;
if (isRef)
{
IntPtr* refPtr = (IntPtr*)fieldPtr;
valuePtr = (byte*)&refPtr;
}
else
{
valuePtr = fieldPtr;
}
return new Value(fieldPtr, valuePtr);
}
public ref T AsValue<T>() where T : struct
{
#if DEV_MODE
if (FieldPtr != ValuePtr) { throw new Exception(); }
#endif
return ref UnsafeUtility.AsRef<T>(FieldPtr);
}
public T AsRef<T>() where T : class
{
#if DEV_MODE
if (FieldPtr == ValuePtr) { throw new Exception(); }
#endif
//ref IntPtr p = ref UnsafeUtility.AsRef<IntPtr>(ValuePtr);
//byte* pp = (byte*)p;
//
//Union union = default;
////union.Ptr = ValuePtr; // ValuePtr это какраз и есть реф
//union.Ptr = pp; // ValuePtr это какраз и есть реф
////object result = union.Ref;
//
//object result = UnsafeUtility.As<IntPtr, object>(ref p);
//return (T)result;
PtrRefUnion union = default;
union.Ptr = ValuePtr; // ValuePtr это какраз и есть реф
object result = union.Ref;
return (T)result;
}
public object AsRef()
{
return AsRef<object>();
}
}
#endregion
#region FieldValueProcessor
private abstract class FieldValueProcessor
{
private static readonly Dictionary<Type, FieldValueProcessor> _processors = new Dictionary<Type, FieldValueProcessor>();
private static readonly StructFieldValueProcessor _defaultProcessor = new StructFieldValueProcessor();
static FieldValueProcessor()
{
_processors.Clear();
_defaultProcessor._valueInfo = InspectorTypeInfo.Get(typeof(object));
_processors.Add(typeof(object), _defaultProcessor);
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (var processorType in assembly.GetTypes())
{
if (processorType.IsGenericType == false &&
processorType.IsAbstract == false &&
typeof(FieldValueProcessor).IsAssignableFrom(processorType) &&
processorType != typeof(StructFieldValueProcessor))
{
var processor = (FieldValueProcessor)Activator.CreateInstance(processorType);
processor._valueInfo = InspectorTypeInfo.Get(processor.ProcessedType);
_processors.Add(processor.ProcessedType, processor);
}
}
}
}
public static FieldValueProcessor GetProcessor(Type type)
{
if(type == null)
{
throw new ArgumentNullException("type");
}
if (_processors == null)
{
throw new Exception("_processors == null");
}
if (_processors.TryGetValue(type, out FieldValueProcessor processor) == false)
{
FieldValueProcessor otherProcessor;
if (type.IsValueType)
{
otherProcessor = _defaultProcessor;
}
else
{
otherProcessor = GetProcessor(type.BaseType);
}
processor = (FieldValueProcessor)otherProcessor.MemberwiseClone();
processor._valueInfo = InspectorTypeInfo.Get(type);
_processors.Add(type, processor);
}
return processor;
}
private InspectorTypeInfo _valueInfo;
public InspectorTypeInfo ValueInfo
{
get { return _valueInfo; }
}
public bool IsDefault
{
get { return this == _defaultProcessor; }
}
public abstract Type ProcessedType { get; }
public abstract float GetHeight(in InspectorFieldInfo field, in Value value);
public abstract void Draw(Rect rect, in InspectorFieldInfo field, in Value value);
public override string ToString()
{
if(_valueInfo == null)
{
return "ERROR";
}
return _valueInfo.Type.Name + " " + GetType().Name;
}
}
private class StructFieldValueProcessor : FieldValueProcessor
{
public override Type ProcessedType { get { return typeof(object); } }
public override float GetHeight(in InspectorFieldInfo field, in Value value)
{
float result = GetPropertyHeight(field, ValueInfo, value);
Debug.Log("GetHeight: " + result + " : " + ValueInfo.Type + " : " + ValueInfo.Fields + " : " + ValueInfo.IsNull);
return result;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value value)
{
Debug.Log("Draw: " + ValueInfo.Type + " : " + ValueInfo.Fields + " : " + ValueInfo.IsNull);
DrawProperty(rect, field, ValueInfo, value);
}
}
private class ValueFieldValueProcessor<T> : StructFieldValueProcessor where T : struct
{
public sealed override Type ProcessedType { get { return typeof(T); } }
public sealed override float GetHeight(in InspectorFieldInfo field, in Value value)
{
float result = GetHeight(field, value, ref value.AsValue<T>());
Debug.Log("GetHeight: " + result + " : " + ValueInfo.Type + " : " + ValueInfo.Fields + " : " + ValueInfo.IsNull);
return result;
}
public sealed override void Draw(Rect rect, in InspectorFieldInfo field, in Value value)
{
Debug.Log("Draw: " + ValueInfo.Type + " : " + ValueInfo.Fields + " : " + ValueInfo.IsNull);
Draw(rect, field, value, ref value.AsValue<T>());
}
public virtual float GetHeight(in InspectorFieldInfo field, in Value raw, ref T value)
{
return base.GetHeight(field, raw);
}
public virtual void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, ref T value)
{
base.Draw(rect, field, raw);
}
}
private class RefFieldValueProcessor<T> : StructFieldValueProcessor where T : class
{
public sealed override Type ProcessedType { get { return typeof(T); } }
public sealed override float GetHeight(in InspectorFieldInfo field, in Value value)
{
float result = GetHeight(field, value, value.AsRef<T>());
Debug.Log("GetHeight: " + result + " : " + ValueInfo.Type + " : " + ValueInfo.Fields + " : " + ValueInfo.IsNull);
return result;
}
public sealed override void Draw(Rect rect, in InspectorFieldInfo field, in Value value)
{
Debug.Log("Draw: " + ValueInfo.Type + " : " + ValueInfo.Fields + " : " + ValueInfo.IsNull);
Draw(rect, field, value, value.AsRef<T>());
}
public virtual float GetHeight(in InspectorFieldInfo field, in Value raw, T value)
{
return base.GetHeight(field, raw);
}
public virtual void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, T value)
{
base.Draw(rect, field, raw);
}
}
private unsafe class ArrayFieldValueProcessor : RefFieldValueProcessor<Array>
{
private static readonly int _mappingDataOffset;
static ArrayFieldValueProcessor()
{
Array array = new int[] { 1, 2, 3 };
ulong handle;
byte* ptrObject = (byte*)UnsafeUtility.PinGCObjectAndGetAddress(array, out handle);
UnsafeUtility.ReleaseGCObject(handle);
byte* ptrData = (byte*)UnsafeUtility.PinGCArrayAndGetDataAddress(array, out handle);
UnsafeUtility.ReleaseGCObject(handle);
_mappingDataOffset = (int)(ptrData - ptrObject);
}
private readonly ReorderableList _listDragCache; // сюда попадает _list если было вызвано событие драг енд дропа, а изначальный _listDragCache перемещается в _list
private readonly ReorderableList _list;
public ArrayFieldValueProcessor()
{
//_list.list
}
public override float GetHeight(in InspectorFieldInfo field, in Value raw, Array value)
{
//var elemType = value.GetType().GetElementType();
//int length = value.Length;
//byte* ptr = raw.ValuePtr + _mappingDataOffset;
//
//
//_list.heigh
//
//ReorderableList l = null;
//l.onMouseDragCallback
//
//float result = 0;
//var processor = GetProcessor(elemType);
//for (int i = 0; i < length; i++)
//{
//
//}
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, Array value)
{
//var elemType = value.GetType().GetElementType();
//int length = value.Length;
//byte* ptr = raw.ValuePtr + _mappingDataOffset;
//
EditorGUI.LabelField(rect, UnityEditorUtility.GetLabel(field.Name), "Array Unsupport");
}
}
private class SByteFieldValueProcessor : ValueFieldValueProcessor<sbyte>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, ref sbyte value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, ref sbyte value)
{
value = (sbyte)EditorGUI.IntField(rect, UnityEditorUtility.GetLabel(field.Name), value);
}
}
private class ByteFieldValueProcessor : ValueFieldValueProcessor<byte>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, ref byte value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, ref byte value)
{
value = (byte)EditorGUI.IntField(rect, UnityEditorUtility.GetLabel(field.Name), value);
}
}
private class ShortFieldValueProcessor : ValueFieldValueProcessor<short>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, ref short value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, ref short value)
{
value = (short)EditorGUI.IntField(rect, UnityEditorUtility.GetLabel(field.Name), value);
}
}
private class UShortFieldValueProcessor : ValueFieldValueProcessor<ushort>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, ref ushort value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, ref ushort value)
{
value = (ushort)EditorGUI.IntField(rect, UnityEditorUtility.GetLabel(field.Name), value);
}
}
private class IntFieldValueProcessor : ValueFieldValueProcessor<int>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, ref int value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, ref int value)
{
value = EditorGUI.IntField(rect, UnityEditorUtility.GetLabel(field.Name), value);
}
}
private class UIntFieldValueProcessor : ValueFieldValueProcessor<uint>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, ref uint value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, ref uint value)
{
value = (uint)EditorGUI.LongField(rect, UnityEditorUtility.GetLabel(field.Name), value);
}
}
private class LongFieldValueProcessor : ValueFieldValueProcessor<long>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, ref long value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, ref long value)
{
value = EditorGUI.LongField(rect, UnityEditorUtility.GetLabel(field.Name), value);
}
}
private class ULongFieldValueProcessor : ValueFieldValueProcessor<ulong>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, ref ulong value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, ref ulong value)
{
value = (ulong)EditorGUI.LongField(rect, UnityEditorUtility.GetLabel(field.Name), (long)value);
}
}
private class FloatFieldValueProcessor : ValueFieldValueProcessor<float>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, ref float value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, ref float value)
{
value = EditorGUI.FloatField(rect, UnityEditorUtility.GetLabel(field.Name), (long)value);
}
}
private class DoubleFieldValueProcessor : ValueFieldValueProcessor<double>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, ref double value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, ref double value)
{
value = EditorGUI.DoubleField(rect, UnityEditorUtility.GetLabel(field.Name), (long)value);
}
}
private class CharFieldValueProcessor : ValueFieldValueProcessor<char>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, ref char value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, ref char value)
{
var result = EditorGUI.TextField(rect, UnityEditorUtility.GetLabel(field.Name), value.ToString());
if(result.Length > 0)
{
value = result[0];
}
value = default;
}
}
private class ColorFieldValueProcessor : ValueFieldValueProcessor<Color>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, ref Color value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, ref Color value)
{
value = EditorGUI.ColorField(rect, UnityEditorUtility.GetLabel(field.Name), value);
}
}
private class StringFieldValueProcessor : RefFieldValueProcessor<string>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, string value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, string value)
{
value = EditorGUI.TextField(rect, UnityEditorUtility.GetLabel(field.Name), value);
}
}
private class GradientFieldValueProcessor : RefFieldValueProcessor<Gradient>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, Gradient value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, Gradient value)
{
value = EditorGUI.GradientField(rect, UnityEditorUtility.GetLabel(field.Name), value);
}
}
private class CurveFieldValueProcessor : RefFieldValueProcessor<AnimationCurve>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, AnimationCurve value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, AnimationCurve value)
{
value = EditorGUI.CurveField(rect, UnityEditorUtility.GetLabel(field.Name), value);
}
}
private class UnityObjectFieldValueProcessor : RefFieldValueProcessor<UnityObject>
{
public override float GetHeight(in InspectorFieldInfo field, in Value raw, UnityObject value)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
public override void Draw(Rect rect, in InspectorFieldInfo field, in Value raw, UnityObject value)
{
value = EditorGUI.ObjectField(rect, UnityEditorUtility.GetLabel(field.Name), value, ValueInfo.Type, true);
}
}
#endregion
#region InspectorTypeInfo
private class InspectorTypeInfo
{
#region cahce
private static Dictionary<Type, InspectorTypeInfo> _typeInfosCache = new Dictionary<Type, InspectorTypeInfo>();
static InspectorTypeInfo()
{
_typeInfosCache.Clear();
}
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
private struct FakeNull { }
public static readonly InspectorTypeInfo PtrTypeInfo = new InspectorTypeInfo(typeof(IntPtr));
public static readonly InspectorTypeInfo NullTypeInfo = new InspectorTypeInfo(typeof(FakeNull));
public readonly Type Type;
//public readonly int Size;
public readonly InspectorFieldInfo[] Fields;
//public readonly float DefaultInspectorHegiht;
public readonly bool IsVector;
public readonly bool IsColor;
public bool IsNull
{
get { return this == NullTypeInfo; }
}
public bool IsPrt
{
get { return this == PtrTypeInfo; }
}
#region Constructors
//private static StructList<InspectorFieldInfo> CnstrBuffer = new StructList<InspectorFieldInfo>(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)
{
StructList<InspectorFieldInfo> CnstrBuffer = new StructList<InspectorFieldInfo>(32);
//if (CnstrBuffer.IsNull)
//{
// CnstrBuffer = new StructList<InspectorFieldInfo>(32);
//}
CnstrBuffer.FastClear();
Type = type;
//Size = UnsafeUtility.SizeOf(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.Name = UnityEditorUtility.TransformFieldName(fieldType.Name);
infocstr.Flag = FieldFlagUtitlity.GetFieldFlag(fieldType);
Debug.LogWarning("Offset: " + type.Name + "." + infocstr.Name + "." + infocstr.Offset);
if (infocstr.Flag == FieldFlag.Struct)
{
infocstr.PreDefinedType = Get(fieldType);
}
else if (infocstr.Flag == FieldFlag.Ref)
{
infocstr.PreDefinedType = PtrTypeInfo;
}
else
{
infocstr.PreDefinedType = NullTypeInfo;
}
CnstrBuffer.Add(infoUniton.Result);
}
Fields = CnstrBuffer.Enumerable.ToArray();
Array.Sort(Fields);
int length = Fields.Length;
if (length >= 2 && length <= 3)
{
bool isCheck = true;
for (int i = 0; i < length; i++)
{
ref var field = ref Fields[i];
if (field.Flag == FieldFlag.Leaf &&
field.PreDefinedType.Type.IsPrimitive &&
char.ToLower(field.Name[0]) != VectorFields[i])
{
isCheck = false;
break;
}
}
if (isCheck)
{
IsVector = true;
}
else
{
isCheck = true;
for (int i = 0; i < length; i++)
{
ref var field = ref Fields[i];
if (field.Flag == FieldFlag.Leaf &&
field.PreDefinedType.Type.IsPrimitive &&
char.ToLower(field.Name[0]) != ColorFields[i])
{
isCheck = false;
break;
}
}
if (isCheck)
{
IsColor = true;
}
}
}
}
#endregion
public override string ToString()
{
return Type.Name;
}
}
#endregion
#region InspectorFieldInfo
[StructLayout(LayoutKind.Sequential)]
private unsafe readonly struct InspectorFieldInfo : IEquatable<InspectorFieldInfo>, IComparable<InspectorFieldInfo>
{
public readonly FieldInfo FieldInfo;
public readonly InspectorTypeInfo PreDefinedType;
public readonly string Name;
public readonly int Offset;
public readonly FieldFlag Flag;
public int CompareTo(InspectorFieldInfo other)
{
return other.Offset - Offset;
}
public bool Equals(InspectorFieldInfo other)
{
return EqualityComparer<InspectorFieldInfo>.Default.Equals(this, other);
}
[StructLayout(LayoutKind.Sequential)]
public unsafe struct Constructor
{
public FieldInfo FieldInfo;
public InspectorTypeInfo PreDefinedType;
public string Name;
public int Offset;
public FieldFlag Flag;
public override string ToString() { return Name; }
}
[StructLayout(LayoutKind.Explicit)]
public struct Union
{
[FieldOffset(0)]
public Constructor Constructor;
[FieldOffset(0)]
public InspectorFieldInfo Result;
}
public override string ToString() { return Name; }
}
private static class FieldFlagUtitlity
{
private static readonly HashSet<Type> _cantDisplayedTypes = new HashSet<Type>()
{
typeof(IntPtr),
typeof(UIntPtr),
};
private static readonly HashSet<Type> _leafTypes = new HashSet<Type>()
{
typeof(string),
typeof(AnimationCurve),
typeof(Gradient),
typeof(LayerMask),
typeof(Color),
};
public static FieldFlag GetFieldFlag(Type fieldType)
{
if (fieldType.IsPointer || _cantDisplayedTypes.Contains(fieldType))
{
return FieldFlag.CantDisplayed;
}
if (fieldType.IsClass || fieldType.IsInterface)
{
return FieldFlag.Ref;
}
if (fieldType.IsPrimitive || fieldType.IsEnum || _leafTypes.Contains(fieldType))
{
return FieldFlag.Leaf;
}
return FieldFlag.Struct;
}
public static bool IsValueField(FieldFlag flag)
{
return flag == FieldFlag.Leaf || flag == FieldFlag.Struct;
}
public static bool IsCanDisplayed(FieldFlag flag)
{
return flag != FieldFlag.None && flag != FieldFlag.CantDisplayed;
}
}
private enum FieldFlag : byte
{
None = 0,
CantDisplayed,
Leaf,
Struct,
Ref,
}
private unsafe static bool FastDrawRuntimeData(void* data, InspectorTypeInfo cache)
{
throw new NotImplementedException();
}
#endregion
private static void DrawProperty(Rect rect, in InspectorFieldInfo field, InspectorTypeInfo valueInfo, in Value value)
{
if (field.Flag == FieldFlag.Leaf)
{
EditorGUI.LabelField(rect, UnityEditorUtility.GetLabel(field.Name));
return;
}
float y = rect.y;
float height = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
Rect subRect = rect;
subRect.y = y;
subRect.height = height - EditorGUIUtility.standardVerticalSpacing;
y += height;
EditorGUI.LabelField(subRect, field.Name);
using (UpIndentLevel())
{
foreach (var subField in valueInfo.Fields)
{
if (FieldFlagUtitlity.IsCanDisplayed(subField.Flag) == false) { continue; }
var subValue = value.Read(subField);
Type subValueType;
switch (subField.Flag)
{
case FieldFlag.Leaf:
case FieldFlag.Struct:
subValueType = subField.PreDefinedType.Type;
break;
case FieldFlag.Ref:
var obj = subValue.AsRef();
subValueType = obj.GetType();
break;
case FieldFlag.None:
case FieldFlag.CantDisplayed:
default:
subValueType = null;
break;
}
if (subValueType == null) { continue; }
var processor = FieldValueProcessor.GetProcessor(subValueType);
height = processor.GetHeight(subField, subValue);
subRect = rect;
subRect.y = y;
subRect.height = height - EditorGUIUtility.standardVerticalSpacing;
y += height;
if (subField.Flag == FieldFlag.Struct && processor.IsDefault)
{
if (subField.PreDefinedType.IsVector)
{
float defLabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 14f;
subRect.xMin += EditorGUIUtility.labelWidth;
var vectorFields = subField.PreDefinedType.Fields;
var widthOne = subRect.width / vectorFields.Length;
foreach (var vectorField in vectorFields)
{
var vectorFieldProcessor = FieldValueProcessor.GetProcessor(vectorField.PreDefinedType.Type);
vectorFieldProcessor.Draw(subRect, vectorField, subValue.Read(vectorField));
}
EditorGUIUtility.labelWidth = defLabelWidth;
}
//else if (subField.PreDefinedType.IsColor)
//{
// EditorGUI.ColorField(subRect, );
//}
}
processor.Draw(subRect, subField, subValue);
}
}
}
private static float GetPropertyHeight(in InspectorFieldInfo field, InspectorTypeInfo valueInfo, in Value value)
{
float result = 0;
if (field.Flag == FieldFlag.Leaf)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
Debug.Log(string.Join("\r\n", valueInfo.Fields));
foreach (var subField in valueInfo.Fields)
{
if (FieldFlagUtitlity.IsCanDisplayed(subField.Flag) == false) { continue; }
var subValue = value.Read(subField);
Type subValueType;
switch (subField.Flag)
{
case FieldFlag.None:
case FieldFlag.CantDisplayed:
default:
subValueType = null;
break;
case FieldFlag.Leaf:
case FieldFlag.Struct:
subValueType = subField.PreDefinedType.Type;
break;
case FieldFlag.Ref:
var obj = subValue.AsRef();
subValueType = obj.GetType();
break;
}
if (subValueType == null) { continue; }
var processor = FieldValueProcessor.GetProcessor(subValueType);
if (subField.Flag == FieldFlag.Struct && processor.IsDefault)
{
if (subField.PreDefinedType.IsVector)
//if (subField.PreDefinedType.IsVector || subField.PreDefinedType.IsColor)
{
return EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
}
}
result += EditorGUIUtility.currentViewWidth + EditorGUIUtility.standardVerticalSpacing;
result += processor.GetHeight(subField, subValue);
}
return result;
}
public static unsafe partial class Layout
{
private static bool DrawProperty(object data)
{
Debug.LogWarning("--------------------------------------------");
EditorGUI.BeginChangeCheck();
Type type = data.GetType();
byte* ptr = (byte*)UnsafeUtility.PinGCObjectAndGetAddress(data, out ulong gcHandle);
try
{
InspectorTypeInfo inspectorTypeInfo = InspectorTypeInfo.Get(type);
Value value = new Value(null, ptr);
#if DEV_MODE
if (data is GameObjectConnect goc)
{
byte* ptrX = (byte*)UnsafeUtility.PinGCObjectAndGetAddress(goc.Connect, out ulong gcHandleX);
UnsafeUtility.ReleaseGCObject(gcHandleX);
var fieldX = inspectorTypeInfo.Fields[0];
Value valueX = value.Read(fieldX);
byte* ptrX2 = valueX.ValuePtr;
PtrRefUnion u = default;
u.Ref = goc.Connect;
Debug.Log((IntPtr)ptrX + " " + (IntPtr)ptrX2);
}
#endif
InspectorFieldInfo f = default;
float h = GetPropertyHeight(in f, inspectorTypeInfo, in value);
var r = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, h);
EcsGUI.DrawProperty(r, in f, inspectorTypeInfo, in value);
UnsafeUtility.ReleaseGCObject(gcHandle);
}
catch (Exception)
{
UnsafeUtility.ReleaseGCObject(gcHandle);
throw;
}
return EditorGUI.EndChangeCheck();
}
}
}
}

View File

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

View File

@ -2,18 +2,11 @@
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;
using UnityEngine;
using Color = UnityEngine.Color;
using UnityComponent = UnityEngine.Component;
using UnityObject = UnityEngine.Object;
namespace DCFApixels.DragonECS.Unity.Editors
{
@ -24,7 +17,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
private static bool _changed = false;
private static bool _delayedChanged = false;
public static int ChangedCounter => _changedCounter;
public static int ChangedCounter
{
get { return _changedCounter; }
}
public static bool Changed
{
get
@ -275,6 +271,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
public static float EntityBarHeight => EditorGUIUtility.singleLineHeight + 3f;
private static float indent => (float)EditorGUI.indentLevel * 15f;
private static float indentLevel => EditorGUI.indentLevel;
#region Properties
private static ComponentColorMode AutoColorMode
@ -292,6 +289,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
get { return UserSettingsPrefs.instance.IsShowRuntimeComponents; }
set { UserSettingsPrefs.instance.IsShowRuntimeComponents = value; }
}
private static bool IsFastModeRuntimeComponents
{
get { return UserSettingsPrefs.instance.IsFastModeRuntimeComponents; }
set { UserSettingsPrefs.instance.IsFastModeRuntimeComponents = value; }
}
private static float OneLineHeight
{
get => EditorGUIUtility.singleLineHeight;
@ -1009,766 +1011,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
_currentProperty = property;
GetReferenceDropDown(sortedPredicateTypes, sortedWithOutTypes).Show(position);
}
#endregion
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static partial class Layout
{
public static void ScriptAssetButton(MonoScript script, params GUILayoutOption[] options)
{
EcsGUI.ScriptAssetButton(GUILayoutUtility.GetRect(UnityEditorUtility.GetLabelTemp(), EditorStyles.miniButton, options), script);
}
public static void CopyMetaIDButton(string metaID, params GUILayoutOption[] options)
{
Rect r = GUILayoutUtility.GetRect(UnityEditorUtility.GetLabelTemp(), EditorStyles.miniButton, options);
var current = Event.current;
var hover = IconHoverScan(r, current);
using (new ColorScope(new Color(1f, 1f, 1f, hover ? 1f : 0.8f)))
{
DrawIcon(r, Icons.Instance.MetaIDIcon, hover ? 1f : 2f, metaID);
if (hover && current.type == EventType.MouseUp)
{
GUIUtility.systemCopyBuffer = metaID;
}
}
}
public static bool IconButton(Texture icon, params GUILayoutOption[] options)
{
bool result = GUILayout.Button(UnityEditorUtility.GetLabel(string.Empty), options);
DrawIcon(GUILayoutUtility.GetLastRect(), icon, 0, null);
return result;
}
public static bool IconButton(Texture icon, float iconPadding = 0, string description = null)
{
bool result = GUILayout.Button(UnityEditorUtility.GetLabel(string.Empty));
DrawIcon(GUILayoutUtility.GetLastRect(), icon, iconPadding, description);
return result;
}
public static bool IconButton(Texture icon, float iconPadding = 0, string description = null, GUIStyle style = null, params GUILayoutOption[] options)
{
bool result;
if (style == null)
{
result = GUILayout.Button(UnityEditorUtility.GetLabel(string.Empty), options);
}
else
{
result = GUILayout.Button(UnityEditorUtility.GetLabel(string.Empty), style, options);
}
DrawIcon(GUILayoutUtility.GetLastRect(), icon, iconPadding, description);
return result;
}
public static void DrawEmptyComponentProperty(SerializedProperty property, string name, bool isDisplayEmpty)
{
EcsGUI.DrawEmptyComponentProperty(GUILayoutUtility.GetRect(UnityEditorUtility.GetLabel(name), EditorStyles.label), property, name, isDisplayEmpty);
}
public static void DrawEmptyComponentProperty(SerializedProperty property, GUIContent label, bool isDisplayEmpty)
{
EcsGUI.DrawEmptyComponentProperty(GUILayoutUtility.GetRect(label, EditorStyles.label), property, label, isDisplayEmpty);
}
public static void DrawWorldBaseInfo(EcsWorld world)
{
bool isNull = world == null || world.IsDestroyed || world.ID == 0;
int entitesCount = isNull ? 0 : world.Count;
int capacity = isNull ? 0 : world.Capacity;
long Version = isNull ? 0 : world.Version;
int leakedEntitesCount = isNull ? 0 : world.CountLeakedEntitesDebug();
EditorGUILayout.IntField("Entities", entitesCount, EditorStyles.boldLabel);
EditorGUILayout.IntField("Capacity", capacity, EditorStyles.boldLabel);
EditorGUILayout.LongField("Version", Version, EditorStyles.boldLabel);
Color color = leakedEntitesCount > 0 ? Color.yellow : GUI.contentColor;
using (new ContentColorScope(color))
{
EditorGUILayout.IntField("Leaked Entites", leakedEntitesCount, EditorStyles.boldLabel);
}
}
public static void DrawWorldComponents(EcsWorld world)
{
bool isNull = world == null || world.IsDestroyed || world.ID == 0;
if (isNull) { return; }
using (BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)))
{
IsShowRuntimeComponents = EditorGUILayout.BeginFoldoutHeaderGroup(IsShowRuntimeComponents, "RUNTIME COMPONENTS", EditorStyles.foldout);
EditorGUILayout.EndFoldoutHeaderGroup();
if (IsShowRuntimeComponents == false) { return; }
var worldID = world.ID;
var cmps = world.GetWorldComponents();
int index = -1;
int total = 9;
foreach (var cmp in cmps)
{
index++;
var meta = cmp.ComponentType.ToMeta();
if (meta.IsHidden == false || IsShowHidden)
{
Type componentType = cmp.ComponentType;
object data = cmp.GetRaw(worldID);
ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType);
float padding = EditorGUIUtility.standardVerticalSpacing;
Rect optionButton = GUILayoutUtility.GetLastRect();
optionButton.yMin = optionButton.yMax;
optionButton.yMax += HeadIconsRect.height;
optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * padding * 2f;
//Canceling isExpanded
if (ClickTest(optionButton))
{
ref bool isExpanded = ref expandMatrix.Down();
isExpanded = !isExpanded;
}
Color panelColor = SelectPanelColor(meta, index, total);
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(panelColor, EscEditorConsts.COMPONENT_DRAWER_ALPHA));
EditorGUI.BeginChangeCheck();
////Close button
//optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
//if (CloseButton(optionButton))
//{
// cmp.Del(worldID);
// return;
//}
//Edit script button
if (ScriptsCache.TryGetScriptAsset(meta, out MonoScript script))
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
EcsGUI.ScriptAssetButton(optionButton, script);
}
//Description icon
if (string.IsNullOrEmpty(meta.Description.Text) == false)
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
DescriptionIcon(optionButton, meta.Description.Text);
}
RuntimeComponentReflectionCache.FieldInfoData componentInfoData = new RuntimeComponentReflectionCache.FieldInfoData(null, componentType, meta.Name);
if (DrawRuntimeData(ref componentInfoData, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData))
{
cmp.SetRaw(worldID, resultData);
}
GUILayout.EndVertical();
}
}
}
}
#region entity bar
public static void EntityBarForAlive(EntityStatus status, int id, short gen, short world)
{
float width = EditorGUIUtility.currentViewWidth;
float height = EntityBarHeight;
EcsGUI.EntityBarForAlive(GUILayoutUtility.GetRect(width, height), status, id, gen, world);
}
public static void EntityBar(EntityStatus status, bool isPlaceholder, int id, short gen, short world)
{
float width = EditorGUIUtility.currentViewWidth;
float height = EntityBarHeight;
EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height), isPlaceholder, status, id, gen, world);
}
public static void EntityBar(int id, short gen, short world)
{
float width = EditorGUIUtility.currentViewWidth;
float height = EntityBarHeight;
EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height), id, gen, world);
}
public static void EntityBar()
{
float width = EditorGUIUtility.currentViewWidth;
float height = EntityBarHeight;
EcsGUI.EntityBar(GUILayoutUtility.GetRect(width, height));
}
#endregion
public static bool AddComponentButtons(out Rect dropDownRect)
{
return EcsGUI.AddComponentButton(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 24f), out dropDownRect);
}
public static AddClearButton AddClearComponentButtons(out Rect dropDownRect)
{
return EcsGUI.AddClearComponentButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 24f), out dropDownRect);
}
public static AddClearButton AddClearSystemButtons(out Rect dropDownRect)
{
return EcsGUI.AddClearSystemButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 24f), out dropDownRect);
}
public static void DrawRuntimeComponents(entlong entity, bool isWithFoldout = true)
{
if (entity.TryUnpackForUnityEditor(out int entityID, out _, out _, out EcsWorld world))
{
DrawRuntimeComponents(entityID, world, isWithFoldout);
}
}
[ThreadStatic]
private static List<IEcsPool> _componentPoolsBuffer;
public static void DrawRuntimeComponents(int entityID, EcsWorld world, bool isWithFoldout = true)
{
using (BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)))
{
if (isWithFoldout)
{
IsShowRuntimeComponents = EditorGUILayout.BeginFoldoutHeaderGroup(IsShowRuntimeComponents, "RUNTIME COMPONENTS", EditorStyles.foldout);
EditorGUILayout.EndFoldoutHeaderGroup();
}
if (isWithFoldout == false || IsShowRuntimeComponents)
{
if (AddComponentButtons(out Rect dropDownRect))
{
RuntimeComponentsUtility.GetAddComponentGenericMenu(world).Open(dropDownRect, entityID);
}
GUILayout.Box("", UnityEditorUtility.GetStyle(GUI.color, 0.16f), GUILayout.ExpandWidth(true));
IsShowHidden = EditorGUI.Toggle(GUILayoutUtility.GetLastRect(), "Show Hidden", IsShowHidden);
if (_componentPoolsBuffer == null)
{
_componentPoolsBuffer = new List<IEcsPool>(64);
}
world.GetComponentPoolsFor(entityID, _componentPoolsBuffer);
int i = 0;
//int iMax = _componentPoolsBuffer.Count;
foreach (var componentPool in _componentPoolsBuffer)
{
DrawRuntimeComponent(entityID, componentPool, 9, i++);
}
}
}
}
private static void DrawRuntimeComponent(int entityID, IEcsPool pool, int total, int index)
{
var meta = pool.ComponentType.ToMeta();
if (meta.IsHidden == false || IsShowHidden)
{
Type componentType = pool.ComponentType;
object data = pool.GetRaw(entityID);
ExpandMatrix expandMatrix = ExpandMatrix.Take(componentType);
float padding = EditorGUIUtility.standardVerticalSpacing;
Rect optionButton = GUILayoutUtility.GetLastRect();
optionButton.yMin = optionButton.yMax;
optionButton.yMax += HeadIconsRect.height;
optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * padding * 2f;
//Canceling isExpanded
if (ClickTest(optionButton))
{
ref bool isExpanded = ref expandMatrix.Down();
isExpanded = !isExpanded;
}
Color panelColor = SelectPanelColor(meta, index, total);
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(panelColor, EscEditorConsts.COMPONENT_DRAWER_ALPHA));
EditorGUI.BeginChangeCheck();
//Close button
optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
if (CloseButton(optionButton))
{
pool.Del(entityID);
return;
}
//Edit script button
if (ScriptsCache.TryGetScriptAsset(meta, out MonoScript script))
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
EcsGUI.ScriptAssetButton(optionButton, script);
}
//Description icon
if (string.IsNullOrEmpty(meta.Description.Text) == false)
{
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
DescriptionIcon(optionButton, meta.Description.Text);
}
RuntimeComponentReflectionCache.FieldInfoData componentInfoData = new RuntimeComponentReflectionCache.FieldInfoData(null, componentType, meta.Name);
if (DrawRuntimeData(ref componentInfoData, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData))
{
pool.SetRaw(entityID, resultData);
}
GUILayout.EndVertical();
}
}
#region Default DrawRuntimeData
[InitializeOnLoadMethod]
private static void ResetRuntimeComponentReflectionCache()
{
_runtimeComponentReflectionCaches.Clear();
}
internal class RuntimeComponentReflectionCache
{
public readonly Type Type;
public readonly bool IsUnityObjectType;
public readonly bool IsUnitySerializable;
public readonly bool IsUnmanaged;
public readonly FieldInfoData[] Fields;
public readonly RefEditorWrapper Wrapper;
public RuntimeComponentReflectionCache(Type type)
{
Type = type;
IsUnmanaged = UnsafeUtility.IsUnmanaged(type);
IsUnityObjectType = typeof(UnityObject).IsAssignableFrom(type);
IsUnitySerializable = IsUnityObjectType || (!type.IsGenericType && type.IsSerializable);
Wrapper = RefEditorWrapper.Take();
if (type == typeof(void)) { return; }
if (IsUnitySerializable == false)
{
var fs = type.GetFields(fieldFlags);
Fields = new FieldInfoData[fs.Length];
for (int i = 0; i < fs.Length; i++)
{
var f = fs[i];
Fields[i] = new FieldInfoData(f);
}
}
}
public readonly struct FieldInfoData
{
public readonly FieldInfo FieldInfo;
public readonly Type FieldType;
public readonly string UnityFormatName;
public readonly bool IsUnityObjectField;
public FieldInfoData(FieldInfo fieldInfo)
{
FieldInfo = fieldInfo;
FieldType = fieldInfo.FieldType;
IsUnityObjectField = typeof(UnityObject).IsAssignableFrom(fieldInfo.FieldType);
UnityFormatName = UnityEditorUtility.TransformFieldName(fieldInfo.Name);
}
public FieldInfoData(FieldInfo fieldInfo, Type fieldType, string unityFormatName)
{
FieldInfo = fieldInfo;
FieldType = fieldType;
UnityFormatName = unityFormatName;
IsUnityObjectField = typeof(UnityObject).IsAssignableFrom(fieldType);
}
}
}
private static Dictionary<Type, RuntimeComponentReflectionCache> _runtimeComponentReflectionCaches = new Dictionary<Type, RuntimeComponentReflectionCache>();
private static RuntimeComponentReflectionCache GetRuntimeComponentReflectionCache(Type type)
{
if (_runtimeComponentReflectionCaches.TryGetValue(type, out RuntimeComponentReflectionCache result) == false)
{
result = new RuntimeComponentReflectionCache(type);
_runtimeComponentReflectionCaches.Add(type, result);
}
return result;
}
private static bool DrawRuntimeData(ref RuntimeComponentReflectionCache.FieldInfoData fieldInfoData, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData)
{
outData = data;
Type type = data == null ? typeof(void) : data.GetType();
RuntimeComponentReflectionCache cache = GetRuntimeComponentReflectionCache(type);
bool isUnityObjectField = fieldInfoData.IsUnityObjectField;
if (isUnityObjectField == false && data == null)
{
EditorGUILayout.TextField(label, "Null");
return false;
}
bool isUnityObjectType = cache.IsUnityObjectType;
ref bool isExpanded = ref expandMatrix.Down();
bool changed = false;
if (cache.IsUnitySerializable == false)
{
isExpanded = EditorGUILayout.BeginFoldoutHeaderGroup(isExpanded, label, EditorStyles.foldout);
EditorGUILayout.EndFoldoutHeaderGroup();
if (isExpanded)
{
using (UpIndentLevel())
{
for (int j = 0, jMax = cache.Fields.Length; j < jMax; j++)
{
var field = cache.Fields[j];
if (DrawRuntimeData(ref field, UnityEditorUtility.GetLabel(field.UnityFormatName), expandMatrix, field.FieldInfo.GetValue(data), out object fieldData))
{
field.FieldInfo.SetValue(data, fieldData);
outData = data;
changed = true;
}
}
}
}
}
else
{
Type fieldType = fieldInfoData.FieldType;
if (isUnityObjectType || isUnityObjectField)
{
EditorGUI.BeginChangeCheck();
var uobj = UnsafeUtility.As<object, UnityObject>(ref data);
bool isComponent = typeof(UnityComponent).IsAssignableFrom(fieldType);
if (isComponent)
{
uobj = EditorGUILayout.ObjectField(label, uobj, typeof(UnityObject), true);
}
else
{
uobj = EditorGUILayout.ObjectField(label, uobj, fieldType, true);
}
if (EditorGUI.EndChangeCheck())
{
if (isComponent && uobj is GameObject go)
{
uobj = go.GetComponent(fieldType);
}
outData = uobj;
changed = true;
}
}
else
{
EditorGUI.BeginChangeCheck();
//WrapperBase wrapper = RefEditorWrapper.Take(data);
RefEditorWrapper wrapper = cache.Wrapper;
wrapper.data = data;
wrapper.SO.Update();
wrapper.IsExpanded = isExpanded;
try
{
EditorGUILayout.PropertyField(wrapper.Property, label, true);
}
catch (ArgumentException)
{
if (Event.current.type != EventType.Repaint)
{
throw;
}
}
if (EditorGUI.EndChangeCheck())
{
isExpanded = wrapper.IsExpanded;
wrapper.SO.ApplyModifiedProperties();
outData = wrapper.Data;
changed = true;
}
//wrapper.Release();
}
}
expandMatrix.Up();
return changed;
}
#endregion
#region FactMode DrawRuntimeData
private class InspectorTypeInfo
{
#region cahce
private static Dictionary<Type, InspectorTypeInfo> _typeInfosCache = new Dictionary<Type, InspectorTypeInfo>();
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<InspectorFieldInfo> CnstrBuffer = new StructList<InspectorFieldInfo>(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<InspectorFieldInfo>, IComparable<InspectorFieldInfo>
{
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<InspectorFieldInfo>.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
}
#endregion
}
}
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,122 +0,0 @@
fileFormatVersion: 2
guid: f6905846bdee2584393b2583d00d10f3
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,122 +0,0 @@
fileFormatVersion: 2
guid: f1fe20f167697834b815161036625d65
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -11,6 +11,22 @@ namespace DCFApixels.DragonECS.Unity.Internal
{
internal T[] _items;
internal int _count;
public IEnumerable<T> Enumerable
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _items.Take(_count); }
}
public bool IsNull
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _items == null; }
}
public bool IsNullOrEmpty
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _items == null || _items.Length <= 0; }
}
public int Count
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]