DragonECS-Unity/src/Connectors/EcsEntityConnect.cs

242 lines
7.7 KiB
C#
Raw Normal View History

2023-05-07 00:50:44 +08:00
using System.Runtime.CompilerServices;
using UnityEngine;
namespace DCFApixels.DragonECS
{
public class EcsEntityConnect : MonoBehaviour
{
2023-06-22 14:30:03 +08:00
private sealed class Aspect : EcsAspect
2023-05-07 00:50:44 +08:00
{
public readonly EcsPool<UnityGameObject> unityGameObjects;
2023-06-22 14:30:03 +08:00
public Aspect(Builder b)
2023-05-07 00:50:44 +08:00
{
unityGameObjects = b.Include<UnityGameObject>();
}
}
private entlong _entity;
private EcsWorld _world;
[SerializeField]
2024-03-03 03:51:49 +08:00
private ScriptableEntityTemplate[] _scriptableTemplates;
2023-05-07 00:50:44 +08:00
[SerializeField]
2024-03-03 03:51:49 +08:00
private MonoEntityTemplate[] _monoTemplates;
2023-05-07 00:50:44 +08:00
2024-03-03 03:51:49 +08:00
internal void SetTemplates_Editor(MonoEntityTemplate[] tempaltes)
2023-05-07 00:50:44 +08:00
{
2024-03-03 03:51:49 +08:00
_monoTemplates = tempaltes;
2023-05-07 00:50:44 +08:00
}
#region Properties
public entlong Entity
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _entity;
}
public EcsWorld World
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _world;
}
2024-03-03 03:51:49 +08:00
public bool IsConected
2023-05-07 00:50:44 +08:00
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _entity.IsAlive;
}
#endregion
public void ConnectWith(entlong entity, bool applyTemplates = false)
{
2023-06-22 14:40:26 +08:00
if (_entity.TryGetID(out int oldE) && _world != null)
2023-05-07 00:50:44 +08:00
{
2023-06-22 14:30:03 +08:00
var s = _world.GetAspect<Aspect>();
2023-05-07 00:50:44 +08:00
s.unityGameObjects.Del(oldE);
}
_world = null;
if (entity.TryGetID(out int newE))
{
_entity = entity;
_world = _entity.World;
2023-06-22 14:30:03 +08:00
var s = _world.GetAspect<Aspect>();
2023-05-07 00:50:44 +08:00
if (!s.unityGameObjects.Has(newE)) s.unityGameObjects.Add(newE) = new UnityGameObject(gameObject);
if (applyTemplates)
ApplyTemplates();
}
else
{
_entity = entlong.NULL;
}
}
2024-03-03 03:51:49 +08:00
public void ApplyTemplates()
{
ApplyTemplatesFor(_entity.ID);
}
2023-05-07 00:50:44 +08:00
public void ApplyTemplatesFor(int entityID)
{
2024-03-03 03:51:49 +08:00
foreach (var t in _scriptableTemplates)
{
t.Apply(_world.id, entityID);
}
foreach (var t in _monoTemplates)
{
t.Apply(_world.id, entityID);
}
2023-05-07 00:50:44 +08:00
}
}
2023-06-28 15:08:09 +08:00
}
2023-05-07 00:50:44 +08:00
2023-06-28 15:08:09 +08:00
#if UNITY_EDITOR
2024-03-03 03:51:49 +08:00
namespace DCFApixels.DragonECS.Unity.Editors
2023-06-28 15:08:09 +08:00
{
2024-03-04 07:38:38 +08:00
using DCFApixels.DragonECS.Unity.Internal;
2023-06-28 15:08:09 +08:00
using UnityEditor;
2024-03-04 07:38:38 +08:00
using static Codice.CM.WorkspaceServer.WorkspaceTreeDataStore;
2023-05-07 00:50:44 +08:00
2023-06-28 15:08:09 +08:00
[CustomEditor(typeof(EcsEntityConnect))]
2024-03-03 03:51:49 +08:00
[CanEditMultipleObjects]
2023-06-28 15:08:09 +08:00
public class EcsEntityEditor : Editor
{
private bool _isInit = false;
2024-03-03 03:51:49 +08:00
private EcsEntityConnect Target => (EcsEntityConnect)target;
private bool IsMultipleTargets => targets.Length > 1;
2023-05-07 00:50:44 +08:00
2023-06-28 15:08:09 +08:00
private void Init()
{
if (_isInit)
2024-03-03 03:51:49 +08:00
{
2023-06-28 15:08:09 +08:00
return;
2024-03-03 03:51:49 +08:00
}
2023-06-28 15:08:09 +08:00
_isInit = true;
}
2023-05-07 00:50:44 +08:00
2023-06-28 15:08:09 +08:00
public override void OnInspectorGUI()
{
Init();
2024-03-03 03:51:49 +08:00
EcsEntityConnect[] targets = new EcsEntityConnect[this.targets.Length];
for (int i = 0; i < targets.Length; i++)
{
targets[i] = (EcsEntityConnect)this.targets[i];
}
2024-03-04 07:38:38 +08:00
DrawEntityInfo(targets);
2023-06-22 14:40:26 +08:00
2024-03-03 03:51:49 +08:00
DrawTemplates();
DrawButtons();
2024-03-03 19:59:39 +08:00
DrawComponents(targets);
2024-03-03 03:51:49 +08:00
}
2023-05-07 00:50:44 +08:00
2024-03-05 03:35:38 +08:00
private const float line1 = 1f;
private const float line2 = 2f;
2024-03-04 07:38:38 +08:00
private void DrawEntityInfo(EcsEntityConnect[] targets)
2024-03-03 03:51:49 +08:00
{
2024-03-04 07:38:38 +08:00
float width = EditorGUIUtility.currentViewWidth;
float height = EditorGUIUtility.singleLineHeight;
2024-03-05 03:35:38 +08:00
Rect entityRect = GUILayoutUtility.GetRect(width, height + line2 * 2f);
Color w = Color.gray;
w.a = 0.6f;
Color b = Color.black;
b.a = 0.55f;
EditorGUI.DrawRect(entityRect, w);
2024-03-04 07:38:38 +08:00
2024-03-05 03:35:38 +08:00
entityRect = RectUtility.AddPadding(entityRect, line1, line1, line2, 0);
var (entityInfoRect, statusRect) = RectUtility.VerticalSliceBottom(entityRect, line2);
2024-03-04 07:38:38 +08:00
var (idRect, genWorldRect) = RectUtility.HorizontalSliceLerp(entityInfoRect, 0.5f);
var (genRect, worldRect) = RectUtility.HorizontalSliceLerp(genWorldRect, 0.5f);
2024-03-05 03:35:38 +08:00
idRect = RectUtility.AddPadding(idRect, line1, 0);
genRect = RectUtility.AddPadding(genRect, line1, 0);
worldRect = RectUtility.AddPadding(worldRect, line1, 0);
EditorGUI.DrawRect(idRect, b);
EditorGUI.DrawRect(genRect, b);
EditorGUI.DrawRect(worldRect, b);
2024-03-04 07:38:38 +08:00
bool isConnected = Target.Entity.TryUnpack(out int id, out short gen, out short world);
2024-03-05 03:35:38 +08:00
GUIStyle style = new GUIStyle(EditorStyles.boldLabel);
style.alignment = TextAnchor.MiddleCenter;
2024-03-04 07:38:38 +08:00
if (IsMultipleTargets == false && isConnected)
2024-03-03 03:51:49 +08:00
{
2024-03-04 07:38:38 +08:00
Color statusColor = EcsGUI.GreenColor;
2024-03-05 03:35:38 +08:00
statusColor.a = 0.4f;
2024-03-04 07:38:38 +08:00
EditorGUI.DrawRect(statusRect, statusColor);
2024-03-05 03:35:38 +08:00
EditorGUI.IntField(idRect, id, style);
EditorGUI.IntField(genRect, gen, style);
EditorGUI.IntField(worldRect, world, style);
2024-03-03 03:51:49 +08:00
}
else
{
2024-03-05 03:35:38 +08:00
Color statusColor = IsMultipleTargets ? new Color32(200, 200, 200, 255) : EcsGUI.RedColor;
statusColor.a = 0.4f;
EditorGUI.DrawRect(statusRect, statusColor);
Color dc = GUI.color;
Color ndc = Color.white;
ndc.a = 0.4f;
GUI.color = ndc;
GUI.Label(idRect, "Entity ID", EditorStyles.boldLabel);
GUI.Label(genRect, "Generation", EditorStyles.boldLabel);
GUI.Label(worldRect, "World ID", EditorStyles.boldLabel);
GUI.color = dc;
2024-03-03 03:51:49 +08:00
}
}
2023-05-07 00:50:44 +08:00
2024-03-03 03:51:49 +08:00
private void DrawTemplates()
{
var iterator = serializedObject.GetIterator();
iterator.NextVisible(true);
bool enterChildren = true;
while (iterator.NextVisible(enterChildren))
2023-06-28 15:08:09 +08:00
{
2024-03-04 07:38:38 +08:00
EditorGUILayout.PropertyField(iterator, true);
2024-03-03 03:51:49 +08:00
enterChildren = false;
}
}
2023-06-22 14:40:26 +08:00
2024-03-03 03:51:49 +08:00
private void DrawButtons()
{
2024-03-04 07:38:38 +08:00
GUILayout.BeginHorizontal();
if (GUILayout.Button("Autoset"))
2024-03-03 03:51:49 +08:00
{
Target.SetTemplates_Editor(Target.GetComponents<MonoEntityTemplate>());
2023-06-28 15:08:09 +08:00
EditorUtility.SetDirty(target);
}
2024-03-04 07:38:38 +08:00
if (GUILayout.Button("Autoset Cascade"))
2023-06-28 15:08:09 +08:00
{
foreach (var item in Target.GetComponentsInChildren<EcsEntityConnect>())
2023-05-07 00:50:44 +08:00
{
2024-03-03 03:51:49 +08:00
item.SetTemplates_Editor(item.GetComponents<MonoEntityTemplate>());
2023-06-28 15:08:09 +08:00
EditorUtility.SetDirty(item);
2023-05-07 00:50:44 +08:00
}
2023-06-28 15:08:09 +08:00
}
2024-03-04 07:38:38 +08:00
GUILayout.EndHorizontal();
2024-03-03 03:51:49 +08:00
}
2023-06-06 17:52:12 +08:00
2024-03-03 19:59:39 +08:00
private void DrawComponents(EcsEntityConnect[] targets)
2024-03-03 03:51:49 +08:00
{
2024-03-03 19:59:39 +08:00
if (IsMultipleTargets)
{
for (int i = 0; i < targets.Length; i++)
{
if (targets[i].IsConected == true)
{
EditorGUILayout.HelpBox("Multiple component editing is not available.", MessageType.Warning);
2024-03-04 07:38:38 +08:00
return;
2024-03-03 19:59:39 +08:00
}
}
}
2024-03-04 07:38:38 +08:00
if (Target.Entity.TryUnpack(out int entityID, out EcsWorld world))
2023-06-28 15:08:09 +08:00
{
2024-03-04 08:21:01 +08:00
EcsGUI.Layout.DrawRuntimeComponents(entityID, world);
2023-05-07 00:50:44 +08:00
}
}
}
}
2023-06-28 15:08:09 +08:00
#endif