mirror of
https://github.com/DCFApixels/DragonECS-Unity.git
synced 2026-04-22 04:35:55 +08:00
stash
This commit is contained in:
parent
0aaffd0240
commit
f1666d2fcb
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
502
src/Internal/Editor/EcsGUI.Layout.cs
Normal file
502
src/Internal/Editor/EcsGUI.Layout.cs
Normal 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
|
||||
11
src/Internal/Editor/EcsGUI.Layout.cs.meta
Normal file
11
src/Internal/Editor/EcsGUI.Layout.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7a7468927b696e4899e73de0866d947
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
896
src/Internal/Editor/EcsGUI.RuntimeCumponents.cs
Normal file
896
src/Internal/Editor/EcsGUI.RuntimeCumponents.cs
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
11
src/Internal/Editor/EcsGUI.RuntimeCumponents.cs.meta
Normal file
11
src/Internal/Editor/EcsGUI.RuntimeCumponents.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b50e8a16e06a37438743ce90a39f93d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -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 |
@ -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 |
@ -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:
|
||||
@ -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)]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user