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())
|
//using (prefs.DisableAutoSave())
|
||||||
{
|
{
|
||||||
GUILayout.BeginHorizontal();
|
|
||||||
prefs.IsShowHidden = EditorGUILayout.ToggleLeft(
|
prefs.IsShowHidden = EditorGUILayout.ToggleLeft(
|
||||||
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsShowHidden)),
|
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsShowHidden)),
|
||||||
prefs.IsShowHidden);
|
prefs.IsShowHidden);
|
||||||
GUILayout.EndHorizontal();
|
|
||||||
|
|
||||||
GUILayout.BeginHorizontal();
|
|
||||||
prefs.IsShowInterfaces = EditorGUILayout.ToggleLeft(
|
prefs.IsShowInterfaces = EditorGUILayout.ToggleLeft(
|
||||||
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsShowInterfaces)),
|
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsShowInterfaces)),
|
||||||
prefs.IsShowInterfaces);
|
prefs.IsShowInterfaces);
|
||||||
GUILayout.EndHorizontal();
|
|
||||||
|
|
||||||
GUILayout.BeginHorizontal();
|
|
||||||
prefs.IsShowRuntimeComponents = EditorGUILayout.ToggleLeft(
|
prefs.IsShowRuntimeComponents = EditorGUILayout.ToggleLeft(
|
||||||
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsShowRuntimeComponents)),
|
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsShowRuntimeComponents)),
|
||||||
prefs.IsShowRuntimeComponents);
|
prefs.IsShowRuntimeComponents);
|
||||||
GUILayout.EndHorizontal();
|
|
||||||
|
|
||||||
GUILayout.BeginHorizontal();
|
|
||||||
prefs.IsUseCustomNames = EditorGUILayout.ToggleLeft(
|
prefs.IsUseCustomNames = EditorGUILayout.ToggleLeft(
|
||||||
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsUseCustomNames)),
|
UnityEditorUtility.TransformFieldName(nameof(UserSettingsPrefs.IsUseCustomNames)),
|
||||||
prefs.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);
|
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]
|
//[SerializeField]
|
||||||
//private bool _poolsToggle = false;
|
//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 DCFApixels.DragonECS.Unity.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
//using System.Drawing;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using Unity.Collections.LowLevel.Unsafe;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEditor.IMGUI.Controls;
|
using UnityEditor.IMGUI.Controls;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Color = UnityEngine.Color;
|
using Color = UnityEngine.Color;
|
||||||
using UnityComponent = UnityEngine.Component;
|
|
||||||
using UnityObject = UnityEngine.Object;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS.Unity.Editors
|
namespace DCFApixels.DragonECS.Unity.Editors
|
||||||
{
|
{
|
||||||
@ -24,7 +17,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
private static bool _changed = false;
|
private static bool _changed = false;
|
||||||
private static bool _delayedChanged = false;
|
private static bool _delayedChanged = false;
|
||||||
|
|
||||||
public static int ChangedCounter => _changedCounter;
|
public static int ChangedCounter
|
||||||
|
{
|
||||||
|
get { return _changedCounter; }
|
||||||
|
}
|
||||||
public static bool Changed
|
public static bool Changed
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -275,6 +271,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
public static float EntityBarHeight => EditorGUIUtility.singleLineHeight + 3f;
|
public static float EntityBarHeight => EditorGUIUtility.singleLineHeight + 3f;
|
||||||
|
|
||||||
private static float indent => (float)EditorGUI.indentLevel * 15f;
|
private static float indent => (float)EditorGUI.indentLevel * 15f;
|
||||||
|
private static float indentLevel => EditorGUI.indentLevel;
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
private static ComponentColorMode AutoColorMode
|
private static ComponentColorMode AutoColorMode
|
||||||
@ -292,6 +289,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
get { return UserSettingsPrefs.instance.IsShowRuntimeComponents; }
|
get { return UserSettingsPrefs.instance.IsShowRuntimeComponents; }
|
||||||
set { UserSettingsPrefs.instance.IsShowRuntimeComponents = value; }
|
set { UserSettingsPrefs.instance.IsShowRuntimeComponents = value; }
|
||||||
}
|
}
|
||||||
|
private static bool IsFastModeRuntimeComponents
|
||||||
|
{
|
||||||
|
get { return UserSettingsPrefs.instance.IsFastModeRuntimeComponents; }
|
||||||
|
set { UserSettingsPrefs.instance.IsFastModeRuntimeComponents = value; }
|
||||||
|
}
|
||||||
private static float OneLineHeight
|
private static float OneLineHeight
|
||||||
{
|
{
|
||||||
get => EditorGUIUtility.singleLineHeight;
|
get => EditorGUIUtility.singleLineHeight;
|
||||||
@ -1009,766 +1011,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
_currentProperty = property;
|
_currentProperty = property;
|
||||||
GetReferenceDropDown(sortedPredicateTypes, sortedWithOutTypes).Show(position);
|
GetReferenceDropDown(sortedPredicateTypes, sortedWithOutTypes).Show(position);
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
#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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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 T[] _items;
|
||||||
internal int _count;
|
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
|
public int Count
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user