mirror of
https://github.com/DCFApixels/DragonECS-Unity.git
synced 2025-09-17 17:34:34 +08:00
update runtime monitors
This commit is contained in:
parent
7f2d1cee73
commit
69e2c926e8
@ -12,6 +12,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public abstract bool IsEmpty { get; }
|
public abstract bool IsEmpty { get; }
|
||||||
public abstract void SetRaw(EcsWorld world);
|
public abstract void SetRaw(EcsWorld world);
|
||||||
public abstract EcsWorld GetRaw();
|
public abstract EcsWorld GetRaw();
|
||||||
|
public abstract EcsWorld GetCurrentWorldRaw();
|
||||||
}
|
}
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public abstract class EcsWorldProvider<TWorld> : EcsWorldProviderBase where TWorld : EcsWorld
|
public abstract class EcsWorldProvider<TWorld> : EcsWorldProviderBase where TWorld : EcsWorld
|
||||||
@ -78,6 +79,10 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
return Get();
|
return Get();
|
||||||
}
|
}
|
||||||
|
public sealed override EcsWorld GetCurrentWorldRaw()
|
||||||
|
{
|
||||||
|
return _world;
|
||||||
|
}
|
||||||
public TWorld Get()
|
public TWorld Get()
|
||||||
{
|
{
|
||||||
if (_world == null || _world.IsDestroyed)
|
if (_world == null || _world.IsDestroyed)
|
||||||
|
@ -23,6 +23,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
EcsWorld world = Target.GetRaw();
|
EcsWorld world = Target.GetRaw();
|
||||||
GUILayout.Box($"{world.GetMeta().Name} ( {world.id} )", style, GUILayout.ExpandWidth(true));
|
GUILayout.Box($"{world.GetMeta().Name} ( {world.id} )", style, GUILayout.ExpandWidth(true));
|
||||||
}
|
}
|
||||||
|
EcsGUI.Layout.DrawWorldBaseInfo(Target.GetCurrentWorldRaw());
|
||||||
|
|
||||||
|
|
||||||
base.OnInspectorGUI();
|
base.OnInspectorGUI();
|
||||||
|
|
||||||
GUILayout.Space(10);
|
GUILayout.Space(10);
|
||||||
|
@ -1,23 +1,33 @@
|
|||||||
namespace DCFApixels.DragonECS
|
using DCFApixels.DragonECS.Unity.Internal;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
public sealed class DebugModule : IEcsModule
|
public sealed class DebugModule : IEcsModule
|
||||||
{
|
{
|
||||||
public const string DEBUG_LAYER = nameof(DEBUG_LAYER);
|
public const string DEBUG_LAYER = nameof(DEBUG_LAYER);
|
||||||
public EcsWorld[] _worlds;
|
public EcsWorld[] _worlds;
|
||||||
|
|
||||||
public DebugModule(params EcsWorld[] worlds)
|
public DebugModule(params EcsWorld[] worlds)
|
||||||
{
|
{
|
||||||
_worlds = worlds;
|
_worlds = worlds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IEcsModule.Import(EcsPipeline.Builder b)
|
void IEcsModule.Import(EcsPipeline.Builder b)
|
||||||
{
|
{
|
||||||
|
UnityDebugService.Activate();
|
||||||
b.Layers.Insert(EcsConsts.POST_END_LAYER, DEBUG_LAYER);
|
b.Layers.Insert(EcsConsts.POST_END_LAYER, DEBUG_LAYER);
|
||||||
//b.Add(new PipelineDebugSystem(), DEBUG_LAYER);
|
b.Add(new PipelineMonitorSystem(), DEBUG_LAYER);
|
||||||
foreach (var world in _worlds)
|
foreach (var world in _worlds)
|
||||||
{
|
{
|
||||||
//b.Add(new WorldDebugSystem(world), DEBUG_LAYER);
|
b.Add(new WorldMonitorSystem(world), DEBUG_LAYER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class DebugModuleExt
|
||||||
|
{
|
||||||
|
public static EcsPipeline.Builder AddUnityDebug(this EcsPipeline.Builder self, params EcsWorld[] worlds)
|
||||||
|
{
|
||||||
|
self.AddModule(new DebugModule(worlds));
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
8
src/Debug/Monitors/Editor.meta
Normal file
8
src/Debug/Monitors/Editor.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b1105324b07e39d449acceb24bdd7eb3
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
20
src/Debug/Monitors/Editor/EntityMonitorEditor.cs
Normal file
20
src/Debug/Monitors/Editor/EntityMonitorEditor.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#if UNITY_EDITOR
|
||||||
|
using DCFApixels.DragonECS.Unity.Internal;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS.Unity.Editors
|
||||||
|
{
|
||||||
|
[CustomEditor(typeof(EntityMonitor))]
|
||||||
|
internal class EntityMonitorEditor : Editor
|
||||||
|
{
|
||||||
|
private EntityMonitor Target => (EntityMonitor)target;
|
||||||
|
|
||||||
|
public override void OnInspectorGUI()
|
||||||
|
{
|
||||||
|
bool isAlive = Target.Entity.TryUnpack(out int id, out short gen, out EcsWorld world);
|
||||||
|
EcsGUI.Layout.EntityBar(isAlive ? EcsGUI.EntityStatus.Alive : EcsGUI.EntityStatus.NotAlive, id, gen, world.id);
|
||||||
|
EcsGUI.Layout.DrawRuntimeComponents(Target.Entity, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
11
src/Debug/Monitors/Editor/EntityMonitorEditor.cs.meta
Normal file
11
src/Debug/Monitors/Editor/EntityMonitorEditor.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c5457dbe0f53566419d37e0ee9d9c13f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
18
src/Debug/Monitors/Editor/WorldMonitorEditor.cs
Normal file
18
src/Debug/Monitors/Editor/WorldMonitorEditor.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#if UNITY_EDITOR
|
||||||
|
using DCFApixels.DragonECS.Unity.Internal;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS.Unity.Editors
|
||||||
|
{
|
||||||
|
[CustomEditor(typeof(WorldMonitor))]
|
||||||
|
internal class WorldMonitorEditor : Editor
|
||||||
|
{
|
||||||
|
private WorldMonitor Target => (WorldMonitor)target;
|
||||||
|
|
||||||
|
public override void OnInspectorGUI()
|
||||||
|
{
|
||||||
|
EcsGUI.Layout.DrawWorldBaseInfo(Target.World);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
11
src/Debug/Monitors/Editor/WorldMonitorEditor.cs.meta
Normal file
11
src/Debug/Monitors/Editor/WorldMonitorEditor.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7aadf8c836c97694186e4b3aeb01fcce
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,31 +1,19 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS.Unity.Internal
|
||||||
{
|
{
|
||||||
[MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)]
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
public class EntityMonitor : MonoBehaviour, IEcsProcess
|
[MetaColor(MetaColor.Gray)]
|
||||||
|
public class EntityMonitor : MonoBehaviour
|
||||||
{
|
{
|
||||||
private entlong _entity;
|
private entlong _entity;
|
||||||
private int _entityID;
|
public entlong Entity
|
||||||
private short _gen;
|
|
||||||
private EcsWorld _world;
|
|
||||||
|
|
||||||
public EcsWorld World
|
|
||||||
{
|
{
|
||||||
get { return _world; }
|
get { return _entity; }
|
||||||
}
|
}
|
||||||
public int EntityID
|
public void Set(entlong entity)
|
||||||
{
|
|
||||||
get { return _entityID; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityMonitor(entlong entity)
|
|
||||||
{
|
{
|
||||||
_entity = entity;
|
_entity = entity;
|
||||||
if (_entity.TryUnpack(out _entityID, out _gen, out _world))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,42 @@
|
|||||||
using UnityEngine;
|
using DCFApixels.DragonECS.Unity.Editors;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS.Unity.Internal
|
||||||
{
|
{
|
||||||
[MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)]
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
public class PipelineMonitor : MonoBehaviour, IEcsProcess
|
[MetaColor(MetaColor.Gray)]
|
||||||
|
public class PipelineMonitor : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
private EcsPipeline _pipeline;
|
||||||
|
public EcsPipeline Pipeline
|
||||||
|
{
|
||||||
|
get { return _pipeline; }
|
||||||
|
}
|
||||||
|
public void Set(EcsPipeline pipeline)
|
||||||
|
{
|
||||||
|
_pipeline = pipeline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
|
[MetaColor(MetaColor.Gray)]
|
||||||
|
public class PipelineMonitorSystem : IEcsInit, IEcsPipelineMember, IEcsDestroy
|
||||||
|
{
|
||||||
|
private PipelineMonitor _monitor;
|
||||||
|
public EcsPipeline Pipeline { get; set; }
|
||||||
|
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
TypeMeta meta = typeof(EcsPipeline).ToMeta();
|
||||||
|
_monitor = new GameObject($"{UnityEditorUtility.TransformToUpperName(meta.Name)}").AddComponent<PipelineMonitor>();
|
||||||
|
UnityEngine.Object.DontDestroyOnLoad(_monitor);
|
||||||
|
_monitor.Set(Pipeline);
|
||||||
|
_monitor.gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Destroy()
|
||||||
|
{
|
||||||
|
UnityEngine.Object.Destroy(_monitor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,108 @@
|
|||||||
using UnityEngine;
|
using DCFApixels.DragonECS.Unity.Editors;
|
||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS.Unity.Internal
|
||||||
{
|
{
|
||||||
[MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)]
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
public class WorldMonitor : MonoBehaviour, IEcsProcess
|
[MetaColor(MetaColor.Gray)]
|
||||||
|
public class WorldMonitor : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
private EcsWorld _world;
|
||||||
|
public EcsWorld World
|
||||||
|
{
|
||||||
|
get { return _world; }
|
||||||
|
}
|
||||||
|
public void Set(EcsWorld world)
|
||||||
|
{
|
||||||
|
_world = world;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MetaTags(MetaTags.HIDDEN)]
|
||||||
|
[MetaColor(MetaColor.Gray)]
|
||||||
|
public class WorldMonitorSystem : IEcsInit, IEcsWorldEventListener, IEcsEntityEventListener
|
||||||
|
{
|
||||||
|
private EcsWorld _world;
|
||||||
|
private WorldMonitor _monitor;
|
||||||
|
private Transform _entityMonitorsPoolRoot;
|
||||||
|
private EntityMonitor[] _entityMonitors;
|
||||||
|
public EcsWorld World
|
||||||
|
{
|
||||||
|
get { return _world; }
|
||||||
|
}
|
||||||
|
public WorldMonitorSystem(EcsWorld world)
|
||||||
|
{
|
||||||
|
_world = world;
|
||||||
|
_entityMonitors = new EntityMonitor[_world.Capacity];
|
||||||
|
|
||||||
|
_world.AddListener(entityEventListener: this);
|
||||||
|
_world.AddListener(worldEventListener: this);
|
||||||
|
}
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
TypeMeta meta = _world.GetMeta();
|
||||||
|
_monitor = new GameObject($"{UnityEditorUtility.TransformToUpperName(meta.Name)} ( {_world.id} )").AddComponent<WorldMonitor>();
|
||||||
|
UnityEngine.Object.DontDestroyOnLoad(_monitor);
|
||||||
|
_monitor.Set(_world);
|
||||||
|
_monitor.gameObject.SetActive(false);
|
||||||
|
|
||||||
|
_entityMonitorsPoolRoot = new GameObject("__POOL").transform;
|
||||||
|
_entityMonitorsPoolRoot.SetParent(_monitor.transform);
|
||||||
|
|
||||||
|
foreach (var e in _world.Entities)
|
||||||
|
{
|
||||||
|
InitNewEntity(e, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IEcsWorldEventListener.OnWorldResize(int newSize)
|
||||||
|
{
|
||||||
|
Array.Resize(ref _entityMonitors, newSize);
|
||||||
|
}
|
||||||
|
void IEcsWorldEventListener.OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer) { }
|
||||||
|
void IEcsWorldEventListener.OnWorldDestroy()
|
||||||
|
{
|
||||||
|
UnityEngine.Object.Destroy(_monitor);
|
||||||
|
UnityEngine.Object.Destroy(_entityMonitorsPoolRoot);
|
||||||
|
_monitor = null;
|
||||||
|
_entityMonitorsPoolRoot = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IEcsEntityEventListener.OnNewEntity(int entityID)
|
||||||
|
{
|
||||||
|
InitNewEntity(entityID, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitNewEntity(int entityID, bool check)
|
||||||
|
{
|
||||||
|
if(_monitor == null) { return; }
|
||||||
|
ref var _entityMonitorRef = ref _entityMonitors[entityID];
|
||||||
|
if (_entityMonitorRef == null)
|
||||||
|
{
|
||||||
|
_entityMonitorRef = new GameObject($"ENTITY ( {entityID} )").AddComponent<EntityMonitor>();
|
||||||
|
}
|
||||||
|
if (check && _entityMonitorRef.Entity.IsAlive)
|
||||||
|
{
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
_entityMonitorRef.Set(_world.GetEntityLong(entityID));
|
||||||
|
_entityMonitorRef.transform.SetParent(_monitor.transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IEcsEntityEventListener.OnDelEntity(int entityID)
|
||||||
|
{
|
||||||
|
if(_monitor == null) { return; }
|
||||||
|
ref var _entityMonitorRef = ref _entityMonitors[entityID];
|
||||||
|
if (_entityMonitorRef != null)
|
||||||
|
{
|
||||||
|
if (_entityMonitorRef.Entity.IsAlive)
|
||||||
|
{
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
_entityMonitorRef.transform.SetParent(_entityMonitorsPoolRoot.transform);
|
||||||
|
_entityMonitorRef.Set(_world.GetEntityLong(entityID));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
|
using Codice.Client.Common.GameUI;
|
||||||
using DCFApixels.DragonECS.Unity.Internal;
|
using DCFApixels.DragonECS.Unity.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@ -23,6 +24,20 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct ContentColorScope : IDisposable
|
||||||
|
{
|
||||||
|
private readonly Color _oldColor;
|
||||||
|
public ContentColorScope(Color color)
|
||||||
|
{
|
||||||
|
_oldColor = GUI.contentColor;
|
||||||
|
GUI.contentColor = color;
|
||||||
|
}
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
GUI.contentColor = _oldColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal readonly static Color GrayColor = new Color32(100, 100, 100, 255);
|
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 GreenColor = new Color32(75, 255, 0, 255);
|
||||||
internal readonly static Color RedColor = new Color32(255, 0, 75, 255);
|
internal readonly static Color RedColor = new Color32(255, 0, 75, 255);
|
||||||
@ -274,6 +289,20 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
|
|
||||||
public static class Layout
|
public static class Layout
|
||||||
{
|
{
|
||||||
|
public static void DrawWorldBaseInfo(EcsWorld world)
|
||||||
|
{
|
||||||
|
bool isNull = world == null || 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);
|
||||||
|
Color color = leakedEntitesCount > 0 ? Color.yellow : GUI.contentColor;
|
||||||
|
using (new ContentColorScope(color))
|
||||||
|
{
|
||||||
|
EditorGUILayout.IntField("Leaked Entites", leakedEntitesCount, EditorStyles.boldLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
public static void EntityBar(EntityStatus status, int id, short gen, short world)
|
public static void EntityBar(EntityStatus status, int id, short gen, short world)
|
||||||
{
|
{
|
||||||
float width = EditorGUIUtility.currentViewWidth;
|
float width = EditorGUIUtility.currentViewWidth;
|
||||||
|
@ -20,6 +20,43 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
|||||||
private static GUIContent _singletonContent = null;
|
private static GUIContent _singletonContent = null;
|
||||||
|
|
||||||
#region TransformFieldName
|
#region TransformFieldName
|
||||||
|
public static string TransformToUpperName(string name)
|
||||||
|
{
|
||||||
|
if (name.Length <= 0)
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
bool nextWorld = true;
|
||||||
|
bool prewIsUpper = false;
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < name.Length; i++)
|
||||||
|
{
|
||||||
|
char c = name[i];
|
||||||
|
if (char.IsLetter(c) == false)
|
||||||
|
{
|
||||||
|
nextWorld = true;
|
||||||
|
prewIsUpper = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isUpper = char.IsUpper(c);
|
||||||
|
if (isUpper)
|
||||||
|
{
|
||||||
|
if (nextWorld == false && prewIsUpper == false)
|
||||||
|
{
|
||||||
|
b.Append('_');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.Append(char.ToUpper(c));
|
||||||
|
nextWorld = false;
|
||||||
|
prewIsUpper = isUpper;
|
||||||
|
}
|
||||||
|
|
||||||
|
return b.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
public static string TransformFieldName(string name)
|
public static string TransformFieldName(string name)
|
||||||
{
|
{
|
||||||
if (name.Length <= 0)
|
if (name.Length <= 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user