mirror of
https://github.com/DCFApixels/DragonECS-Unity.git
synced 2025-09-17 17:34:34 +08:00
remove unsafe runtime components
This commit is contained in:
parent
8a2200982b
commit
d7c50a011b
@ -69,9 +69,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsUseCustomNames)),
|
||||
prefs.IsUseCustomNames);
|
||||
|
||||
prefs.IsFastModeRuntimeComponents = EditorGUILayout.ToggleLeft(
|
||||
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsFastModeRuntimeComponents)),
|
||||
prefs.IsFastModeRuntimeComponents);
|
||||
//prefs.IsFastModeRuntimeComponents = EditorGUILayout.ToggleLeft(
|
||||
// UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsFastModeRuntimeComponents)),
|
||||
// prefs.IsFastModeRuntimeComponents);
|
||||
|
||||
prefs.ComponentColorMode = (ComponentColorMode)EditorGUILayout.EnumPopup(UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.ComponentColorMode)), prefs.ComponentColorMode);
|
||||
}
|
||||
|
@ -69,31 +69,18 @@ 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;
|
||||
//public bool PoolsToggle
|
||||
//private bool _isFastModeRuntimeComponents = false;
|
||||
//public bool IsFastModeRuntimeComponents
|
||||
//{
|
||||
// get => _poolsToggle;
|
||||
// get => _isFastModeRuntimeComponents;
|
||||
// set
|
||||
// {
|
||||
// _isChanged = _poolsToggle != value;
|
||||
// _poolsToggle = value;
|
||||
// AutoSave();
|
||||
// if (_isFastModeRuntimeComponents != value)
|
||||
// {
|
||||
// _isFastModeRuntimeComponents = value;
|
||||
// AutoSave();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
@ -295,21 +295,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
|
||||
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))
|
||||
{
|
||||
if (DrawRuntimeData(ref componentInfoData, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData))
|
||||
{
|
||||
pool.SetRaw(entityID, resultData);
|
||||
}
|
||||
pool.SetRaw(entityID, resultData);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DrawProperty(data, meta.Name))
|
||||
{
|
||||
pool.SetRaw(entityID, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
@ -1,874 +0,0 @@
|
||||
using DCFApixels.DragonECS.Unity.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Xml.Schema;
|
||||
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 byte* Ptr;
|
||||
[FieldOffset(0)]
|
||||
public object Ref;
|
||||
public PtrRefUnion(byte* 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[0]);
|
||||
}
|
||||
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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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.singleLineHeight + 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(fieldInfo.Name);
|
||||
infocstr.Flag = FieldFlagUtitlity.GetFieldFlag(fieldType);
|
||||
|
||||
if (infocstr.Flag == FieldFlag.StructValue)
|
||||
{
|
||||
infocstr.PreDefinedType = Get(fieldType);
|
||||
}
|
||||
else if (infocstr.Flag == FieldFlag.Ref)
|
||||
{
|
||||
infocstr.PreDefinedType = PtrTypeInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type == infocstr.FieldInfo.FieldType)
|
||||
{
|
||||
infocstr.PreDefinedType = NullTypeInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
infocstr.PreDefinedType = Get(fieldType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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.LeafValue &&
|
||||
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.LeafValue &&
|
||||
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 Offset - other.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.LeafValue;
|
||||
}
|
||||
return FieldFlag.StructValue;
|
||||
}
|
||||
public static bool IsValueField(FieldFlag flag)
|
||||
{
|
||||
return flag == FieldFlag.LeafValue || flag == FieldFlag.StructValue;
|
||||
}
|
||||
public static bool IsCanDisplayed(FieldFlag flag)
|
||||
{
|
||||
return flag != FieldFlag.None && flag != FieldFlag.CantDisplayed;
|
||||
}
|
||||
}
|
||||
private enum FieldFlag : byte
|
||||
{
|
||||
None = 0,
|
||||
CantDisplayed,
|
||||
LeafValue,
|
||||
StructValue,
|
||||
Ref,
|
||||
}
|
||||
#endregion
|
||||
|
||||
private static void DrawProperty(Rect rect, in InspectorFieldInfo field, InspectorTypeInfo valueInfo, in Value value)
|
||||
{
|
||||
//if (field.Flag == FieldFlag.LeafValue)
|
||||
//{
|
||||
// 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.LeafValue:
|
||||
case FieldFlag.StructValue:
|
||||
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.StructValue && 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.LeafValue)
|
||||
//{
|
||||
// return EditorGUIUtility.singleLineHeight + 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 = null;
|
||||
|
||||
switch (subField.Flag)
|
||||
{
|
||||
case FieldFlag.LeafValue:
|
||||
case FieldFlag.StructValue:
|
||||
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.StructValue && processor.IsDefault)
|
||||
{
|
||||
if (subField.PreDefinedType.IsVector)
|
||||
//if (subField.PreDefinedType.IsVector || subField.PreDefinedType.IsColor)
|
||||
{
|
||||
return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
}
|
||||
result += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
result += processor.GetHeight(subField, subValue);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static unsafe partial class Layout
|
||||
{
|
||||
private static bool DrawProperty(object data, string name)
|
||||
{
|
||||
//Debug.LogWarning("--------------------------------------------");
|
||||
EditorGUI.BeginChangeCheck();
|
||||
Type type = data.GetType();
|
||||
byte* ptr = (byte*)UnsafeUtility.PinGCObjectAndGetAddress(data, out ulong gcHandle);
|
||||
ptr += sizeof(IntPtr) * 2; //TODO тут надо просчитать что констатно ли значение смещения для упакованных данных
|
||||
try
|
||||
{
|
||||
InspectorTypeInfo inspectorTypeInfo = InspectorTypeInfo.Get(type);
|
||||
Value value = new Value(ptr, ptr);
|
||||
|
||||
InspectorFieldInfo.Union f = default;
|
||||
f.Constructor.Name = name;
|
||||
float h = GetPropertyHeight(in f.Result, inspectorTypeInfo, in value);
|
||||
var r = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, h);
|
||||
EcsGUI.DrawProperty(r, in f.Result, inspectorTypeInfo, in value);
|
||||
|
||||
|
||||
UnsafeUtility.ReleaseGCObject(gcHandle);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
UnsafeUtility.ReleaseGCObject(gcHandle);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
||||
return EditorGUI.EndChangeCheck();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b50e8a16e06a37438743ce90a39f93d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -289,11 +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 bool IsFastModeRuntimeComponents
|
||||
//{
|
||||
// get { return UserSettingsPrefs.instance.IsFastModeRuntimeComponents; }
|
||||
// set { UserSettingsPrefs.instance.IsFastModeRuntimeComponents = value; }
|
||||
//}
|
||||
private static float OneLineHeight
|
||||
{
|
||||
get => EditorGUIUtility.singleLineHeight;
|
||||
|
Loading…
Reference in New Issue
Block a user