This commit is contained in:
Mikhail 2024-03-04 07:38:38 +08:00
parent f88b07950f
commit 21f041bd44
10 changed files with 266 additions and 199 deletions

View File

@ -2,74 +2,96 @@ using UnityEngine;
namespace DCFApixels.DragonECS
{
public static class EcsDefaultWorldBuilder
public class AutoEntityCreator : MonoBehaviour
{
public static EcsDefaultWorld Build()
[SerializeField]
private EcsEntityConnect _connect;
[SerializeField]
private EcsWorldProviderBase _world;
private bool _created;
#region Properties
public EcsEntityConnect Connect => _connect;
#endregion
#region UnityEvents
private void OnValidate()
{
return new EcsDefaultWorld();
if (_world == null)
{
AutoResolveWorldProviderDependensy();
}
}
}
namespace Project.Unity
{
public class AutoEntityCreator : MonoBehaviour
private void Start()
{
[SerializeField]
private EcsEntityConnect _connect;
[SerializeField]
private EcsWorldProviderBase _world;
private bool _created;
CreateEntity();
}
#endregion
#region Properties
public EcsEntityConnect Connect => _connect;
#endregion
#region UnityEvents
private void OnValidate()
private void AutoResolveWorldProviderDependensy()
{
_world = EcsDefaultWorldSingletonProvider.Instance;
}
public void ManualStart()
{
CreateEntity();
}
private void CreateEntity()
{
if (_created)
{
if (_world == null)
return;
}
if (_world == null)
{
AutoResolveWorldProviderDependensy();
}
else
{
InitConnect(_connect, _world.GetRaw());
}
_created = true;
}
private void InitConnect(EcsEntityConnect connect, EcsWorld world)
{
connect.ConnectWith(world.NewEntityLong());
connect.ApplyTemplates();
}
#if UNITY_EDITOR
internal void Autoset_Editor()
{
_connect = GetComponentInChildren<EcsEntityConnect>();
}
#endif
}
}
#if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors
{
using UnityEditor;
[CustomEditor(typeof(AutoEntityCreator))]
[CanEditMultipleObjects]
public class AutoEntityCreatorEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("Autoset"))
{
foreach (var tr in targets)
{
AutoResolveWorldProviderDependensy();
AutoEntityCreator creator = (AutoEntityCreator)tr;
creator.Autoset_Editor();
EditorUtility.SetDirty(creator);
}
}
private void Start()
{
CreateEntity();
}
#endregion
private void AutoResolveWorldProviderDependensy()
{
_world = EcsDefaultWorldSingletonProvider.Instance;
}
public void ManualStart()
{
CreateEntity();
}
private void CreateEntity()
{
if (_created)
{
return;
}
if (_world == null)
{
AutoResolveWorldProviderDependensy();
}
else
{
InitConnect(_connect, _world.GetRaw());
}
_created = true;
}
private void InitConnect(EcsEntityConnect connect, EcsWorld world)
{
connect.ConnectWith(world.NewEntityLong());
connect.ApplyTemplates();
}
}
}
}
}
#endif

View File

@ -91,7 +91,9 @@ namespace DCFApixels.DragonECS
#if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors
{
using DCFApixels.DragonECS.Unity.Internal;
using UnityEditor;
using static Codice.CM.WorkspaceServer.WorkspaceTreeDataStore;
[CustomEditor(typeof(EcsEntityConnect))]
[CanEditMultipleObjects]
@ -120,8 +122,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
DrawTop();
DrawConnectStatus(targets);
DrawEntityInfo();
DrawEntityInfo(targets);
DrawTemplates();
@ -132,57 +133,48 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
var iterator = serializedObject.GetIterator();
iterator.NextVisible(true);
using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath))
using (new EditorGUI.DisabledScope(true))
{
EditorGUILayout.PropertyField(iterator, true);
}
}
private void DrawConnectStatus(EcsEntityConnect[] targets)
{
bool isConnected = Target.IsConected;
for (int i = 0; i < targets.Length; i++)
{
if (isConnected != targets[i].IsConected)
{
isConnected = !Target.IsConected;
break;
}
}
if (isConnected == Target.IsConected)
{
EcsGUI.Layout.DrawConnectStatus(Target.IsConected);
}
else
{
EcsGUI.Layout.DrawUndeterminedConnectStatus();
}
}
private void DrawEntityInfo()
private void DrawEntityInfo(EcsEntityConnect[] targets)
{
GUILayout.Label(string.Empty);
Rect entityRect = GUILayoutUtility.GetLastRect();
Rect idRect = entityRect;
idRect.xMax -= idRect.width / 2f;
Rect genRect = entityRect;
genRect.xMin = idRect.xMax;
genRect.xMax -= genRect.width / 2f;
Rect worldRect = genRect;
worldRect.x += worldRect.width;
float width = EditorGUIUtility.currentViewWidth;
float height = EditorGUIUtility.singleLineHeight;
Rect entityRect = GUILayoutUtility.GetRect(width, height + 3f);
if (IsMultipleTargets == false && Target.Entity.TryUnpack(out int id, out short gen, out short world))
var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(entityRect, 3f);
var (idRect, genWorldRect) = RectUtility.HorizontalSliceLerp(entityInfoRect, 0.5f);
var (genRect, worldRect) = RectUtility.HorizontalSliceLerp(genWorldRect, 0.5f);
bool isConnected = Target.Entity.TryUnpack(out int id, out short gen, out short world);
if (IsMultipleTargets == false && isConnected)
{
Color statusColor = EcsGUI.GreenColor;
statusColor.a = 0.32f;
EditorGUI.DrawRect(statusRect, statusColor);
EditorGUI.IntField(idRect, id);
EditorGUI.IntField(genRect, gen);
EditorGUI.IntField(worldRect, world);
}
else
{
GUI.enabled = false;
EditorGUI.TextField(idRect, "Entity ID");
EditorGUI.TextField(genRect, "Gen");
EditorGUI.TextField(worldRect, "World ID");
GUI.enabled = true;
using (new EditorGUI.DisabledScope(true))
{
Color statusColor = IsMultipleTargets ? EcsGUI.GrayColor : EcsGUI.RedColor;
statusColor.a = 0.32f;
EditorGUI.DrawRect(statusRect, statusColor);
EditorGUI.TextField(idRect, "Entity ID");
EditorGUI.TextField(genRect, "Gen");
EditorGUI.TextField(worldRect, "World ID");
}
}
}
@ -193,22 +185,20 @@ namespace DCFApixels.DragonECS.Unity.Editors
bool enterChildren = true;
while (iterator.NextVisible(enterChildren))
{
using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath))
{
EditorGUILayout.PropertyField(iterator, true);
}
EditorGUILayout.PropertyField(iterator, true);
enterChildren = false;
}
}
private void DrawButtons()
{
if (GUILayout.Button("Autoset Templates"))
GUILayout.BeginHorizontal();
if (GUILayout.Button("Autoset"))
{
Target.SetTemplates_Editor(Target.GetComponents<MonoEntityTemplate>());
EditorUtility.SetDirty(target);
}
if (GUILayout.Button("Autoset Templates Cascade"))
if (GUILayout.Button("Autoset Cascade"))
{
foreach (var item in Target.GetComponentsInChildren<EcsEntityConnect>())
{
@ -216,6 +206,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
EditorUtility.SetDirty(item);
}
}
GUILayout.EndHorizontal();
}
private void DrawComponents(EcsEntityConnect[] targets)
@ -227,13 +218,13 @@ namespace DCFApixels.DragonECS.Unity.Editors
if (targets[i].IsConected == true)
{
EditorGUILayout.HelpBox("Multiple component editing is not available.", MessageType.Warning);
break;
return;
}
}
}
if (Target.IsConected)
if (Target.Entity.TryUnpack(out int entityID, out EcsWorld world))
{
EcsGUI.Layout.DrawComponents(Target.Entity);
EcsGUI.Layout.DrawComponents(entityID, world);
}
}
}

View File

@ -1,7 +1,6 @@
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
@ -60,15 +59,15 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
public static class EcsGUI
internal static class EcsGUI
{
private static Color _grayColor = new Color32(100, 100, 100, 100);
private static Color _greenColor = new Color32(75, 255, 0, 100);
private static Color _redColor = new Color32(255, 0, 75, 100);
internal readonly static Color GrayColor = new Color32(100, 100, 100, 255);
internal readonly static Color GreenColor = new Color32(75, 255, 0, 255);
internal readonly static Color RedColor = new Color32(255, 0, 75, 255);
private static GUIStyle _grayStyle;
private static GUIStyle _greenStyle;
private static GUIStyle _redStyle;
//private static GUIStyle _grayStyle;
//private static GUIStyle _greenStyle;
//private static GUIStyle _redStyle;
private static GUILayoutOption[] _defaultParams;
private static bool _isInit = false;
@ -81,62 +80,62 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
_defaultParams = new GUILayoutOption[] { GUILayout.ExpandWidth(true) };
_grayStyle = EcsEditor.GetStyle(_grayColor);
_greenStyle = EcsEditor.GetStyle(_greenColor);
_redStyle = EcsEditor.GetStyle(_redColor);
//_grayStyle = EcsEditor.GetStyle(GrayColor);
//_greenStyle = EcsEditor.GetStyle(GreenColor);
//_redStyle = EcsEditor.GetStyle(RedColor);
_isInit = true;
}
private const string CONNECTED = "Connected";
private const string NOT_CONNECTED = "Not connected";
private const string UNDETERMINED_CONNECTED = "---";
public static void DrawConnectStatus(Rect position, bool status)
{
Init();
if (status)
{
GUI.Box(position, CONNECTED, _greenStyle);
}
else
{
GUI.Box(position, NOT_CONNECTED, _redStyle);
}
}
public static void DrawUndeterminedConnectStatus(Rect position)
{
Init();
GUI.Box(position, UNDETERMINED_CONNECTED, _grayStyle);
}
//private const string CONNECTED = "Connected";
//private const string NOT_CONNECTED = "Not connected";
//private const string UNDETERMINED_CONNECTED = "---";
//public static void DrawConnectStatus(Rect position, bool status)
//{
// Init();
// if (status)
// {
// GUI.Box(position, CONNECTED, _greenStyle);
// }
// else
// {
// GUI.Box(position, NOT_CONNECTED, _redStyle);
// }
//}
//
//public static void DrawUndeterminedConnectStatus(Rect position)
//{
// Init();
// GUI.Box(position, UNDETERMINED_CONNECTED, _grayStyle);
//}
public static class Layout
{
public static void DrawConnectStatus(bool status, params GUILayoutOption[] options)
{
Init();
if (options == null || options.Length <= 0)
{
options = _defaultParams;
}
GUILayout.Box("", options);
Rect lastRect = GUILayoutUtility.GetLastRect();
Color color = status ? _greenColor : _redColor;
string text = status ? CONNECTED : NOT_CONNECTED;
color.a = 0.6f;
EditorGUI.DrawRect(lastRect, color);
GUI.Box(lastRect, text);
}
//public static void DrawConnectStatus(bool status, params GUILayoutOption[] options)
//{
// Init();
// if (options == null || options.Length <= 0)
// {
// options = _defaultParams;
// }
// GUILayout.Box("", options);
// Rect lastRect = GUILayoutUtility.GetLastRect();
// Color color = status ? GreenColor : RedColor;
// string text = status ? CONNECTED : NOT_CONNECTED;
// color.a = 0.6f;
// EditorGUI.DrawRect(lastRect, color);
// GUI.Box(lastRect, text);
//}
public static void DrawUndeterminedConnectStatus(params GUILayoutOption[] options)
{
Init();
if (options == null || options.Length <= 0)
{
options = _defaultParams;
}
GUILayout.Box(UNDETERMINED_CONNECTED, _grayStyle, options);
}
//public static void DrawUndeterminedConnectStatus(params GUILayoutOption[] options)
//{
// Init();
// if (options == null || options.Length <= 0)
// {
// options = _defaultParams;
// }
// GUILayout.Box(UNDETERMINED_CONNECTED, _grayStyle, options);
//}
public static void DrawComponents(entlong entity)
{
if (entity.TryUnpack(out int entityID, out EcsWorld world))
@ -147,17 +146,18 @@ namespace DCFApixels.DragonECS.Unity.Editors
public static void DrawComponents(int entityID, EcsWorld world)
{
var componentTypeIDs = world.GetComponentTypeIDs(entityID);
GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f));
foreach (var componentTypeID in componentTypeIDs)
{
var pool = world.GetPool(componentTypeID);
{
DrawComponent(entityID, world, pool);
DrawComponent(entityID, pool);
}
}
GUILayout.EndVertical();
}
private static readonly BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
private static void DrawComponent(int entityID, EcsWorld world, IEcsPool pool)
private static void DrawComponent(int entityID, IEcsPool pool)
{
object data = pool.GetRaw(entityID);
var meta = data.GetMeta();
@ -176,27 +176,19 @@ namespace DCFApixels.DragonECS.Unity.Editors
GUILayout.EndVertical();
Rect lineRect = GUILayoutUtility.GetLastRect();
lineRect.y = lineRect.yMax;
lineRect.height = 3f;
Color rectColor = panelColor;
rectColor.a = 0.34f;
EditorGUI.DrawRect(lineRect, rectColor);
GUILayout.Space(2f);
}
private static bool DrawData(Type fieldType, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData)
{
Type type = data.GetType();
var uobj = data as UnityEngine.Object;
UnityEngine.Object uobj = data as UnityEngine.Object;
ref bool isExpanded = ref expandMatrix.Down();
bool changed = false;
outData = data;
if ((uobj == false && type.IsGenericType) ||
(uobj == false && !type.IsSerializable))
if (uobj == null && (type.IsGenericType || !type.IsSerializable))
{
bool result = false;
isExpanded = EditorGUILayout.Foldout(isExpanded, label);
if (isExpanded)
@ -208,16 +200,13 @@ namespace DCFApixels.DragonECS.Unity.Editors
if (DrawData(field.FieldType, subLabel, expandMatrix, field.GetValue(data), out object fieldData))
{
field.SetValue(data, fieldData);
result = true;
outData = fieldData;
changed = true;
}
}
EditorGUI.indentLevel--;
}
expandMatrix.Up();
outData = data;
return result;
}
else
{
@ -228,19 +217,16 @@ namespace DCFApixels.DragonECS.Unity.Editors
EditorGUILayout.PropertyField(w.Property, label, true);
isExpanded = w.IsExpanded;
w.Release();
expandMatrix.Up();
if (EditorGUI.EndChangeCheck())
{
w.SO.ApplyModifiedProperties();
outData = w.Data;
return true;
changed = true;
}
outData = data;
return false;
}
expandMatrix.Up();
return changed;
}
}
}

View File

@ -11,7 +11,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
private static Dictionary<Type, ExpandMatrix> _instances = new Dictionary<Type, ExpandMatrix>();
public static ExpandMatrix Take(Type type)
{
if(_instances.TryGetValue(type, out ExpandMatrix result) == false)
if (_instances.TryGetValue(type, out ExpandMatrix result) == false)
{
result = new ExpandMatrix();
_instances.Add(type, result);

41
src/Editor/RectUtility.cs Normal file
View File

@ -0,0 +1,41 @@
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Internal
{
internal static class RectUtility
{
public static (Rect, Rect) HorizontalSliceLerp(Rect rect, float t)
{
Rect l = rect;
Rect r = rect;
l.xMax -= rect.width * (1f - t);
r.xMin += rect.width * t;
return (l, r);
}
public static (Rect, Rect) HorizontalSliceLeft(Rect rect, float with)
{
Rect l = rect;
Rect r = rect;
l.xMax = l.xMin + with;
r.xMin += with;
return (l, r);
}
public static (Rect, Rect) HorizontalSliceRight(Rect rect, float with)
{
Rect l = rect;
Rect r = rect;
l.xMax -= with;
r.xMin = r.xMax - with;
return (l, r);
}
public static (Rect, Rect) VerticalSliceBottom(Rect rect, float height)
{
Rect t = rect;
Rect b = rect;
t.yMax -= height;
b.yMin = b.yMax - height;
return (t, b);
}
}
}

View File

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

View File

@ -1,5 +1,6 @@
#if UNITY_EDITOR
 #if UNITY_EDITOR
using System;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
@ -12,8 +13,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
public override object Data
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return data; }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static RefEditorWrapper Take(object data)
{
var result = Take();

View File

@ -1,5 +1,6 @@
#if UNITY_EDITOR
using System;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
@ -12,8 +13,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
public override object Data
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return data; }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static UnityObjEditorWrapper Take(UnityEngine.Object data)
{
var result = Take();

View File

@ -1,6 +1,7 @@
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEditor;
using UnityEngine;
@ -29,17 +30,22 @@ namespace DCFApixels.DragonECS.Unity.Editors
public override bool IsExpanded
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return Property.isExpanded; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set { Property.isExpanded = value; }
}
public override SerializedObject SO
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _so; }
}
public override SerializedProperty Property
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _property; }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TSelf Take()
{
TSelf result;
@ -60,6 +66,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
result._isReleased = false;
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Release(TSelf wrapper)
{
if (wrapper._isReleased)
@ -75,6 +82,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
_isDestroyed = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void Release()
{
Release((TSelf)this);

View File

@ -99,11 +99,13 @@ namespace DCFApixels.DragonECS.Unity.Editors
return;
DrawTop(target);
GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f));
for (int i = 0; i < componentsProp.arraySize; i++)
{
DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i);
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * 2);
}
GUILayout.EndVertical();
DrawFooter(target);
}
private void DrawTop(ITemplateInternal target)
@ -183,12 +185,12 @@ namespace DCFApixels.DragonECS.Unity.Editors
removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f);
GUILayout.EndVertical();
Rect lineRect = GUILayoutUtility.GetLastRect();
lineRect.y = lineRect.yMax;
lineRect.height = 3f;
Color rectColor = panelColor;
rectColor.a = 0.34f;
EditorGUI.DrawRect(lineRect, rectColor);
//Rect lineRect = GUILayoutUtility.GetLastRect();
//lineRect.y = lineRect.yMax;
//lineRect.height = 3f;
//Color rectColor = panelColor;
//rectColor.a = 0.34f;
//EditorGUI.DrawRect(lineRect, rectColor);
GUILayout.Label("", GUILayout.Width(removeButtonRect.width));
if (GUI.Button(removeButtonRect, "x", removeButtonStyle))