This commit is contained in:
Mikhail 2024-03-03 03:51:49 +08:00
parent 0862067ddd
commit ebfaf5bc98
43 changed files with 1344 additions and 1105 deletions

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 37d966ee996491b4d923ae68af4b67cd guid: f2b9c91714b4752468a3a5691cbf5237
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -0,0 +1,21 @@
using UnityEngine;
namespace DCFApixels.DragonECS
{
[CreateAssetMenu(fileName = nameof(EcsDefaultWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsDefaultWorldProvider), order = 1)]
public class EcsDefaultWorldProvider : EcsWorldProvider<EcsDefaultWorld>
{
//private static EcsDefaultWorldProvider _singleInstance;
//public static EcsDefaultWorldProvider SingletonInstance
//{
// get
// {
// if (_singleInstance == null)
// {
// _singleInstance = FindOrCreateSingleton<EcsDefaultWorldProvider>();
// }
// return _singleInstance;
// }
//}
}
}

View File

@ -0,0 +1,23 @@
namespace DCFApixels.DragonECS
{
public class EcsDefaultWorldSingletonProvider : EcsWorldProvider<EcsDefaultWorld>
{
private static EcsDefaultWorldSingletonProvider _instance;
public static EcsDefaultWorldSingletonProvider Instance
{
get
{
if (_instance == null)
{
_instance = FindOrCreateSingleton<EcsDefaultWorldSingletonProvider>("DefaultSingletonProvider");
}
return _instance;
}
}
protected override EcsDefaultWorld BuildWorld()
{
return new EcsDefaultWorld();
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 54d84d8749e68c044b4f13a512808a67 guid: 7592c6e5a68845c4abeac089e561d8c7
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -6,89 +6,93 @@ using UnityEngine;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
[Serializable] [Serializable]
[DebugColor(255 / 3, 255, 0)] [MetaColor(255 / 3, 255, 0)]
public struct UnityComponent<T> : IEcsComponent, IEnumerable<T>//IntelliSense hack public struct UnityComponent<T> : IEcsComponent, IEnumerable<T>//IntelliSense hack
where T : Component where T : Component
{ {
public T obj; public T obj;
public UnityComponent(T obj) => this.obj = obj; public UnityComponent(T obj)
{
this.obj = obj;
}
IEnumerator<T> IEnumerable<T>.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack IEnumerator<T> IEnumerable<T>.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack
IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack
} }
#region Unity Component Templates
public class UnityComponentInitializer<T> : TemplateComponentInitializer<UnityComponent<T>> where T : Component public class UnityComponentTemplate<T> : ComponentTemplateBase<UnityComponent<T>> where T : Component
{ {
public override string Name => "UnityComponent/" + typeof(T).Name; public override string Name => "UnityComponent/" + typeof(T).Name;
public sealed override void Add(EcsWorld w, int e) => w.GetPool<UnityComponent<T>>().Add(e) = component; public sealed override void Apply(int worldID, int entityID)
public override void OnValidate(GameObject gameObject) {
EcsWorld.GetPool<EcsPool<UnityComponent<T>>>(worldID).TryAddOrGet(entityID) = component;
}
public override void OnValidate(UnityEngine.Object obj)
{ {
if (component.obj == null) if (component.obj == null)
component.obj = gameObject.GetComponent<T>(); {
if (obj is GameObject go)
{
component.obj = go.GetComponent<T>();
}
}
} }
} }
[Serializable]
public sealed class UnityComponentRigitBodyInitializer : UnityComponentTemplate<Rigidbody> { }
[Serializable]
public sealed class UnityComponentAnimatorInitializer : UnityComponentTemplate<Animator> { }
[Serializable]
public sealed class UnityComponentCharacterControllerInitializer : UnityComponentTemplate<CharacterController> { }
#endregion
#region Collider Templates
[Serializable] [Serializable]
public sealed class UnityComponentRigitBodyInitializer : UnityComponentInitializer<Rigidbody> public sealed class UnityComponentColliderTemplate : UnityComponentTemplate<Collider>
{
}
[Serializable]
public sealed class UnityComponentAnimatorInitializer : UnityComponentInitializer<Animator>
{
}
[Serializable]
public sealed class UnityComponentCharacterControllerInitializer : UnityComponentInitializer<CharacterController>
{
}
#region Colliders
[Serializable]
public sealed class UnityComponentColliderInitializer : UnityComponentInitializer<Collider>
{ {
public override string Name => "UnityComponent/Collider/" + nameof(Collider); public override string Name => "UnityComponent/Collider/" + nameof(Collider);
} }
[Serializable] [Serializable]
public sealed class UnityComponentBoxColliderInitializer : UnityComponentInitializer<BoxCollider> public sealed class UnityComponentBoxColliderTemplate : UnityComponentTemplate<BoxCollider>
{ {
public override string Name => "UnityComponent/Collider/" + nameof(BoxCollider); public override string Name => "UnityComponent/Collider/" + nameof(BoxCollider);
} }
[Serializable] [Serializable]
public sealed class UnityComponentSphereColliderInitializer : UnityComponentInitializer<SphereCollider> public sealed class UnityComponentSphereColliderTemplate : UnityComponentTemplate<SphereCollider>
{ {
public override string Name => "UnityComponent/Collider/" + nameof(SphereCollider); public override string Name => "UnityComponent/Collider/" + nameof(SphereCollider);
} }
[Serializable] [Serializable]
public sealed class UnityComponentCapsuleColliderInitializer : UnityComponentInitializer<CapsuleCollider> public sealed class UnityComponentCapsuleColliderTemplate : UnityComponentTemplate<CapsuleCollider>
{ {
public override string Name => "UnityComponent/Collider/" + nameof(CapsuleCollider); public override string Name => "UnityComponent/Collider/" + nameof(CapsuleCollider);
} }
[Serializable] [Serializable]
public sealed class UnityComponentMeshColliderInitializer : UnityComponentInitializer<MeshCollider> public sealed class UnityComponentMeshColliderTemplate : UnityComponentTemplate<MeshCollider>
{ {
public override string Name => "UnityComponent/Collider/" + nameof(MeshCollider); public override string Name => "UnityComponent/Collider/" + nameof(MeshCollider);
} }
#endregion #endregion
#region Joints #region Joint Templates
[Serializable] [Serializable]
public sealed class UnityComponentJointInitializer : UnityComponentInitializer<Joint> public sealed class UnityComponentJointTemplate : UnityComponentTemplate<Joint>
{ {
public override string Name => "UnityComponent/Joint/" + nameof(Joint); public override string Name => "UnityComponent/Joint/" + nameof(Joint);
} }
[Serializable] [Serializable]
public sealed class UnityComponentFixedJointInitializer : UnityComponentInitializer<FixedJoint> public sealed class UnityComponentFixedJointTemplate : UnityComponentTemplate<FixedJoint>
{ {
public override string Name => "UnityComponent/Joint/" + nameof(FixedJoint); public override string Name => "UnityComponent/Joint/" + nameof(FixedJoint);
} }
[Serializable] [Serializable]
public sealed class UnityComponentCharacterJointInitializer : UnityComponentInitializer<CharacterJoint> public sealed class UnityComponentCharacterJointTemplate : UnityComponentTemplate<CharacterJoint>
{ {
public override string Name => "UnityComponent/Joint/" + nameof(CharacterJoint); public override string Name => "UnityComponent/Joint/" + nameof(CharacterJoint);
} }
[Serializable] [Serializable]
public sealed class UnityComponentConfigurableJointInitializer : UnityComponentInitializer<ConfigurableJoint> public sealed class UnityComponentConfigurableJointTemplate : UnityComponentTemplate<ConfigurableJoint>
{ {
public override string Name => "UnityComponent/Joint/" + nameof(ConfigurableJoint); public override string Name => "UnityComponent/Joint/" + nameof(ConfigurableJoint);
} }

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 47a8547ed46c26e4bb6a68651ad40be0 guid: 637d69c48b6c0164abe654cd7f5ceb07
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -1,4 +1,5 @@
using DCFApixels.DragonECS.RunnersCore; using DCFApixels.DragonECS.Internal;
using DCFApixels.DragonECS.RunnersCore;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
@ -10,7 +11,7 @@ namespace DCFApixels.DragonECS
{ {
public static void DrawGizmos(this EcsPipeline systems) public static void DrawGizmos(this EcsPipeline systems)
{ {
systems.GetRunner<IEcsGizmosProcess>().DrawGizmos(systems); systems.GetRunnerInstance<EcsLateGizmosRunner>().DrawGizmos(systems);
} }
} }
@ -20,9 +21,9 @@ namespace DCFApixels.DragonECS
} }
public static class IEcsLateRunSystemExtensions public static class IEcsLateRunSystemExtensions
{ {
public static void LateRun(this EcsPipeline systems) public static void LateRun(this EcsPipeline pipeline)
{ {
systems.GetRunner<IEcsLateRunProcess>().LateRun(systems); pipeline.GetRunnerInstance<EcsLateRunRunner>().LateRun(pipeline);
} }
} }
public interface IEcsFixedRunProcess : IEcsProcess public interface IEcsFixedRunProcess : IEcsProcess
@ -33,14 +34,14 @@ namespace DCFApixels.DragonECS
{ {
public static void FixedRun(this EcsPipeline pipeline) public static void FixedRun(this EcsPipeline pipeline)
{ {
pipeline.GetRunner<IEcsFixedRunProcess>().FixedRun(pipeline); pipeline.GetRunnerInstance<EcsFixedRunRunner>().FixedRun(pipeline);
} }
} }
namespace Internal namespace Internal
{ {
[DebugColor(DebugColor.Orange)] [MetaColor(MetaColor.Orange)]
public class EcsLateGizmosSystemRunner : EcsRunner<IEcsGizmosProcess>, IEcsGizmosProcess public class EcsLateGizmosRunner : EcsRunner<IEcsGizmosProcess>, IEcsGizmosProcess
{ {
#if DEBUG && !DISABLE_DEBUG #if DEBUG && !DISABLE_DEBUG
private EcsProfilerMarker[] _markers; private EcsProfilerMarker[] _markers;
@ -48,10 +49,10 @@ namespace DCFApixels.DragonECS
public void DrawGizmos(EcsPipeline pipeline) public void DrawGizmos(EcsPipeline pipeline)
{ {
#if DEBUG && !DISABLE_DEBUG #if DEBUG && !DISABLE_DEBUG
for (int i = 0; i < targets.Length; i++) for (int i = 0; i < Process.Length; i++)
{ {
using (_markers[i].Auto()) using (_markers[i].Auto())
targets[i].DrawGizmos(pipeline); Process[i].DrawGizmos(pipeline);
} }
#else #else
foreach (var item in targets) item.DrawGizmos(pipeline); foreach (var item in targets) item.DrawGizmos(pipeline);
@ -61,17 +62,17 @@ namespace DCFApixels.DragonECS
#if DEBUG && !DISABLE_DEBUG #if DEBUG && !DISABLE_DEBUG
protected override void OnSetup() protected override void OnSetup()
{ {
_markers = new EcsProfilerMarker[targets.Length]; _markers = new EcsProfilerMarker[Process.Length];
for (int i = 0; i < targets.Length; i++) for (int i = 0; i < Process.Length; i++)
{ {
_markers[i] = new EcsProfilerMarker($"{targets[i].GetType().Name}.{nameof(DrawGizmos)}"); _markers[i] = new EcsProfilerMarker($"{Process[i].GetType().Name}.{nameof(DrawGizmos)}");
} }
} }
#endif #endif
} }
[DebugColor(DebugColor.Orange)] [MetaColor(MetaColor.Orange)]
public class EcsLateRunSystemRunner : EcsRunner<IEcsLateRunProcess>, IEcsLateRunProcess public class EcsLateRunRunner : EcsRunner<IEcsLateRunProcess>, IEcsLateRunProcess
{ {
#if DEBUG && !DISABLE_DEBUG #if DEBUG && !DISABLE_DEBUG
private EcsProfilerMarker[] _markers; private EcsProfilerMarker[] _markers;
@ -79,10 +80,12 @@ namespace DCFApixels.DragonECS
public void LateRun(EcsPipeline pipeline) public void LateRun(EcsPipeline pipeline)
{ {
#if DEBUG && !DISABLE_DEBUG #if DEBUG && !DISABLE_DEBUG
for (int i = 0; i < targets.Length; i++) for (int i = 0; i < Process.Length; i++)
{ {
using (_markers[i].Auto()) using (_markers[i].Auto())
targets[i].LateRun(pipeline); {
Process[i].LateRun(pipeline);
}
} }
#else #else
foreach (var item in targets) item.LateRun(pipeline); foreach (var item in targets) item.LateRun(pipeline);
@ -92,16 +95,16 @@ namespace DCFApixels.DragonECS
#if DEBUG && !DISABLE_DEBUG #if DEBUG && !DISABLE_DEBUG
protected override void OnSetup() protected override void OnSetup()
{ {
_markers = new EcsProfilerMarker[targets.Length]; _markers = new EcsProfilerMarker[Process.Length];
for (int i = 0; i < targets.Length; i++) for (int i = 0; i < Process.Length; i++)
{ {
_markers[i] = new EcsProfilerMarker($"EcsRunner.{targets[i].GetType().Name}.{nameof(LateRun)}"); _markers[i] = new EcsProfilerMarker($"EcsRunner.{Process[i].GetType().Name}.{nameof(LateRun)}");
} }
} }
#endif #endif
} }
[DebugColor(DebugColor.Orange)] [MetaColor(MetaColor.Orange)]
public class EcsFixedRunSystemRunner : EcsRunner<IEcsFixedRunProcess>, IEcsFixedRunProcess public class EcsFixedRunRunner : EcsRunner<IEcsFixedRunProcess>, IEcsFixedRunProcess
{ {
#if DEBUG && !DISABLE_DEBUG #if DEBUG && !DISABLE_DEBUG
private EcsProfilerMarker[] _markers; private EcsProfilerMarker[] _markers;
@ -109,10 +112,12 @@ namespace DCFApixels.DragonECS
public void FixedRun(EcsPipeline pipeline) public void FixedRun(EcsPipeline pipeline)
{ {
#if DEBUG && !DISABLE_DEBUG #if DEBUG && !DISABLE_DEBUG
for (int i = 0; i < targets.Length; i++) for (int i = 0; i < Process.Length; i++)
{ {
using (_markers[i].Auto()) using (_markers[i].Auto())
targets[i].FixedRun(pipeline); {
Process[i].FixedRun(pipeline);
}
} }
#else #else
foreach (var item in targets) item.FixedRun(pipeline); foreach (var item in targets) item.FixedRun(pipeline);
@ -122,10 +127,10 @@ namespace DCFApixels.DragonECS
#if DEBUG && !DISABLE_DEBUG #if DEBUG && !DISABLE_DEBUG
protected override void OnSetup() protected override void OnSetup()
{ {
_markers = new EcsProfilerMarker[targets.Length]; _markers = new EcsProfilerMarker[Process.Length];
for (int i = 0; i < targets.Length; i++) for (int i = 0; i < Process.Length; i++)
{ {
_markers[i] = new EcsProfilerMarker($"EcsRunner.{targets[i].GetType().Name}.{nameof(FixedRun)}"); _markers[i] = new EcsProfilerMarker($"EcsRunner.{Process[i].GetType().Name}.{nameof(FixedRun)}");
} }
} }
#endif #endif

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 0ce52308e352f734e8a21c5ae282c246 guid: 9b692b77d059ff445912bada1712ccab
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -6,7 +6,7 @@ using UnityEditor;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
[DebugColor(DebugColor.Cyan)] [MetaColor(MetaColor.Cyan)]
public readonly struct UnityGameObject : IEcsComponent public readonly struct UnityGameObject : IEcsComponent
{ {
public readonly GameObject gameObject; public readonly GameObject gameObject;
@ -60,12 +60,11 @@ namespace DCFApixels.DragonECS
public static class GameObjectRefExt public static class GameObjectRefExt
{ {
public static entlong NewEntityWithGameObject(this EcsWorld self, string name = "EcsEntity", GameObjectIcon icon = GameObjectIcon.NONE) public static entlong NewEntityWithGameObject(this EcsWorld self, string name = "Entity", GameObjectIcon icon = GameObjectIcon.NONE)
{ {
entlong result = self.GetEntityLong(self.NewEmptyEntity()); entlong result = self.NewEntityLong();
GameObject newGameObject = new GameObject(name); GameObject newGameObject = new GameObject(name);
newGameObject.AddComponent<EcsEntityConnect>().ConnectWith(result); newGameObject.AddComponent<EcsEntityConnect>().ConnectWith(result);
// self.GetPool<UnityGameObject>().Add(result.id) =
#if UNITY_EDITOR #if UNITY_EDITOR
if (icon != GameObjectIcon.NONE) if (icon != GameObjectIcon.NONE)
{ {
@ -84,7 +83,6 @@ namespace DCFApixels.DragonECS
EditorGUIUtility.SetIconForObject(newGameObject, (Texture2D)iconContent.image); EditorGUIUtility.SetIconForObject(newGameObject, (Texture2D)iconContent.image);
} }
#endif #endif
return result; return result;
} }
} }

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 909b2b01fa1e58b4e9e739827e36cff4 guid: 398c78166eea90647a60b91b2b9a0f0b
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -1,19 +0,0 @@
using UnityEngine;
namespace DCFApixels.DragonECS
{
[CreateAssetMenu(fileName = nameof(EcsDefaultWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsDefaultWorldProvider), order = 1)]
public class EcsDefaultWorldProvider : EcsWorldProvider<EcsDefaultWorld>
{
private static EcsDefaultWorldProvider _single;
public static EcsDefaultWorldProvider Single
{
get
{
if (_single == null)
_single = FindOrCreateSingle<EcsDefaultWorldProvider>();
return _single;
}
}
}
}

View File

@ -18,13 +18,13 @@ namespace DCFApixels.DragonECS
private EcsWorld _world; private EcsWorld _world;
[SerializeField] [SerializeField]
private EntityTemplatePreset[] _entityTemplatePresets; private ScriptableEntityTemplate[] _scriptableTemplates;
[SerializeField] [SerializeField]
private EntityTemplate[] _entityTemplates; private MonoEntityTemplate[] _monoTemplates;
internal void SetTemplates_Editor(EntityTemplate[] tempaltes) internal void SetTemplates_Editor(MonoEntityTemplate[] tempaltes)
{ {
_entityTemplates = tempaltes; _monoTemplates = tempaltes;
} }
#region Properties #region Properties
@ -38,7 +38,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _world; get => _world;
} }
public bool IsAlive public bool IsConected
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _entity.IsAlive; get => _entity.IsAlive;
@ -69,70 +69,157 @@ namespace DCFApixels.DragonECS
_entity = entlong.NULL; _entity = entlong.NULL;
} }
} }
public void ApplyTemplates() => ApplyTemplatesFor(_entity.ID); public void ApplyTemplates()
{
ApplyTemplatesFor(_entity.ID);
}
public void ApplyTemplatesFor(int entityID) public void ApplyTemplatesFor(int entityID)
{ {
foreach (var t in _entityTemplatePresets) foreach (var t in _scriptableTemplates)
t.Apply(_world, entityID); {
foreach (var t in _entityTemplates) t.Apply(_world.id, entityID);
t.Apply(_world, entityID); }
foreach (var t in _monoTemplates)
{
t.Apply(_world.id, entityID);
}
} }
} }
} }
#if UNITY_EDITOR #if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors
namespace DCFApixels.DragonECS.Editors
{ {
using System.Collections.Generic; using System.Collections.Generic;
using UnityEditor; using UnityEditor;
[CustomEditor(typeof(EcsEntityConnect))] [CustomEditor(typeof(EcsEntityConnect))]
[CanEditMultipleObjects]
public class EcsEntityEditor : Editor public class EcsEntityEditor : Editor
{ {
private EcsEntityConnect Target => (EcsEntityConnect)target;
private bool _isInit = false; private bool _isInit = false;
private EcsEntityConnect Target => (EcsEntityConnect)target;
private bool IsMultipleTargets => targets.Length > 1;
private void Init() private void Init()
{ {
if (_isInit) if (_isInit)
{
return; return;
}
_isInit = true; _isInit = true;
} }
public override void OnInspectorGUI() public override void OnInspectorGUI()
{ {
Init(); Init();
EcsGUI.Layout.DrawConnectStatus(Target.IsAlive); EcsEntityConnect[] targets = new EcsEntityConnect[this.targets.Length];
for (int i = 0; i < targets.Length; i++)
{
targets[i] = (EcsEntityConnect)this.targets[i];
}
DrawTop();
if (Target.Entity.TryGetID(out int id)) DrawConnectStatus(targets);
EditorGUILayout.IntField(id); DrawEntityInfo();
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);
}
else else
EditorGUILayout.IntField(0); {
GUILayout.Label(Target.Entity.ToString()); EcsGUI.Layout.DrawUndeterminedConnectStatus();
}
}
base.OnInspectorGUI(); 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, "-");
}
}
private void DrawTemplates()
{
var iterator = serializedObject.GetIterator();
iterator.NextVisible(true);
bool enterChildren = true;
while (iterator.NextVisible(enterChildren))
{
using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath))
{
EditorGUILayout.PropertyField(iterator, true);
}
enterChildren = false;
}
}
private void DrawButtons()
{
if (GUILayout.Button("Autoset Templates")) if (GUILayout.Button("Autoset Templates"))
{ {
Target.SetTemplates_Editor(Target.GetComponents<EntityTemplate>()); Target.SetTemplates_Editor(Target.GetComponents<MonoEntityTemplate>());
EditorUtility.SetDirty(target); EditorUtility.SetDirty(target);
} }
if (GUILayout.Button("Autoset Templates Cascade")) if (GUILayout.Button("Autoset Templates Cascade"))
{ {
foreach (var item in Target.GetComponentsInChildren<EcsEntityConnect>()) foreach (var item in Target.GetComponentsInChildren<EcsEntityConnect>())
{ {
item.SetTemplates_Editor(item.GetComponents<EntityTemplate>()); item.SetTemplates_Editor(item.GetComponents<MonoEntityTemplate>());
EditorUtility.SetDirty(item); EditorUtility.SetDirty(item);
} }
} }
}
if (Target.IsAlive) private void DrawComponents()
{
if (Target.IsConected)
{ {
List<object> comps = new List<object>(); List<object> comps = new List<object>();
Target.World.GetComponents(Target.Entity.ID, comps); Target.World.GetComponents(Target.Entity.ID, comps);

View File

@ -9,43 +9,50 @@ namespace DCFApixels.DragonECS
[Serializable] [Serializable]
public abstract class EcsWorldProviderBase : ScriptableObject public abstract class EcsWorldProviderBase : ScriptableObject
{ {
public abstract EcsWorld WorldRaw { get; } public abstract bool IsEmpty { get; }
public abstract EcsWorld GetRaw(Func<EcsWorld> builder = null); public abstract void SetRaw(EcsWorld world);
public abstract EcsWorld GetRaw();
} }
[Serializable] [Serializable]
public abstract class EcsWorldProvider<TWorld> : EcsWorldProviderBase where TWorld : EcsWorld public abstract class EcsWorldProvider<TWorld> : EcsWorldProviderBase where TWorld : EcsWorld
{ {
private static TWorld _world; private TWorld _world;
public sealed override EcsWorld WorldRaw => _world;
public override EcsWorld GetRaw(Func<EcsWorld> builder = null)
{
if (_world == null || _world.IsDestroyed)
{
if (builder != null)
_world = (TWorld)builder();
else
_world = (TWorld)Activator.CreateInstance(typeof(TWorld));
OnWorldCreated(_world);
}
return _world;
}
public TWorld Get(Func<TWorld> builder = null)
{
if (_world == null || _world.IsDestroyed)
{
if(builder != null)
_world = builder();
else
_world = (TWorld)Activator.CreateInstance(typeof(TWorld));
OnWorldCreated(_world);
}
return _world;
}
protected virtual void OnWorldCreated(TWorld world) { }
protected static TProvider FindOrCreateSingle<TProvider>() where TProvider : EcsWorldProvider<TWorld> #region Properties
public sealed override bool IsEmpty
{
get { return _world == null; }
}
#endregion
#region Methods
public sealed override void SetRaw(EcsWorld worldRaw)
{
Set((TWorld)worldRaw);
}
public void Set(TWorld world)
{
_world = world;
}
public sealed override EcsWorld GetRaw()
{
return Get();
}
public TWorld Get()
{
if (_world == null || _world.IsDestroyed)
{
_world = BuildWorld();
OnWorldCreated(_world);
}
return _world;
}
protected static TProvider FindOrCreateSingleton<TProvider>() where TProvider : EcsWorldProvider<TWorld>
{
return FindOrCreateSingleton<TProvider>(typeof(TProvider).Name + "Singleton");
}
protected static TProvider FindOrCreateSingleton<TProvider>(string name) where TProvider : EcsWorldProvider<TWorld>
{ {
string name = typeof(TProvider).Name + "Single";
TProvider instance = Resources.Load<TProvider>(name); TProvider instance = Resources.Load<TProvider>(name);
if (instance == null) if (instance == null)
{ {
@ -62,5 +69,42 @@ namespace DCFApixels.DragonECS
} }
return instance; return instance;
} }
#endregion
#region Events
protected virtual TWorld BuildWorld()
{
return (TWorld)Activator.CreateInstance(typeof(TWorld), new object[] { null, -1 });
}
protected virtual void OnWorldCreated(TWorld world) { }
#endregion
} }
} }
#if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomEditor(typeof(EcsWorldProviderBase), true)]
[CanEditMultipleObjects]
public class EcsWorldProviderBaseEditor : Editor
{
private EcsWorldProviderBase Target => (EcsWorldProviderBase)target;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (Target.IsEmpty)
{
var style = EcsEditor.GetStyle(new Color32(255, 0, 75, 100));
GUILayout.Box("Is Empty", style, GUILayout.ExpandWidth(true));
}
else
{
var style = EcsEditor.GetStyle(new Color32(75, 255, 0, 100));
EcsWorld world = Target.GetRaw();
GUILayout.Box($"{world.GetMeta().Name} ( {world.id} )", style, GUILayout.ExpandWidth(true));
}
}
}
}
#endif

View File

@ -18,6 +18,7 @@ namespace DCFApixels.DragonECS
if (v is Exception e) if (v is Exception e)
{ {
Debug.LogException(e); Debug.LogException(e);
return;
} }
bool hasTag = string.IsNullOrEmpty(tag) == false; bool hasTag = string.IsNullOrEmpty(tag) == false;

View File

@ -1,7 +1,7 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using UnityEditor; using UnityEditor;
namespace DCFApixels.DragonECS.Editors namespace DCFApixels.DragonECS.Unity.Editors
{ {
[FilePath("DragonECS/DebugMonitorPrefs.prefs", FilePathAttribute.Location.ProjectFolder)] [FilePath("DragonECS/DebugMonitorPrefs.prefs", FilePathAttribute.Location.ProjectFolder)]
public class DebugMonitorPrefs : ScriptableSingleton<DebugMonitorPrefs> public class DebugMonitorPrefs : ScriptableSingleton<DebugMonitorPrefs>

View File

@ -1,48 +1,83 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System; using System;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using UnityEditor; using UnityEditor;
using UnityEditor.UI;
using UnityEngine; using UnityEngine;
namespace DCFApixels.DragonECS.Editors namespace DCFApixels.DragonECS.Unity.Editors
{ {
public static class EcsGUI public static class EcsGUI
{ {
private static GUIStyle _grayStyle;
private static GUIStyle _greenStyle; private static GUIStyle _greenStyle;
private static GUIStyle _redStyle; private static GUIStyle _redStyle;
private static GUILayoutOption[] _defaultParams;
private static bool _isInit = false; private static bool _isInit = false;
private static void Init() private static void Init()
{ {
if (_isInit) if (_isInit)
{
return; return;
}
_defaultParams = new GUILayoutOption[] { GUILayout.ExpandWidth(true) };
_grayStyle = EcsEditor.GetStyle(new Color32(100, 100, 100, 100));
_greenStyle = EcsEditor.GetStyle(new Color32(75, 255, 0, 100)); _greenStyle = EcsEditor.GetStyle(new Color32(75, 255, 0, 100));
_redStyle = EcsEditor.GetStyle(new Color32(255, 0, 75, 100)); _redStyle = EcsEditor.GetStyle(new Color32(255, 0, 75, 100));
_isInit = true; _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) public static void DrawConnectStatus(Rect position, bool status)
{ {
Init(); Init();
if (status) if (status)
GUI.Box(position, "Connected", _greenStyle); {
GUI.Box(position, CONNECTED, _greenStyle);
}
else else
GUI.Box(position, "Not connected", _redStyle); {
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 class Layout
{ {
public static void DrawConnectStatus(bool status, params GUILayoutOption[] options) public static void DrawConnectStatus(bool status, params GUILayoutOption[] options)
{ {
Init(); Init();
if(options == null || options.Length <= 0)
{
options = _defaultParams;
}
if (status) if (status)
GUILayout.Box("Connected", _greenStyle, GUILayout.ExpandWidth(true)); {
GUILayout.Box(CONNECTED, _greenStyle, options);
}
else else
GUILayout.Box("Not connected", _redStyle, GUILayout.ExpandWidth(true)); {
GUILayout.Box(NOT_CONNECTED, _redStyle, options);
}
}
public static void DrawUndeterminedConnectStatus(params GUILayoutOption[] options)
{
Init();
if (options == null || options.Length <= 0)
{
options = _defaultParams;
}
GUILayout.Box(UNDETERMINED_CONNECTED, _grayStyle, options);
} }
} }
} }

View File

@ -1,29 +1,30 @@
using DCFApixels.DragonECS.Unity.Debug; using DCFApixels.DragonECS.Unity.Debug;
using System.Reflection;
using UnityEngine; using UnityEngine;
using System.Linq;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
[DebugHide, DebugColor(DebugColor.Gray)] [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)]
public class PipelineDebugSystem : IEcsPreInitProcess public class PipelineDebugSystem : IEcsPreInit, IEcsPipelineMember
{ {
public EcsPipeline Pipeline { get; set; }
private string _monitorName; private string _monitorName;
public PipelineDebugSystem(string monitorName = "Pipeline") public PipelineDebugSystem(string monitorName = "Pipeline")
{ {
_monitorName = monitorName; _monitorName = monitorName;
} }
void IEcsPreInitProcess.PreInit(EcsPipeline pipeline) void IEcsPreInit.PreInit()
{ {
PipelineDebugMonitor monitor = new GameObject(EcsConsts.DEBUG_PREFIX + _monitorName).AddComponent<PipelineDebugMonitor>(); PipelineDebugMonitor monitor = new GameObject(EcsConsts.DEBUG_PREFIX + _monitorName).AddComponent<PipelineDebugMonitor>();
monitor.source = this; monitor.source = this;
monitor.pipeline = pipeline; monitor.pipeline = Pipeline;
monitor.monitorName = _monitorName; monitor.monitorName = _monitorName;
PipelineProcessesDebugMonitor processesMonitor = new GameObject(EcsConsts.DEBUG_PREFIX + "Processes Matrix").AddComponent<PipelineProcessesDebugMonitor>(); PipelineProcessesDebugMonitor processesMonitor = new GameObject(EcsConsts.DEBUG_PREFIX + "Processes Matrix").AddComponent<PipelineProcessesDebugMonitor>();
processesMonitor.transform.parent = monitor.transform; processesMonitor.transform.parent = monitor.transform;
processesMonitor.source = this; processesMonitor.source = this;
processesMonitor.pipeline = pipeline; processesMonitor.pipeline = Pipeline;
processesMonitor.monitorName = "Processes Matrix"; processesMonitor.monitorName = "Processes Matrix";
//foreach (var item in pipeline.AllSystems) //Вырезано пока не сделаю TODO в SystemDebugMonitor //foreach (var item in pipeline.AllSystems) //Вырезано пока не сделаю TODO в SystemDebugMonitor
@ -46,295 +47,295 @@ namespace DCFApixels.DragonECS
internal PipelineDebugSystem source; internal PipelineDebugSystem source;
internal EcsPipeline pipeline; internal EcsPipeline pipeline;
} }
}
#if UNITY_EDITOR #if UNITY_EDITOR
namespace Editors namespace DCFApixels.DragonECS.Unity.Editors
{
using DCFApixels.DragonECS.RunnersCore;
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Collections.Generic;
using UnityEditor;
[CustomEditor(typeof(PipelineDebugMonitor))]
public class PipelineDebugMonitorEditor : Editor
{ {
using DCFApixels.DragonECS.Internal; private MetaColorAttribute _fakeDebugColorAttribute = new MetaColorAttribute(190, 190, 190);
using DCFApixels.DragonECS.RunnersCore; private Type _debugColorAttributeType = typeof(MetaColorAttribute);
using System; private GUIStyle _headerStyle;
using System.Collections.Generic; private GUIStyle _interfacesStyle;
using System.Linq; private Color _interfaceColor = new Color(0.96f, 1f, 0.16f);
using UnityEditor; private PipelineDebugMonitor Target => (PipelineDebugMonitor)target;
[CustomEditor(typeof(PipelineDebugMonitor))]
public class PipelineDebugMonitorEditor : Editor private GUIStyle systemsListStyle;
public override void OnInspectorGUI()
{ {
private DebugColorAttribute _fakeDebugColorAttribute = new DebugColorAttribute(190, 190, 190); systemsListStyle = new GUIStyle(EditorStyles.miniLabel);
private Type _debugColorAttributeType = typeof(DebugColorAttribute); systemsListStyle.wordWrap = true;
private GUIStyle _headerStyle;
private GUIStyle _interfacesStyle;
private Color _interfaceColor = new Color(0.96f, 1f, 0.16f);
private PipelineDebugMonitor Target => (PipelineDebugMonitor)target;
if (Target.source == null)
private GUIStyle systemsListStyle; return;
if (_headerStyle == null)
public override void OnInspectorGUI()
{ {
systemsListStyle = new GUIStyle(EditorStyles.miniLabel); _headerStyle = new GUIStyle(EditorStyles.boldLabel);
systemsListStyle.wordWrap = true; _interfacesStyle = new GUIStyle(EditorStyles.miniLabel);
_interfacesStyle.hover.textColor = _interfaceColor;
if (Target.source == null) _interfacesStyle.focused.textColor = _interfaceColor;
return; _interfacesStyle.active.textColor = _interfaceColor;
if (_headerStyle == null) _interfacesStyle.normal.textColor = _interfaceColor;
{ _interfacesStyle.wordWrap = true;
_headerStyle = new GUIStyle(EditorStyles.boldLabel); _headerStyle.fontSize = 28;
_interfacesStyle = new GUIStyle(EditorStyles.miniLabel);
_interfacesStyle.hover.textColor = _interfaceColor;
_interfacesStyle.focused.textColor = _interfaceColor;
_interfacesStyle.active.textColor = _interfaceColor;
_interfacesStyle.normal.textColor = _interfaceColor;
_interfacesStyle.wordWrap = true;
_headerStyle.fontSize = 28;
}
GUILayout.Label("[Systems]", _headerStyle);
DebugMonitorPrefs.instance.IsShowInterfaces = EditorGUILayout.Toggle("Show Interfaces", DebugMonitorPrefs.instance.IsShowInterfaces);
DebugMonitorPrefs.instance.IsShowHidden = EditorGUILayout.Toggle("Show Hidden", DebugMonitorPrefs.instance.IsShowHidden);
GUILayout.BeginVertical();
foreach (var item in Target.pipeline.AllSystems)
{
DrawSystem(item);
}
GUILayout.EndVertical();
GUILayout.Label("[Runners]", _headerStyle);
GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f));
foreach (var item in Target.pipeline.AllRunners)
{
DrawRunner(item.Value);
}
GUILayout.EndVertical();
} }
private void DrawSystem(IEcsProcess system) GUILayout.Label("[Systems]", _headerStyle);
DebugMonitorPrefs.instance.IsShowInterfaces = EditorGUILayout.Toggle("Show Interfaces", DebugMonitorPrefs.instance.IsShowInterfaces);
DebugMonitorPrefs.instance.IsShowHidden = EditorGUILayout.Toggle("Show Hidden", DebugMonitorPrefs.instance.IsShowHidden);
GUILayout.BeginVertical();
foreach (var item in Target.pipeline.AllSystems)
{ {
if (system is SystemsLayerMarkerSystem markerSystem) DrawSystem(item);
{
GUILayout.EndVertical();
GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f));
GUILayout.BeginHorizontal();
GUILayout.Label("<");
GUILayout.Label($"{markerSystem.name}", EditorStyles.boldLabel);
GUILayout.Label(">", GUILayout.ExpandWidth(false));
GUILayout.EndHorizontal();
return;
}
Type type = system.GetType();
if (CheckIsHidden(type))
return;
string name = EcsEditor.GetGenericName(type);
//Color color = (GetAttribute<DebugColorAttribute>(type) ?? _fakeDebugColorAttribute).GetUnityColor();
Color color = EcsDebugUtility.GetColor(type).ToUnityColor();
GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f));
if (DebugMonitorPrefs.instance.IsShowInterfaces)
{
GUILayout.Label(string.Join(", ", type.GetInterfaces().Select(o => o.Name)), _interfacesStyle);
}
GUILayout.Label(name, EditorStyles.boldLabel);
GUILayout.EndVertical();
} }
GUILayout.EndVertical();
private void DrawRunner(IEcsRunner runner)
GUILayout.Label("[Runners]", _headerStyle);
GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f));
foreach (var item in Target.pipeline.AllRunners)
{ {
Type type = runner.GetType(); DrawRunner(item.Value);
if (CheckIsHidden(type))
return;
//Color color = (GetAttribute<DebugColorAttribute>(type) ?? _fakeDebugColorAttribute).GetUnityColor();
Color color = EcsDebugUtility.GetColor(type).ToUnityColor();
GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f));
GUILayout.Label(EcsEditor.GetGenericName(type), EditorStyles.boldLabel);
GUILayout.Label(string.Join(", ", runner.Targets.Cast<object>().Select(o => o.GetType().Name)), systemsListStyle);
GUILayout.EndVertical();
}
private TAttribute GetAttribute<TAttribute>(Type target) where TAttribute : Attribute
{
var result = target.GetCustomAttributes(_debugColorAttributeType, false);
if (result.Length > 0)
return (TAttribute)result[0];
return null;
}
private bool CheckIsHidden(Type target)
{
if (DebugMonitorPrefs.instance.IsShowHidden)
return false;
return target.GetCustomAttribute<DebugHideAttribute>() != null;
} }
GUILayout.EndVertical();
} }
[CustomEditor(typeof(PipelineProcessesDebugMonitor))] private void DrawSystem(IEcsProcess system)
public class PipelineProcessesDebugMonitorEditor : Editor
{ {
private bool _isInit = false; if (system is SystemsLayerMarkerSystem markerSystem)
private List<ProcessData> _processesList = new List<ProcessData>();
private Dictionary<Type, int> _processeIndexes = new Dictionary<Type, int>();
private PipelineProcessesDebugMonitor Target => (PipelineProcessesDebugMonitor)target;
private Type systemInterfaceType = typeof(IEcsProcess);
private IEcsProcess[] _systems;
private void Init()
{ {
if (_isInit) GUILayout.EndVertical();
return; GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f));
bool showHidden = DebugMonitorPrefs.instance.IsShowHidden;
_processesList.Clear();
_processeIndexes.Clear();
if (showHidden)
_systems = Target.pipeline.AllSystems.Where(o => o is SystemsLayerMarkerSystem == false).ToArray();
else
_systems = Target.pipeline.AllSystems.Where(o => o.GetType().GetCustomAttribute<DebugHideAttribute>() == null).ToArray();
int i = 0; GUILayout.BeginHorizontal();
foreach (var system in _systems) GUILayout.Label("<");
{ GUILayout.Label($"{markerSystem.name}", EditorStyles.boldLabel);
foreach (var intr in system.GetType().GetInterfaces()) GUILayout.Label(">", GUILayout.ExpandWidth(false));
{ GUILayout.EndHorizontal();
if (systemInterfaceType.IsAssignableFrom(intr) && systemInterfaceType != intr && (showHidden || intr.GetCustomAttribute<DebugHideAttribute>() == null)) return;
{
ProcessData data;
if (!_processeIndexes.TryGetValue(intr, out int index))
{
index = _processesList.Count;
_processeIndexes.Add(intr, index);
data = new ProcessData();
_processesList.Add(data);
data.name = EcsEditor.GetGenericName(intr);
data.interfaceType = intr;
data.systemsBitMask = new BitMask(_systems.Length);
}
data = _processesList[index];
data.systemsBitMask[i] = true;
}
}
i++;
}
_isInit = true;
}
private Vector2 _position;
private Vector2 _cellsize = new Vector2(EditorGUIUtility.singleLineHeight, EditorGUIUtility.singleLineHeight);
private Vector2 _nameCellSize = new Vector2(200f, 200f);
public override void OnInspectorGUI()
{
EditorGUI.BeginChangeCheck();
DebugMonitorPrefs.instance.IsShowHidden = EditorGUILayout.Toggle("Show Hidden", DebugMonitorPrefs.instance.IsShowHidden);
if (EditorGUI.EndChangeCheck())
{
_isInit = false;
}
Init();
Rect rect;
Rect lineRect;
GUILayout.Label("", GUILayout.ExpandWidth(true), GUILayout.Height(400f));
rect = GUILayoutUtility.GetLastRect();
rect.height = 400f;
Rect rectView = new Rect(0f, 0f, _nameCellSize.x + _cellsize.x * _processesList.Count, _nameCellSize.y + _cellsize.y * _systems.Length);
_position = GUI.BeginScrollView(rect, _position, rectView, true, true);
List<string> systeNames = new List<string>();
var blackStyle = EcsEditor.GetStyle(Color.black, 0.04f);
var whiteStyle = EcsEditor.GetStyle(Color.white, 0.04f);
GUIContent label = new GUIContent();
Vector2 pivod = _nameCellSize;
rect = new Rect();
rect.y = _nameCellSize.y;
rect.width = _nameCellSize.x;
rect.height = _cellsize.x;
rect.y -= _cellsize.y;
for (int i = 0; i < _processesList.Count; i++)
{
lineRect = rect;
lineRect.y = 0f;
lineRect.x = _nameCellSize.x + _cellsize.x * i;
lineRect.width = _cellsize.x;
lineRect.height = rectView.height;
GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle);
GUIUtility.RotateAroundPivot(90, pivod);
//GUIContent label = new GUIContent(_processesList[i].name, "." + _processesList[i].name);
label.text = _processesList[i].name;
label.tooltip = "." + _processesList[i].name;
GUI.Label(rect, label, EditorStyles.miniBoldLabel);
GUIUtility.RotateAroundPivot(-90, pivod);
pivod.x += _cellsize.x;
rect.x += _cellsize.x;
}
//GUIUtility.RotateAroundPivot(-90, _nameCellSize);
rect = new Rect();
rect.y = _nameCellSize.y;
rect.width = _nameCellSize.x;
rect.height = _cellsize.x;
for (int i = 0; i < _systems.Length; i++)
{
string name = EcsEditor.GetGenericName(_systems[i].GetType());
systeNames.Add(name);
lineRect = rect;
lineRect.width = rectView.width;
GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle);
// GUIContent label = new GUIContent(name, i + " " + name);
label.text = name;
label.tooltip = i + " " + name;
GUI.Label(rect, label, EditorStyles.miniBoldLabel);
rect.y += _cellsize.y;
}
for (int x = 0; x < _processesList.Count; x++)
{
var process = _processesList[x];
for (int y = 0; y < _systems.Length; y++)
{
string systemName = systeNames[x];
rect = new Rect(x * _cellsize.x + _nameCellSize.x, y * _cellsize.y + _nameCellSize.y, _cellsize.x, _cellsize.y);
bool flag = process.systemsBitMask[y];
string labeltext = flag ? "^" : " ";
label.text = labeltext;
label.tooltip = $"{process.name}-{systemName}";
GUI.Label(rect, label);
//GUI.Label(rect, lable, flag ? whiteStyle : blackStyle);
// GUI.Label(rect, label, EditorStyles.helpBox);
}
}
GUI.EndScrollView();
} }
private class ProcessData Type type = system.GetType();
if (CheckIsHidden(type))
return;
string name = EcsEditor.GetGenericName(type);
//Color color = (GetAttribute<DebugColorAttribute>(type) ?? _fakeDebugColorAttribute).GetUnityColor();
Color color = EcsDebugUtility.GetColor(type).ToUnityColor();
GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f));
if (DebugMonitorPrefs.instance.IsShowInterfaces)
{ {
public Type interfaceType; GUILayout.Label(string.Join(", ", type.GetInterfaces().Select(o => o.Name)), _interfacesStyle);
public string name;
public BitMask systemsBitMask;
} }
GUILayout.Label(name, EditorStyles.boldLabel);
GUILayout.EndVertical();
}
private void DrawRunner(IEcsRunner runner)
{
Type type = runner.GetType();
if (CheckIsHidden(type))
return;
//Color color = (GetAttribute<DebugColorAttribute>(type) ?? _fakeDebugColorAttribute).GetUnityColor();
Color color = EcsDebugUtility.GetColor(type).ToUnityColor();
GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f));
GUILayout.Label(EcsEditor.GetGenericName(type), EditorStyles.boldLabel);
GUILayout.Label(string.Join(", ", runner.ProcessRaw.Cast<object>().Select(o => o.GetType().Name)), systemsListStyle);
GUILayout.EndVertical();
}
private TAttribute GetAttribute<TAttribute>(Type target) where TAttribute : Attribute
{
var result = target.GetCustomAttributes(_debugColorAttributeType, false);
if (result.Length > 0)
return (TAttribute)result[0];
return null;
}
private bool CheckIsHidden(Type target)
{
if (DebugMonitorPrefs.instance.IsShowHidden)
return false;
return target.GetCustomAttribute<DebugHideAttribute>() != null;
}
}
[CustomEditor(typeof(PipelineProcessesDebugMonitor))]
public class PipelineProcessesDebugMonitorEditor : Editor
{
private bool _isInit = false;
private List<ProcessData> _processesList = new List<ProcessData>();
private Dictionary<Type, int> _processeIndexes = new Dictionary<Type, int>();
private PipelineProcessesDebugMonitor Target => (PipelineProcessesDebugMonitor)target;
private Type systemInterfaceType = typeof(IEcsProcess);
private IEcsProcess[] _systems;
private void Init()
{
if (_isInit)
return;
bool showHidden = DebugMonitorPrefs.instance.IsShowHidden;
_processesList.Clear();
_processeIndexes.Clear();
if (showHidden)
_systems = Target.pipeline.AllSystems.Where(o => o is SystemsLayerMarkerSystem == false).ToArray();
else
_systems = Target.pipeline.AllSystems.Where(o => o.GetType().GetCustomAttribute<DebugHideAttribute>() == null).ToArray();
int i = 0;
foreach (var system in _systems)
{
foreach (var intr in system.GetType().GetInterfaces())
{
if (systemInterfaceType.IsAssignableFrom(intr) && systemInterfaceType != intr && (showHidden || intr.GetCustomAttribute<DebugHideAttribute>() == null))
{
ProcessData data;
if (!_processeIndexes.TryGetValue(intr, out int index))
{
index = _processesList.Count;
_processeIndexes.Add(intr, index);
data = new ProcessData();
_processesList.Add(data);
data.name = EcsEditor.GetGenericName(intr);
data.interfaceType = intr;
data.systemsBitMask = new BitMask(_systems.Length);
}
data = _processesList[index];
data.systemsBitMask[i] = true;
}
}
i++;
}
_isInit = true;
}
private Vector2 _position;
private Vector2 _cellsize = new Vector2(EditorGUIUtility.singleLineHeight, EditorGUIUtility.singleLineHeight);
private Vector2 _nameCellSize = new Vector2(200f, 200f);
public override void OnInspectorGUI()
{
EditorGUI.BeginChangeCheck();
DebugMonitorPrefs.instance.IsShowHidden = EditorGUILayout.Toggle("Show Hidden", DebugMonitorPrefs.instance.IsShowHidden);
if (EditorGUI.EndChangeCheck())
{
_isInit = false;
}
Init();
Rect rect;
Rect lineRect;
GUILayout.Label("", GUILayout.ExpandWidth(true), GUILayout.Height(400f));
rect = GUILayoutUtility.GetLastRect();
rect.height = 400f;
Rect rectView = new Rect(0f, 0f, _nameCellSize.x + _cellsize.x * _processesList.Count, _nameCellSize.y + _cellsize.y * _systems.Length);
_position = GUI.BeginScrollView(rect, _position, rectView, true, true);
List<string> systeNames = new List<string>();
var blackStyle = EcsEditor.GetStyle(Color.black, 0.04f);
var whiteStyle = EcsEditor.GetStyle(Color.white, 0.04f);
GUIContent label = new GUIContent();
Vector2 pivod = _nameCellSize;
rect = new Rect();
rect.y = _nameCellSize.y;
rect.width = _nameCellSize.x;
rect.height = _cellsize.x;
rect.y -= _cellsize.y;
for (int i = 0; i < _processesList.Count; i++)
{
lineRect = rect;
lineRect.y = 0f;
lineRect.x = _nameCellSize.x + _cellsize.x * i;
lineRect.width = _cellsize.x;
lineRect.height = rectView.height;
GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle);
GUIUtility.RotateAroundPivot(90, pivod);
//GUIContent label = new GUIContent(_processesList[i].name, "." + _processesList[i].name);
label.text = _processesList[i].name;
label.tooltip = "." + _processesList[i].name;
GUI.Label(rect, label, EditorStyles.miniBoldLabel);
GUIUtility.RotateAroundPivot(-90, pivod);
pivod.x += _cellsize.x;
rect.x += _cellsize.x;
}
//GUIUtility.RotateAroundPivot(-90, _nameCellSize);
rect = new Rect();
rect.y = _nameCellSize.y;
rect.width = _nameCellSize.x;
rect.height = _cellsize.x;
for (int i = 0; i < _systems.Length; i++)
{
string name = EcsEditor.GetGenericName(_systems[i].GetType());
systeNames.Add(name);
lineRect = rect;
lineRect.width = rectView.width;
GUI.Label(lineRect, "", i % 2 == 1 ? whiteStyle : blackStyle);
// GUIContent label = new GUIContent(name, i + " " + name);
label.text = name;
label.tooltip = i + " " + name;
GUI.Label(rect, label, EditorStyles.miniBoldLabel);
rect.y += _cellsize.y;
}
for (int x = 0; x < _processesList.Count; x++)
{
var process = _processesList[x];
for (int y = 0; y < _systems.Length; y++)
{
string systemName = systeNames[x];
rect = new Rect(x * _cellsize.x + _nameCellSize.x, y * _cellsize.y + _nameCellSize.y, _cellsize.x, _cellsize.y);
bool flag = process.systemsBitMask[y];
string labeltext = flag ? "^" : " ";
label.text = labeltext;
label.tooltip = $"{process.name}-{systemName}";
GUI.Label(rect, label);
//GUI.Label(rect, lable, flag ? whiteStyle : blackStyle);
// GUI.Label(rect, label, EditorStyles.helpBox);
}
}
GUI.EndScrollView();
}
private class ProcessData
{
public Type interfaceType;
public string name;
public BitMask systemsBitMask;
} }
} }
#endif
} }
#endif

View File

@ -1,10 +1,11 @@
using DCFApixels.DragonECS.Unity.Debug; using DCFApixels.DragonECS.Unity.Debug;
using UnityEngine; using UnityEngine;
using System.Linq;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
[DebugHide, DebugColor(DebugColor.Gray)] [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)]
public class WorldDebugSystem : IEcsRunProcess public class WorldDebugSystem : IEcsRun
{ {
private string _monitorName; private string _monitorName;
private EcsWorld _ecsWorld; private EcsWorld _ecsWorld;
@ -27,7 +28,7 @@ namespace DCFApixels.DragonECS
poolsmonitor.monitorName = "pools"; poolsmonitor.monitorName = "pools";
} }
public void Run(EcsPipeline pipeline) public void Run()
{ {
} }
} }
@ -65,116 +66,112 @@ namespace DCFApixels.DragonECS
internal WorldDebugSystem source; internal WorldDebugSystem source;
internal EcsWorld world; internal EcsWorld world;
} }
}
#if UNITY_EDITOR #if UNITY_EDITOR
namespace Editors namespace DCFApixels.DragonECS.Unity.Editors
{
using UnityEditor;
[CustomEditor(typeof(WorldPoolsMonitor))]
public class WorldPoolsMonitorEditor : Editor
{ {
using System.Linq; private static Vector2 _poolBlockMinSize = new Vector2(80, 160);
using System.Reflection; private static Vector2 _poolProgressBasrSize = _poolBlockMinSize * new Vector2(1f, 0.8f);
using UnityEditor;
[CustomEditor(typeof(WorldPoolsMonitor))] private WorldPoolsMonitor Target => (WorldPoolsMonitor)target;
public class WorldPoolsMonitorEditor : Editor
private Vector2 _scroll;
public override void OnInspectorGUI()
{ {
private static Vector2 _poolBlockMinSize = new Vector2(80, 160); _scroll = GUILayout.BeginScrollView(_scroll, GUILayout.Height(800f));
private static Vector2 _poolProgressBasrSize = _poolBlockMinSize * new Vector2(1f, 0.8f);
private WorldPoolsMonitor Target => (WorldPoolsMonitor)target; var pools = Target.world.AllPools.ToArray().Where(o => !o.IsNullOrDummy()).OfType<IEcsPool>();
private Vector2 _scroll; GUILayout.Label("", GUILayout.ExpandWidth(true));
public override void OnInspectorGUI() float width = GUILayoutUtility.GetLastRect().width;
Vector3 newPoolBlockSize = _poolBlockMinSize;
int widthCount = Mathf.Max(1, Mathf.Min((Mathf.FloorToInt(width / _poolBlockMinSize.x)), pools.Count()));
newPoolBlockSize.x = width / widthCount;
int x = -1, y = 0;
foreach (var pool in pools)
{ {
_scroll = GUILayout.BeginScrollView(_scroll, GUILayout.Height(800f)); if (++x >= widthCount)
var pools = Target.world.AllPools.ToArray().Where(o => !o.IsNullOrDummy()).OfType<IEcsPool>();
GUILayout.Label("", GUILayout.ExpandWidth(true));
float width = GUILayoutUtility.GetLastRect().width;
Vector3 newPoolBlockSize = _poolBlockMinSize;
int widthCount = Mathf.Max(1, Mathf.Min((Mathf.FloorToInt(width / _poolBlockMinSize.x)), pools.Count()));
newPoolBlockSize.x = width / widthCount;
int x = -1, y = 0;
foreach (var pool in pools)
{ {
if (++x >= widthCount) x = 0;
{ y++;
x = 0;
y++;
}
DrawPoolBlock(pool, new Rect(newPoolBlockSize.x * x, newPoolBlockSize.y * y, newPoolBlockSize.x, newPoolBlockSize.y));
} }
GUILayout.EndScrollView();
DrawPoolBlock(pool, new Rect(newPoolBlockSize.x * x, newPoolBlockSize.y * y, newPoolBlockSize.x, newPoolBlockSize.y));
} }
GUILayout.EndScrollView();
}
/// Äåôîëòíûé öâåò äëÿ ïóëà: new Color(0.3f, 1f, 0f, 1f);
private void DrawPoolBlock(IEcsPool pool, Rect position) private void DrawPoolBlock(IEcsPool pool, Rect position)
{ {
int count = pool.Count; var meta = pool.GetMeta();
int capacity = pool.Capacity < 0 ? count : pool.Capacity;
Color defaultContentColor = GUI.contentColor; int count = pool.Count;
GUI.contentColor = Color.black * 0.925f; int capacity = pool.Capacity < 0 ? count : pool.Capacity;
position = AddMargin(position, 1f, 1f); Color defaultContentColor = GUI.contentColor;
GUI.contentColor = Color.black * 0.925f;
EditorGUI.DrawRect(position, Color.black * 0.16f); position = AddMargin(position, 1f, 1f);
Rect progressBar = new Rect(Vector2.zero, _poolProgressBasrSize); EditorGUI.DrawRect(position, Color.black * 0.16f);
progressBar.width = position.width;
progressBar.center = position.center - Vector2.up * _poolBlockMinSize.y * 0.09f;
Rect progressBar = new Rect(Vector2.zero, _poolProgressBasrSize);
progressBar.width = position.width;
progressBar.center = position.center - Vector2.up * _poolBlockMinSize.y * 0.09f;
Color mainColor = new Color(0.3f, 1f, 0f, 1f); Color mainColor = meta.Color.ToUnityColor();
var debugColor = pool.ComponentType.GetCustomAttribute<DebugColorAttribute>(); Color backgroundColor = mainColor * 0.3f + Color.white * 0.2f;
if (debugColor != null)
{
mainColor = debugColor.GetUnityColor();
}
Color backgroundColor = mainColor * 0.3f + Color.white * 0.2f;
EditorGUI.DrawRect(progressBar, backgroundColor); EditorGUI.DrawRect(progressBar, backgroundColor);
progressBar.yMin = progressBar.yMax - ((float)count / capacity) * progressBar.height; progressBar.yMin = progressBar.yMax - ((float)count / capacity) * progressBar.height;
GUIStyle textStyle0 = new GUIStyle(EditorStyles.miniBoldLabel); GUIStyle textStyle0 = new GUIStyle(EditorStyles.miniBoldLabel);
textStyle0.alignment = TextAnchor.MiddleCenter; textStyle0.alignment = TextAnchor.MiddleCenter;
Color foregroundColor = mainColor; Color foregroundColor = mainColor;
EditorGUI.DrawRect(progressBar, foregroundColor); EditorGUI.DrawRect(progressBar, foregroundColor);
GUI.Label(progressBar, count.ToString(), textStyle0); GUI.Label(progressBar, count.ToString(), textStyle0);
GUIStyle textStyle1 = new GUIStyle(EditorStyles.miniBoldLabel); GUIStyle textStyle1 = new GUIStyle(EditorStyles.miniBoldLabel);
textStyle1.alignment = TextAnchor.UpperCenter; textStyle1.alignment = TextAnchor.UpperCenter;
GUI.Label(AddMargin(position, 3f, 3f), "Total\r\n" + capacity, textStyle1); GUI.Label(AddMargin(position, 3f, 3f), "Total\r\n" + capacity, textStyle1);
GUI.contentColor = defaultContentColor; GUI.contentColor = defaultContentColor;
GUIStyle textStyle2 = new GUIStyle(EditorStyles.miniBoldLabel); GUIStyle textStyle2 = new GUIStyle(EditorStyles.miniBoldLabel);
textStyle2.wordWrap = true; textStyle2.wordWrap = true;
textStyle2.alignment = TextAnchor.LowerCenter; textStyle2.alignment = TextAnchor.LowerCenter;
string name = EcsEditor.GetGenericName(pool.ComponentType); string name = EcsEditor.GetGenericName(pool.ComponentType);
GUIContent label = new GUIContent(name, $"{name} e:{count}"); GUIContent label = new GUIContent(name, $"{name} e:{count}");
GUI.Label(AddMargin(position, -10f, 3f), label, textStyle2); GUI.Label(AddMargin(position, -10f, 3f), label, textStyle2);
} }
private Rect AddMargin(Rect rect, Vector2 value) private Rect AddMargin(Rect rect, Vector2 value)
{ {
return AddMargin(rect, value.x, value.y); return AddMargin(rect, value.x, value.y);
} }
private Rect AddMargin(Rect rect, float x, float y) private Rect AddMargin(Rect rect, float x, float y)
{ {
rect.yMax -= y; rect.yMax -= y;
rect.yMin += y; rect.yMin += y;
rect.xMax -= x; rect.xMax -= x;
rect.xMin += x; rect.xMin += x;
return rect; return rect;
}
} }
} }
#endif
} }
#endif

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d8c6da13649cc094e80f3ec624bad02b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,251 @@
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Reflection;
#if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors
{
using UnityEditor;
using UnityEngine;
public abstract class EntityTemplateEditorBase : Editor
{
private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 15f, 15f);
private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 15f, 15f);
private GUIStyle removeButtonStyle;
private GenericMenu genericMenu;
private bool _isInit = false;
#region Init
private void Init()
{
if (genericMenu == null)
_isInit = false;
if (_isInit)
return;
var tmpstylebase = EcsEditor.GetStyle(new Color(0.9f, 0f, 0.22f), 0.5f);
var tmpStyle = EcsEditor.GetStyle(new Color(1f, 0.5f, 0.7f), 0.5f);
removeButtonStyle = new GUIStyle(EditorStyles.linkLabel);
removeButtonStyle.alignment = TextAnchor.MiddleCenter;
removeButtonStyle.normal = tmpstylebase.normal;
removeButtonStyle.hover = tmpStyle.normal;
removeButtonStyle.active = tmpStyle.normal;
removeButtonStyle.focused = tmpStyle.normal;
removeButtonStyle.padding = new RectOffset(0, 0, 0, 0);
removeButtonStyle.margin = new RectOffset(0, 0, 0, 0);
removeButtonStyle.border = new RectOffset(0, 0, 0, 0);
genericMenu = new GenericMenu();
var dummies = ComponentTemplateTypeCache.Dummies;
foreach (var dummy in dummies)
{
string name = dummy.Name;
string description = dummy.Description;
if (string.IsNullOrEmpty(description) == false)
{
name = $"{name} {EcsUnityConsts.INFO_MARK}";
}
genericMenu.AddItem(new GUIContent(name, description), false, OnAddComponent, dummy);
}
_isInit = true;
}
#endregion
#region Add/Remove
private void OnAddComponent(object obj)
{
Type componentType = obj.GetType();
if (this.target is ITemplateInternal target)
{
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
for (int i = 0; i < componentsProp.arraySize; i++)
{
if (componentsProp.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType)
return;
}
componentsProp.InsertArrayElementAtIndex(0);
componentsProp.GetArrayElementAtIndex(0).managedReferenceValue = ((IComponentTemplate)obj).Clone();
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(this.target);
}
}
private void OnRemoveComponentAt(int index)
{
if (this.target is ITemplateInternal target)
{
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
componentsProp.DeleteArrayElementAtIndex(index);
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(this.target);
}
}
#endregion
protected void Draw(ITemplateInternal target)
{
Init();
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
if (componentsProp == null)
return;
DrawTop(target);
for (int i = 0; i < componentsProp.arraySize; i++)
{
DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i);
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * 2);
}
DrawFooter(target);
}
private void DrawTop(ITemplateInternal target)
{
if (GUILayout.Button("Add Component", GUILayout.Height(24f)))
{
Init();
genericMenu.ShowAsContext();
}
}
private void DrawFooter(ITemplateInternal target)
{
if (GUILayout.Button("Clear", GUILayout.Height(24f)))
{
Init();
serializedObject.FindProperty(target.ComponentsPropertyName).ClearArray();
serializedObject.ApplyModifiedProperties();
}
}
private void DrawComponentData(SerializedProperty componentRefProp, int index)
{
IComponentTemplate template = componentRefProp.managedReferenceValue as IComponentTemplate;
if (template == null)
{
DrawDamagedComponent(componentRefProp, index);
return;
}
if (componentRefProp.managedReferenceValue == null)
{
DrawDamagedComponent(componentRefProp, index);
return;
}
Type initializerType;
Type componentType;
SerializedProperty componentProperty = componentRefProp;
ComponentTemplateBase customInitializer = componentProperty.managedReferenceValue as ComponentTemplateBase;
if (customInitializer != null)
{
componentProperty = componentRefProp.FindPropertyRelative("component");
initializerType = customInitializer.Type;
componentType = customInitializer.GetType().GetField("component", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FieldType;
}
else
{
initializerType = componentProperty.managedReferenceValue.GetType();
componentType = initializerType;
}
string name = template.Name;
string description = template.Description;
Color panelColor = template.Color;
GUILayout.BeginHorizontal();
GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.22f));
EditorGUI.BeginChangeCheck();
GUIContent label = new GUIContent(name);
if (componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0)
{
GUILayout.Label(label);
}
else
{
EditorGUILayout.PropertyField(componentProperty, label, true);
}
if (EditorGUI.EndChangeCheck())
{
componentProperty.serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
}
Rect lastrect = GUILayoutUtility.GetLastRect();
Rect removeButtonRect = RemoveButtonRect;
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);
GUILayout.Label("", GUILayout.Width(removeButtonRect.width));
if (GUI.Button(removeButtonRect, "x", removeButtonStyle))
OnRemoveComponentAt(index);
if (!string.IsNullOrEmpty(description))
{
Rect tooltipIconRect = TooltipIconRect;
tooltipIconRect.center = new Vector2(lastrect.xMax - removeButtonRect.width / 2f, lastrect.yMin + removeButtonRect.height / 2f);
GUIContent descriptionLabel = new GUIContent(EcsUnityConsts.INFO_MARK, description);
GUI.Label(tooltipIconRect, descriptionLabel, EditorStyles.boldLabel);
}
GUILayout.EndHorizontal();
}
private void DrawDamagedComponent(SerializedProperty componentRefProp, int index)
{
GUILayout.BeginHorizontal();
EditorGUILayout.HelpBox($"Damaged component. If the problem occurred after renaming a component or initializer. use MovedFromAttrubute", MessageType.Warning);
Rect lastrect = GUILayoutUtility.GetLastRect();
Rect removeButtonRect = RemoveButtonRect;
removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f);
GUILayout.Label("", GUILayout.Width(removeButtonRect.width));
if (GUI.Button(removeButtonRect, "x", removeButtonStyle))
OnRemoveComponentAt(index);
GUILayout.EndHorizontal();
}
public string GetLastPathComponent(string input)
{
int lastSlashIndex = input.LastIndexOfAny(new char[] { '/', '\\' });
if (lastSlashIndex == -1)
return input;
else
return input.Substring(lastSlashIndex + 1);
}
}
[CustomEditor(typeof(ScriptableEntityTemplate), true)]
public class EntityTemplatePresetEditor : EntityTemplateEditorBase
{
public override void OnInspectorGUI()
{
Draw((ITemplateInternal)target);
}
}
[CustomEditor(typeof(MonoEntityTemplate), true)]
public class EntityTemplateEditor : EntityTemplateEditorBase
{
public override void OnInspectorGUI()
{
Draw((ITemplateInternal)target);
}
}
}
#endif

View File

@ -1,49 +0,0 @@
using UnityEngine;
namespace DCFApixels.DragonECS
{
public class EntityTemplate : MonoBehaviour, ITemplateInternal
{
[SerializeReference]
private ITemplateComponent[] _components;
string ITemplateInternal.ComponentsPropertyName => nameof(_components);
public void Apply(EcsWorld world, int entityID)
{
foreach (var item in _components)
item.Add(world, entityID);
}
private void OnValidate()
{
if (_components == null) return;
foreach (var item in _components)
{
if (item is ITemplateComponentOnValidate g)
g.OnValidate(gameObject);
}
}
private void OnDrawGizmos()
{
if (_components == null) return;
foreach (var item in _components)
{
if (item is ITemplateComponentGizmos g)
g.OnGizmos(transform, ITemplateComponentGizmos.Mode.Always);
}
}
private void OnDrawGizmosSelected()
{
if (_components == null) return;
foreach (var item in _components)
{
if (item is ITemplateComponentGizmos g)
g.OnGizmos(transform, ITemplateComponentGizmos.Mode.Selected);
}
}
public void Clear()
{
_components = new ITemplateComponent[0];
}
}
}

View File

@ -1,260 +0,0 @@
using System;
using System.Reflection;
namespace DCFApixels.DragonECS
{
#if UNITY_EDITOR
namespace Editors
{
using UnityEditor;
using UnityEngine;
public abstract class EntityTemplateEditorBase : Editor
{
private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 15f, 15f);
private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 15f, 15f);
private GUIStyle removeButtonStyle;
private GenericMenu genericMenu;
private bool _isInit = false;
#region Init
private void Init()
{
if (genericMenu == null)
_isInit = false;
if (_isInit)
return;
var tmpstylebase = EcsEditor.GetStyle(new Color(0.9f, 0f, 0.22f), 0.5f);
var tmpStyle = EcsEditor.GetStyle(new Color(1f, 0.5f, 0.7f), 0.5f);
removeButtonStyle = new GUIStyle(EditorStyles.linkLabel);
removeButtonStyle.alignment = TextAnchor.MiddleCenter;
removeButtonStyle.normal = tmpstylebase.normal;
removeButtonStyle.hover = tmpStyle.normal;
removeButtonStyle.active = tmpStyle.normal;
removeButtonStyle.focused = tmpStyle.normal;
removeButtonStyle.padding = new RectOffset(0, 0, 0, 0);
removeButtonStyle.margin = new RectOffset(0, 0, 0, 0);
removeButtonStyle.border = new RectOffset(0, 0, 0, 0);
genericMenu = new GenericMenu();
var dummies = TemplateBrowsableTypeCache.Dummies;
foreach (var dummy in dummies)
{
string name, description;
if (dummy is ITemplateComponentName browsableName)
name = browsableName.Name;
else
name = EcsEditor.GetName(dummy.GetType());
if (dummy is TemplateComponentInitializerBase initializer)
description = initializer.Description;
else
description = EcsEditor.GetDescription(dummy.GetType());
if (!string.IsNullOrEmpty(description))
{
name = $"{name} {EcsUnityConsts.INFO_MARK}";
}
genericMenu.AddItem(new GUIContent(name, description), false, OnAddComponent, dummy);
}
_isInit = true;
}
#endregion
#region Add/Remove
private void OnAddComponent(object obj)
{
Type componentType = obj.GetType();
if (this.target is ITemplateInternal target)
{
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
for (int i = 0; i < componentsProp.arraySize; i++)
{
if (componentsProp.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType)
return;
}
componentsProp.InsertArrayElementAtIndex(0);
componentsProp.GetArrayElementAtIndex(0).managedReferenceValue = ((ITemplateComponent)obj).Clone();
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(this.target);
}
}
private void OnRemoveComponentAt(int index)
{
if (this.target is ITemplateInternal target)
{
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
componentsProp.DeleteArrayElementAtIndex(index);
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(this.target);
}
}
#endregion
protected void Draw(ITemplateInternal target)
{
Init();
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
if (componentsProp == null)
return;
DrawTop(target);
for (int i = 0; i < componentsProp.arraySize; i++)
{
DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i);
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * 2);
}
DrawFooter(target);
}
private void DrawTop(ITemplateInternal target)
{
if (GUILayout.Button("Add Component", GUILayout.Height(24f)))
{
Init();
genericMenu.ShowAsContext();
}
}
private void DrawFooter(ITemplateInternal target)
{
if (GUILayout.Button("Clear", GUILayout.Height(24f)))
{
Init();
serializedObject.FindProperty(target.ComponentsPropertyName).ClearArray();
serializedObject.ApplyModifiedProperties();
}
}
private void DrawComponentData(SerializedProperty componentRefProp, int index)
{
ITemplateComponent browsable = componentRefProp.managedReferenceValue as ITemplateComponent;
if (browsable == null)
{
DrawDamagedComponent(componentRefProp, index);
return;
}
ITemplateComponentName browsableName = browsable as ITemplateComponentName;
if (componentRefProp.managedReferenceValue == null)
{
DrawDamagedComponent(componentRefProp, index);
return;
}
Type initializerType;
Type componentType;
SerializedProperty componentProperty = componentRefProp;
TemplateComponentInitializerBase customInitializer = componentProperty.managedReferenceValue as TemplateComponentInitializerBase;
if (customInitializer != null)
{
componentProperty = componentRefProp.FindPropertyRelative("component");
initializerType = customInitializer.Type;
componentType = customInitializer.GetType().GetField("component", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FieldType;
}
else
{
initializerType = componentProperty.managedReferenceValue.GetType();
componentType = initializerType;
}
Type type = browsable.GetType();
string name = browsableName == null ? type.Name : GetLastPathComponent(browsableName.Name);
string description = customInitializer != null ? customInitializer.Description : initializerType.GetCustomAttribute<DebugDescriptionAttribute>()?.description;
// Color panelColor = customInitializer != null ? customInitializer.Color : initializerType.GetCustomAttribute<DebugColorAttribute>()?.GetUnityColor() ?? Color.black;
Color panelColor = customInitializer != null ? customInitializer.Color : EcsDebugUtility.GetColor(initializerType).ToUnityColor();
GUILayout.BeginHorizontal();
GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.2f));
EditorGUI.BeginChangeCheck();
GUIContent label = new GUIContent(name, $"{name} ");
if (componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0)
{
GUILayout.Label(label);
}
else
{
EditorGUILayout.PropertyField(componentProperty, label, true);
}
if (EditorGUI.EndChangeCheck())
{
componentProperty.serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
}
Rect lastrect = GUILayoutUtility.GetLastRect();
Rect removeButtonRect = RemoveButtonRect;
removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f);
GUILayout.EndVertical();
GUILayout.Label("", GUILayout.Width(removeButtonRect.width));
if (GUI.Button(removeButtonRect, "x", removeButtonStyle))
OnRemoveComponentAt(index);
if (!string.IsNullOrEmpty(description))
{
Rect tooltipIconRect = TooltipIconRect;
tooltipIconRect.center = new Vector2(lastrect.xMax - removeButtonRect.width / 2f, lastrect.yMin + removeButtonRect.height / 2f);
GUIContent descriptionLabel = new GUIContent(EcsUnityConsts.INFO_MARK, description);
GUI.Label(tooltipIconRect, descriptionLabel, EditorStyles.boldLabel);
}
GUILayout.EndHorizontal();
}
private void DrawDamagedComponent(SerializedProperty componentRefProp, int index)
{
GUILayout.BeginHorizontal();
EditorGUILayout.HelpBox($"Damaged component. If the problem occurred after renaming a component or initializer. use MovedFromAttrubute", MessageType.Warning);
Rect lastrect = GUILayoutUtility.GetLastRect();
Rect removeButtonRect = RemoveButtonRect;
removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f);
GUILayout.Label("", GUILayout.Width(removeButtonRect.width));
if (GUI.Button(removeButtonRect, "x", removeButtonStyle))
OnRemoveComponentAt(index);
GUILayout.EndHorizontal();
}
public string GetLastPathComponent(string input)
{
int lastSlashIndex = input.LastIndexOfAny(new char[] { '/', '\\' });
if (lastSlashIndex == -1)
return input;
else
return input.Substring(lastSlashIndex + 1);
}
}
[CustomEditor(typeof(EntityTemplatePreset), true)]
public class EntityTemplatePresetEditor : EntityTemplateEditorBase
{
public override void OnInspectorGUI()
{
Draw((ITemplateInternal)target);
}
}
[CustomEditor(typeof(EntityTemplate), true)]
public class EntityTemplateEditor : EntityTemplateEditorBase
{
public override void OnInspectorGUI()
{
Draw((ITemplateInternal)target);
}
}
}
#endif
}

View File

@ -1,29 +0,0 @@
using UnityEngine;
namespace DCFApixels.DragonECS
{
[CreateAssetMenu(fileName = "EntityTemplatePreset", menuName = EcsConsts.FRAMEWORK_NAME + "/EntityTemplatePreset", order = 1)]
public class EntityTemplatePreset : ScriptableObject, ITemplateInternal
{
[SerializeReference]
private ITemplateComponent[] _components;
string ITemplateInternal.ComponentsPropertyName => nameof(_components);
//ITemplateBrowsable[] ITemplateInternal.Components
//{
// get => _components;
// set => _components = value;
//}
public void Apply(EcsWorld world, int entityID)
{
foreach (var item in _components)
item.Add(world, entityID);
}
public void Clear()
{
_components = new ITemplateComponent[0];
}
}
}

View File

@ -1,23 +0,0 @@
namespace DCFApixels.DragonECS
{
public interface ITemplate
{
public void Apply(EcsWorld world, int entityID);
}
public interface ITemplateInternal : ITemplate
{
// internal ITemplateBrowsable[] Components { get; set; }
internal string ComponentsPropertyName { get; }
}
public static class ITemplateExt
{
public static int NewEntity(this ITemplate self, EcsWorld world)
{
int e = world.NewEmptyEntity();
self.Apply(world, e);
return e;
}
}
}

View File

@ -0,0 +1,57 @@
namespace DCFApixels.DragonECS
{
public interface ITemplateNode
{
void Apply(int worldID, int entityID);
}
public interface ITemplate : ITemplateNode
{
//void Add(ITemplateNode template);
//void Remove(ITemplateNode template);
}
public interface ITemplateInternal : ITemplate
{
string ComponentsPropertyName { get; }
//EntityTemplateInheritanceMatrix InheritanceMatrix { get; }
}
public static class ITemplateExtensions
{
public static int NewEntity(this EcsWorld world, ITemplateNode template)
{
int e = world.NewEntity();
template.Apply(world.id, e);
return e;
}
public static entlong NewEntityLong(this EcsWorld world, ITemplateNode template)
{
entlong e = world.NewEntityLong();
template.Apply(world.id, e.ID);
return e;
}
public static entlong NewEntityWithGameObject(this EcsWorld world, ITemplateNode template, string name = "Entity", GameObjectIcon icon = GameObjectIcon.NONE)
{
entlong e = world.NewEntityWithGameObject(name, icon);
template.Apply(world.id, e.ID);
return e;
}
}
//[Serializable]
//public class EntityTemplateInheritanceMatrix
//{
// [SerializeReference]
// private ITemplateNode[] _components;
//
// #region Methods
// public void Apply(int worldID, int entityID)
// {
// foreach (var item in _components)
// {
// item.Apply(worldID, entityID);
// }
// }
// #endregion
//}
}

View File

@ -1,151 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
namespace DCFApixels.DragonECS
{
public interface ITemplateComponent
{
public void Add(EcsWorld w, int e);
}
public interface ITemplateComponentName : ITemplateComponent
{
public string Name { get; }
}
public interface ITemplateComponentGizmos
{
public void OnGizmos(Transform transform, Mode mode);
public enum Mode
{
Always,
Selected
}
}
public interface ITemplateComponentOnValidate
{
public void OnValidate(GameObject gameObject);
}
[Serializable]
public abstract class TemplateComponentInitializerBase
{
public virtual string Name => string.Empty;
public virtual Color Color => Color.black;
public virtual string Description => string.Empty;
public abstract Type Type { get; }
internal abstract object ComponentRef { get; }
#region Get meta
internal static Color GetColor(Type type)
{
//var atr = type.GetCustomAttribute<DebugColorAttribute>();
//if (atr == null) return Color.black;
//return atr.GetUnityColor();
return EcsDebugUtility.GetColor(type).ToUnityColor();
}
internal static string GetName(Type type)
{
string friendlyName = type.Name;
if (type.IsGenericType)
{
int iBacktick = friendlyName.IndexOf('`');
if (iBacktick > 0)
friendlyName = friendlyName.Remove(iBacktick);
friendlyName += "/" + friendlyName;
friendlyName += "<";
Type[] typeParameters = type.GetGenericArguments();
for (int i = 0; i < typeParameters.Length; ++i)
{
string typeParamName = GetName(typeParameters[i]);
friendlyName += (i == 0 ? typeParamName : "," + typeParamName);
}
friendlyName += ">";
}
return friendlyName;
}
internal static string GetDescription(Type type)
{
var atr = type.GetCustomAttribute<DebugDescriptionAttribute>();
if (atr == null) return string.Empty;
return atr.description;
}
#endregion
}
[Serializable]
public abstract class TemplateComponentInitializer<T> : TemplateComponentInitializerBase, ITemplateComponentName, ITemplateComponentGizmos, ITemplateComponentOnValidate
{
private static string _autoname = GetName(typeof(T));
private static Color _autoColor = GetColor(typeof(T));
private static string _autoDescription = GetDescription(typeof(T));
[SerializeField]
protected T component;
#region Properties
public override string Name => _autoname;
public override Color Color => _autoColor;
public override string Description => _autoDescription;
public sealed override Type Type => typeof(T);
internal T Component => component;
internal override object ComponentRef => component;
#endregion
public abstract void Add(EcsWorld w, int e);
public virtual void OnGizmos(Transform transform, ITemplateComponentGizmos.Mode mode) { }
public virtual void OnValidate(GameObject gameObject) { }
}
internal static class ITemplateBrowsableExt
{
private static MethodInfo memberwiseCloneMethdo = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);
internal static ITemplateComponent Clone(this ITemplateComponent obj)
{
return (ITemplateComponent)memberwiseCloneMethdo.Invoke(obj, null);
}
}
#if UNITY_EDITOR
namespace Editors
{
internal static class TemplateBrowsableTypeCache
{
private static Type[] _types;
private static ITemplateComponent[] _dummies;
internal static ReadOnlySpan<Type> Types => _types;
internal static ReadOnlySpan<ITemplateComponent> Dummies => _dummies;
static TemplateBrowsableTypeCache()
{
List<Type> types = new List<Type>();
Type interfaceType = typeof(ITemplateComponent);
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var targetTypes = assembly.GetTypes().Where(type => !type.IsGenericType && (type.IsValueType || type.IsClass) && type.GetCustomAttribute<SerializableAttribute>() != null);
types.AddRange(targetTypes.Where(type => interfaceType.IsAssignableFrom(type)));
foreach (var t in targetTypes)
{
if (t.IsSubclassOf(typeof(TemplateComponentInitializer<>)))
{
if (t.HasAttribute<SerializableAttribute>())
types.Add(t);
}
}
}
_types = types.ToArray();
_dummies = new ITemplateComponent[_types.Length];
for (int i = 0; i < _types.Length; i++)
_dummies[i] = (ITemplateComponent)Activator.CreateInstance(_types[i]);
}
}
}
#endif
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 14555d6350df03d448d362de7b6a31c1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,157 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using static DCFApixels.DragonECS.IComponentTemplate;
namespace DCFApixels.DragonECS
{
public interface IComponentTemplate : ITemplateNode
{
#region Properties
Type Type { get; }
string Name { get; }
MetaGroup Group { get; }
string Description { get; }
IReadOnlyCollection<string> Tags { get; }
Color Color { get; }
#endregion
#region Methods
object GetRaw();
void SetRaw(object raw);
void OnGizmos(Transform transform, GizmosMode mode);
void OnValidate(UnityEngine.Object obj);
#endregion
public enum GizmosMode
{
Always,
Selected
}
}
[Serializable]
public abstract class ComponentTemplateBase : IComponentTemplate
{
#region Properties
public abstract Type Type { get; }
public virtual string Name { get { return string.Empty; } }
public virtual MetaGroup Group { get { return default; } }
public virtual string Description { get { return string.Empty; } }
public virtual IReadOnlyCollection<string> Tags { get { return Array.Empty<string>(); } }
public virtual Color Color { get { return Color.black; } }
#endregion
#region Methods
public abstract object GetRaw();
public abstract void SetRaw(object raw);
public virtual void OnGizmos(Transform transform, GizmosMode mode) { }
public virtual void OnValidate(UnityEngine.Object obj) { }
public abstract void Apply(int worldID, int entityID);
#endregion
}
[Serializable]
public abstract class ComponentTemplateBase<T> : ComponentTemplateBase, IComponentTemplate
{
private static TypeMetaDataCached _meta = EcsDebugUtility.GetCachedTypeMeta<T>();
[SerializeField]
protected T component;
#region Properties
public override Type Type { get { return typeof(T); } }
public override string Name { get { return _meta.Name; } }
public override MetaGroup Group { get { return _meta.Group; } }
public override string Description { get { return _meta.Description; } }
public override IReadOnlyCollection<string> Tags { get { return _meta.Tags; } }
public override Color Color { get { return _meta.Color.ToUnityColor(); } }
#endregion
#region Methods
public override object GetRaw()
{
return component;
}
public override void SetRaw(object raw)
{
component = (T)raw;
}
#endregion
}
public abstract class ComponentTemplate<T> : ComponentTemplateBase<T>, IComponentTemplate
where T : struct, IEcsComponent
{
public override void Apply(int worldID, int entityID)
{
EcsWorld.GetPool<EcsPool<T>>(worldID).TryAddOrGet(entityID) = component;
}
}
public abstract class TagComponentTemplate<T> : ComponentTemplateBase<T>, IComponentTemplate
where T : struct, IEcsTagComponent
{
public override void Apply(int worldID, int entityID)
{
EcsWorld.GetPool<EcsTagPool<T>>(worldID).Set(entityID, true);
}
}
}
namespace DCFApixels.DragonECS.Unity.Internal
{
internal static class ComponentTemplateExtensions
{
private static MethodInfo memberwiseCloneMethdo = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);
internal static IComponentTemplate Clone(this IComponentTemplate obj)
{
return (IComponentTemplate)memberwiseCloneMethdo.Invoke(obj, null);
}
}
}
#if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors
{
internal static class ComponentTemplateTypeCache
{
private static Type[] _types;
private static IComponentTemplate[] _dummies;
internal static ReadOnlySpan<Type> Types => _types;
internal static ReadOnlySpan<IComponentTemplate> Dummies => _dummies;
static ComponentTemplateTypeCache()
{
List<Type> types = new List<Type>();
Type interfaceType = typeof(IComponentTemplate);
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var targetTypes = assembly.GetTypes().Where(type => !type.IsGenericType && !(type.IsAbstract || type.IsInterface) && type.GetCustomAttribute<SerializableAttribute>() != null);
types.AddRange(targetTypes.Where(type => interfaceType.IsAssignableFrom(type)));
foreach (var t in targetTypes)
{
if (t.IsSubclassOf(typeof(ComponentTemplateBase<>)))
{
types.Add(t);
}
}
}
_types = types.ToArray();
foreach (var type in _types)
{
EcsDebugUtility.GetCachedTypeMeta(type);
}
_dummies = new IComponentTemplate[_types.Length];
for (int i = 0; i < _types.Length; i++)
{
_dummies[i] = (IComponentTemplate)Activator.CreateInstance(_types[i]);
}
}
}
}
#endif

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 3c96e3aedd5a69443af75096e5561265 guid: b532f9d8441035d49b9acb99ea23c231
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -0,0 +1,65 @@
using System;
using UnityEngine;
namespace DCFApixels.DragonECS
{
public class MonoEntityTemplate : MonoBehaviour, ITemplateInternal
{
[SerializeReference]
private IComponentTemplate[] _components;
//[SerializeField]
//private EntityTemplateInheritanceMatrix _inheritanceMatrix;
#region Properties
string ITemplateInternal.ComponentsPropertyName
{
get { return nameof(_components); }
}
//EntityTemplateInheritanceMatrix ITemplateInternal.InheritanceMatrix
//{
// get { return _inheritanceMatrix; }
//}
#endregion
#region Methods
public void Apply(int worldID, int entityID)
{
foreach (var item in _components)
{
item.Apply(worldID, entityID);
}
}
public void Clear()
{
_components = Array.Empty<IComponentTemplate>();
}
#endregion
#region UnityEvents
private void OnValidate()
{
if (_components == null) { return; }
foreach (var item in _components)
{
item.OnValidate(gameObject);
}
}
private void OnDrawGizmos()
{
if (_components == null) { return; }
foreach (var item in _components)
{
item.OnGizmos(transform, IComponentTemplate.GizmosMode.Always);
}
}
private void OnDrawGizmosSelected()
{
if (_components == null) { return; }
foreach (var item in _components)
{
item.OnGizmos(transform, IComponentTemplate.GizmosMode.Selected);
}
}
#endregion
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 385a6c66660032944ad2cce7130715d7 guid: 351338ca92ace49499f450172d857af6
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -0,0 +1,50 @@
using System;
using UnityEngine;
namespace DCFApixels.DragonECS
{
[CreateAssetMenu(fileName = nameof(ScriptableEntityTemplate), menuName = EcsConsts.FRAMEWORK_NAME + "/" + nameof(ScriptableEntityTemplate), order = 1)]
public class ScriptableEntityTemplate : ScriptableObject, ITemplateInternal
{
[SerializeReference]
private IComponentTemplate[] _components;
//[SerializeField]
//private EntityTemplateInheritanceMatrix _inheritanceMatrix;
#region Properties
string ITemplateInternal.ComponentsPropertyName
{
get { return nameof(_components); }
}
//EntityTemplateInheritanceMatrix ITemplateInternal.InheritanceMatrix
//{
// get { return _inheritanceMatrix; }
//}
#endregion
#region Methods
public void Apply(int worldID, int entityID)
{
foreach (var item in _components)
{
item.Apply(worldID, entityID);
}
}
public void Clear()
{
_components = Array.Empty<IComponentTemplate>();
}
#endregion
#region UnityEvents
private void OnValidate()
{
if (_components == null) { return; }
foreach (var item in _components)
{
item.OnValidate(this);
}
}
#endregion
}
}

View File

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

View File

@ -1,42 +0,0 @@
using DCFApixels.DragonECS.Internal;
using System.Collections.Generic;
namespace DCFApixels.DragonECS
{
[DebugHide, DebugColor(DebugColor.Grey)]
public class DeleteOneFrameComponentFixedSystem<TComponent> : IEcsFixedRunProcess, IEcsInject<EcsWorld>
where TComponent : struct, IEcsComponent
{
private sealed class Aspect : EcsAspect
{
public EcsPool<TComponent> pool;
public Aspect(Builder b) => pool = b.Include<TComponent>();
}
List<EcsWorld> _worlds = new List<EcsWorld>();
public void Inject(EcsWorld obj) => _worlds.Add(obj);
public void FixedRun(EcsPipeline pipeline)
{
for (int i = 0, iMax = _worlds.Count; i < iMax; i++)
{
EcsWorld world = _worlds[i];
if (world.IsComponentTypeDeclared<TComponent>())
{
foreach (var e in world.Where(out Aspect a))
a.pool.Del(e);
}
}
}
}
public static class DeleteOneFrameComponentFixedSystemExtensions
{
private const string AUTO_DEL_LAYER = nameof(AUTO_DEL_LAYER);
public static EcsPipeline.Builder AutoDelFixed<TComponent>(this EcsPipeline.Builder b, string layerName = AUTO_DEL_LAYER)
where TComponent : struct, IEcsComponent
{
if (AUTO_DEL_LAYER == layerName)
b.Layers.Insert(EcsConsts.POST_END_LAYER, AUTO_DEL_LAYER);
b.AddUnique(new DeleteOneFrameComponentSystem<TComponent>(), layerName);
return b;
}
}
}

View File

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

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS.Editors namespace DCFApixels.DragonECS.Unity.Internal
{ {
internal class BitMask internal class BitMask
{ {
@ -21,21 +21,30 @@ namespace DCFApixels.DragonECS.Editors
public bool this[int index] public bool this[int index]
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => (_data[index >> OFFSET] & (1 << (index & MOD_MASK))) != 0; get
{
return (_data[index >> OFFSET] & (1 << (index & MOD_MASK))) != 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
set set
{ {
if (value) if (value)
{
_data[index >> OFFSET] |= (1 << (index & MOD_MASK)); _data[index >> OFFSET] |= (1 << (index & MOD_MASK));
}
else else
{
_data[index >> OFFSET] &= ~(1 << (index & MOD_MASK)); _data[index >> OFFSET] &= ~(1 << (index & MOD_MASK));
}
} }
} }
public void Resize(int newSize) public void Resize(int newSize)
{ {
if (newSize <= _size) if (newSize <= _size)
{
return; return;
}
_size = newSize / DATA_BITS + 1; _size = newSize / DATA_BITS + 1;
Array.Resize(ref _data, _size); Array.Resize(ref _data, _size);

View File

@ -1,25 +0,0 @@
using UnityEngine;
namespace DCFApixels.DragonECS
{
public static class DebugColorAttributeExt
{
public static Color GetUnityColor(this DebugColorAttribute self)
{
return self.color.ToUnityColor();
}
public static Color32 GetUnityColor32(this DebugColorAttribute self)
{
return self.color.ToUnityColor32();
}
public static Color ToUnityColor(this DebugColor self)
{
return new Color(self.r / 255f, self.g / 255f, self.b / 255f, self.a / 255f);
}
public static Color32 ToUnityColor32(this DebugColor self)
{
return new Color32(self.r, self.g, self.b, self.a);
}
}
}

View File

@ -0,0 +1,16 @@
using UnityEngine;
namespace DCFApixels.DragonECS
{
public static class MetaColorExstensions
{
public static Color ToUnityColor<T>(this T self) where T : IMetaColor
{
return new Color(self.R / 255f, self.G / 255f, self.B / 255f, self.A / 255f);
}
public static Color32 ToUnityColor32<T>(this T self) where T : IMetaColor
{
return new Color32(self.R, self.G, self.B, self.A);
}
}
}

View File

@ -6,7 +6,7 @@ using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS.Editors namespace DCFApixels.DragonECS.Unity.Internal
{ {
internal class SparseArray<TValue> internal class SparseArray<TValue>
{ {