Merge branch 'dev'

This commit is contained in:
DCFApixels 2024-12-31 23:25:06 +08:00
commit a56366e316
19 changed files with 852 additions and 438 deletions

View File

@ -5,6 +5,6 @@ namespace DCFApixels.DragonECS
[CreateAssetMenu(fileName = nameof(EcsDefaultWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsDefaultWorldProvider), order = 1)] [CreateAssetMenu(fileName = nameof(EcsDefaultWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsDefaultWorldProvider), order = 1)]
public class EcsDefaultWorldProvider : EcsWorldProvider<EcsDefaultWorld> public class EcsDefaultWorldProvider : EcsWorldProvider<EcsDefaultWorld>
{ {
protected override EcsDefaultWorld BuildWorld(ConfigContainer configs) { return new EcsDefaultWorld(configs, WorldID); } protected override EcsDefaultWorld BuildWorld(ConfigContainer configs) { return new EcsDefaultWorld(configs, null, WorldID); }
} }
} }

View File

@ -14,6 +14,6 @@
return _instance; return _instance;
} }
} }
protected override EcsDefaultWorld BuildWorld(ConfigContainer configs) { return new EcsDefaultWorld(configs, WorldID); } protected override EcsDefaultWorld BuildWorld(ConfigContainer configs) { return new EcsDefaultWorld(configs, null, WorldID); }
} }
} }

View File

@ -77,6 +77,7 @@ namespace DCFApixels.DragonECS
private void OnDrawGizmos() private void OnDrawGizmos()
{ {
Gizmos.DrawIcon(transform.position, "", false);
_pipeline?.DrawGizmos(); _pipeline?.DrawGizmos();
} }

View File

@ -5,6 +5,6 @@ namespace DCFApixels.DragonECS
[CreateAssetMenu(fileName = nameof(EcsWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsWorldProvider), order = 1)] [CreateAssetMenu(fileName = nameof(EcsWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsWorldProvider), order = 1)]
public class EcsWorldProvider : EcsWorldProvider<EcsWorld> public class EcsWorldProvider : EcsWorldProvider<EcsWorld>
{ {
protected override EcsWorld BuildWorld(ConfigContainer configs) { return new EcsWorld(configs, WorldID); } protected override EcsWorld BuildWorld(ConfigContainer configs) { return new EcsWorld(configs, null, WorldID); }
} }
} }

View File

@ -33,7 +33,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
EcsGUI.Layout.DrawWorldBaseInfo(Target.GetCurrentWorldRaw()); EcsGUI.Layout.DrawWorldBaseInfo(Target.GetCurrentWorldRaw());
base.OnInspectorGUI(); base.OnInspectorGUI();
GUILayout.Space(10); GUILayout.Space(10);
@ -53,6 +52,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
c.a = 0.3f; c.a = 0.3f;
EditorGUI.DrawRect(r, c); EditorGUI.DrawRect(r, c);
GUILayout.Space(10); GUILayout.Space(10);
EcsGUI.Layout.DrawWorldComponents(Target.GetCurrentWorldRaw());
} }
} }
} }

View File

@ -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);
} }

View File

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

View File

@ -118,6 +118,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
EcsGUI.Layout.DrawWorldBaseInfo(Target.World); EcsGUI.Layout.DrawWorldBaseInfo(Target.World);
EcsGUI.Layout.DrawWorldComponents(Target.World);
} }
} }
} }

View File

@ -71,4 +71,75 @@ namespace DCFApixels.DragonECS.Unity.Internal
void IEnumerator.Reset() { throw new NotSupportedException(); } void IEnumerator.Reset() { throw new NotSupportedException(); }
} }
} }
internal static class ArrayUtility
{
private static int GetHighBitNumber(uint bits)
{
if (bits == 0)
{
return -1;
}
int bit = 0;
if ((bits & 0xFFFF0000) != 0)
{
bits >>= 16;
bit |= 16;
}
if ((bits & 0xFF00) != 0)
{
bits >>= 8;
bit |= 8;
}
if ((bits & 0xF0) != 0)
{
bits >>= 4;
bit |= 4;
}
if ((bits & 0xC) != 0)
{
bits >>= 2;
bit |= 2;
}
if ((bits & 0x2) != 0)
{
bit |= 1;
}
return bit;
}
public static int NormalizeSizeToPowerOfTwo(int minSize)
{
unchecked
{
return 1 << (GetHighBitNumber((uint)minSize - 1u) + 1);
}
}
public static int NormalizeSizeToPowerOfTwo_ClampOverflow(int minSize)
{
unchecked
{
int hibit = (GetHighBitNumber((uint)minSize - 1u) + 1);
if (hibit >= 32)
{
return int.MaxValue;
}
return 1 << hibit;
}
}
public static void Fill<T>(T[] array, T value, int startIndex = 0, int length = -1)
{
if (length < 0)
{
length = array.Length;
}
else
{
length = startIndex + length;
}
for (int i = startIndex; i < length; i++)
{
array[i] = value;
}
}
}
} }

View File

@ -0,0 +1,492 @@
#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 (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
}
}
}
#endif

View File

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

View File

@ -2,27 +2,25 @@
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 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
{ {
internal static class EcsGUI internal static partial class EcsGUI
{ {
#region Scores #region Scores
private static int _changedCounter = 0; private static int _changedCounter = 0;
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
@ -273,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
@ -290,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;
@ -453,18 +457,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
} }
#endregion #endregion
//#region One line elems
//public static bool LeftToggle(Rect position, GUIContent label, bool value)
//{
// position = position.AddPadding(indent, 0, 0, 0);
// Rect togglePos;
// (togglePos, position) = position.HorizontalSliceLeft(18f);
//
// EditorGUI.togg(position, label);
// GUI.Label(position, label);
//}
//#endregion
#region entity bar #region entity bar
public static void EntityBarForAlive(Rect position, EntityStatus status, int id, short gen, short world) public static void EntityBarForAlive(Rect position, EntityStatus status, int id, short gen, short world)
{ {
@ -1019,405 +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;
int leakedEntitesCount = isNull ? 0 : world.CountLeakedEntitesDebug();
EditorGUILayout.IntField("Entities", entitesCount, EditorStyles.boldLabel);
EditorGUILayout.IntField("Capacity", capacity, EditorStyles.boldLabel);
EditorGUILayout.LongField("Version", world.Version, EditorStyles.boldLabel);
Color color = leakedEntitesCount > 0 ? Color.yellow : GUI.contentColor;
using (new ContentColorScope(color))
{
EditorGUILayout.IntField("Leaked Entites", leakedEntitesCount, EditorStyles.boldLabel);
}
}
#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();
}
}
[InitializeOnLoadMethod]
private static void ResetRuntimeComponentReflectionCache()
{
_runtimeComponentReflectionCaches.Clear();
}
private 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;
}
}
} }
} }
#endif #endif

View File

@ -92,12 +92,35 @@ namespace DCFApixels.DragonECS.Unity.Editors
{ {
base.OnInspectorGUI(); base.OnInspectorGUI();
} }
protected SerializedProperty FindProperty(string name) protected SerializedProperty FindProperty(string name)
{ {
return serializedObject.FindProperty(name); return serializedObject.FindProperty(name);
} }
//Color proColor = (Color)new Color32(56, 56, 56, 255);
//Color plebColor = (Color)new Color32(194, 194, 194, 255);
//protected override void OnHeaderGUI()
//{
// //base.OnHeaderGUI();
// var rect = EditorGUILayout.GetControlRect(false, 0f);
// rect.height = EditorGUIUtility.singleLineHeight;
// rect.y -= rect.height;
// rect.x = 48;
// rect.xMax -= rect.x * 2f;
//
// //GUI.skin.settings
// EditorGUI.DrawRect(rect, EditorGUIUtility.isProSkin ? proColor : plebColor);
//
// //string header = (target as ComponentFolder).folderName; // <--- your variable
// string header = "";
// if (string.IsNullOrEmpty(header))
// {
// header = target.ToString() + 1;
// }
//
// EditorGUI.LabelField(rect, header, EditorStyles.boldLabel);
//}
} }
internal abstract class ExtendedEditor<T> : ExtendedEditor internal abstract class ExtendedEditor<T> : ExtendedEditor
{ {

View File

@ -103,12 +103,15 @@ namespace DCFApixels.DragonECS.Unity.Editors
namespace DCFApixels.DragonECS.Unity.Editors namespace DCFApixels.DragonECS.Unity.Editors
{ {
using UnityEditor; using UnityEditor;
using Assembly = System.Reflection.Assembly;
[InitializeOnLoad] [InitializeOnLoad]
internal static partial class UnityEditorUtility internal static partial class UnityEditorUtility
{ {
static UnityEditorUtility() static UnityEditorUtility()
{ {
_integrationAssembly = typeof(UnityEditorUtility).Assembly;
colorBoxeStyles = new SparseArray<GUIStyle>(); colorBoxeStyles = new SparseArray<GUIStyle>();
List<Type> serializableTypes = new List<Type>(); List<Type> serializableTypes = new List<Type>();
@ -144,6 +147,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
//}).ToArray(); //}).ToArray();
} }
internal static readonly Assembly _integrationAssembly;
internal static readonly Type[] _serializableTypes; internal static readonly Type[] _serializableTypes;
internal static readonly TypeMeta[] _serializableTypeWithMetaIDMetas; internal static readonly TypeMeta[] _serializableTypeWithMetaIDMetas;
private static readonly Dictionary<string, Type> _metaIDTypePairs = new Dictionary<string, Type>(); private static readonly Dictionary<string, Type> _metaIDTypePairs = new Dictionary<string, Type>();

View File

@ -0,0 +1,181 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS.Unity.Internal
{
[DebuggerDisplay("Count: {Count}")]
internal struct StructList<T>
{
internal T[] _items;
internal int _count;
public IEnumerable<T> Enumerable
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _items.Take(_count); }
}
public bool IsNull
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _items == null; }
}
public bool IsNullOrEmpty
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _items == null || _items.Length <= 0; }
}
public int Count
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _count; }
}
public int Capacity
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _items.Length; }
set
{
if (value <= _items.Length) { return; }
value = ArrayUtility.NormalizeSizeToPowerOfTwo(value);
Array.Resize(ref _items, value);
}
}
public T this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
#if DEBUG
if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
#endif
return _items[index];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
#if DEBUG
if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
#endif
_items[index] = value;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public StructList(int capacity)
{
_items = new T[ArrayUtility.NormalizeSizeToPowerOfTwo(capacity)];
_count = 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Add(T item)
{
if (_count >= _items.Length)
{
Array.Resize(ref _items, _items.Length << 1);
}
_items[_count++] = item;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int IndexOf(T item)
{
return Array.IndexOf(_items, item, 0, _count);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SwapAt(int idnex1, int idnex2)
{
T tmp = _items[idnex1];
_items[idnex1] = _items[idnex2];
_items[idnex2] = tmp;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void FastRemoveAt(int index)
{
#if DEBUG
if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
#endif
_items[index] = _items[--_count];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RemoveAt(int index)
{
#if DEBUG
if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
#endif
_items[index] = _items[--_count];
_items[_count] = default;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RemoveAtWithOrder(int index)
{
#if DEBUG
if (index < 0 || index >= _count) { Throw.ArgumentOutOfRange(); }
#endif
for (int i = index; i < _count;)
{
_items[i++] = _items[i];
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Remove(T item)
{
int index = IndexOf(item);
if (index >= 0)
{
RemoveAt(index);
return true;
}
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool RemoveWithOrder(T item)
{
int index = IndexOf(item);
if (index >= 0)
{
RemoveAtWithOrder(index);
return true;
}
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void FastClear()
{
_count = 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Clear()
{
for (int i = 0; i < _count; i++)
{
_items[i] = default;
}
_count = 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlySpan<T>.Enumerator GetEnumerator()
{
return new ReadOnlySpan<T>(_items, 0, _count).GetEnumerator();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlySpan<T> ToReadOnlySpan()
{
return new ReadOnlySpan<T>(_items, 0, _count);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public IEnumerable<T> ToEnumerable()
{
return _items.Take(_count);
}
public T[] ToArray()
{
T[] result = new T[_count];
Array.Copy(_items, result, _count);
return _items;
}
}
}

View File

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

View File

@ -0,0 +1,12 @@
using System;
namespace DCFApixels.DragonECS.Unity.Internal
{
internal static class Throw
{
internal static void ArgumentOutOfRange()
{
throw new ArgumentOutOfRangeException();
}
}
}

View File

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

View File

@ -1,7 +1,9 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal; using DCFApixels.DragonECS.Unity.Internal;
using DCFApixels.DragonECS.Unity.RefRepairer.Editors; using DCFApixels.DragonECS.Unity.RefRepairer.Editors;
using System;
using UnityEditor; using UnityEditor;
using UnityEditor.Graphs;
using UnityEditorInternal; using UnityEditorInternal;
using UnityEngine; using UnityEngine;