DragonECS-Unity/src/Connectors/EcsEntityConnect.cs

231 lines
6.8 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
{
using System.Collections.Generic;
using UnityEditor;
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];
}
DrawTop();
DrawConnectStatus(targets);
DrawEntityInfo();
2023-06-22 14:40:26 +08:00
2024-03-03 03:51:49 +08:00
DrawTemplates();
DrawButtons();
DrawComponents();
}
private void DrawTop()
{
var iterator = serializedObject.GetIterator();
iterator.NextVisible(true);
using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath))
{
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);
}
2023-06-28 15:08:09 +08:00
else
2024-03-03 03:51:49 +08:00
{
EcsGUI.Layout.DrawUndeterminedConnectStatus();
}
}
2023-05-07 00:50:44 +08:00
2024-03-03 03:51:49 +08:00
private void DrawEntityInfo()
{
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;
if (IsMultipleTargets == false && Target.Entity.TryUnpack(out int id, out short gen, out short world))
{
EditorGUI.IntField(idRect, id);
EditorGUI.IntField(genRect, gen);
EditorGUI.IntField(worldRect, world);
}
else
{
EditorGUI.TextField(idRect, "-");
EditorGUI.TextField(genRect, "-");
EditorGUI.TextField(worldRect, "-");
}
}
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-03 03:51:49 +08:00
using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath))
{
EditorGUILayout.PropertyField(iterator, true);
}
enterChildren = false;
}
}
2023-06-22 14:40:26 +08:00
2024-03-03 03:51:49 +08:00
private void DrawButtons()
{
if (GUILayout.Button("Autoset Templates"))
{
Target.SetTemplates_Editor(Target.GetComponents<MonoEntityTemplate>());
2023-06-28 15:08:09 +08:00
EditorUtility.SetDirty(target);
}
if (GUILayout.Button("Autoset Templates Cascade"))
{
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-03 03:51:49 +08:00
}
2023-06-06 17:52:12 +08:00
2024-03-03 03:51:49 +08:00
private void DrawComponents()
{
if (Target.IsConected)
2023-06-28 15:08:09 +08:00
{
List<object> comps = new List<object>();
Target.World.GetComponents(Target.Entity.ID, comps);
GUILayout.TextArea(string.Join("\r\n", comps));
2023-05-07 00:50:44 +08:00
}
}
}
}
2023-06-28 15:08:09 +08:00
#endif