diff --git a/src/Extensions.meta b/src/Buildin.meta similarity index 77% rename from src/Extensions.meta rename to src/Buildin.meta index 4a9e845..e8b4de6 100644 --- a/src/Extensions.meta +++ b/src/Buildin.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 37d966ee996491b4d923ae68af4b67cd +guid: f2b9c91714b4752468a3a5691cbf5237 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/src/Buildin/EcsDefaultWorldProvider.cs b/src/Buildin/EcsDefaultWorldProvider.cs new file mode 100644 index 0000000..35d4f40 --- /dev/null +++ b/src/Buildin/EcsDefaultWorldProvider.cs @@ -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 + { + //private static EcsDefaultWorldProvider _singleInstance; + //public static EcsDefaultWorldProvider SingletonInstance + //{ + // get + // { + // if (_singleInstance == null) + // { + // _singleInstance = FindOrCreateSingleton(); + // } + // return _singleInstance; + // } + //} + } +} diff --git a/src/Connectors/EcsDefaultWorldProvider.cs.meta b/src/Buildin/EcsDefaultWorldProvider.cs.meta similarity index 100% rename from src/Connectors/EcsDefaultWorldProvider.cs.meta rename to src/Buildin/EcsDefaultWorldProvider.cs.meta diff --git a/src/Buildin/EcsDefaultWorldSingletonProvider.cs b/src/Buildin/EcsDefaultWorldSingletonProvider.cs new file mode 100644 index 0000000..956c326 --- /dev/null +++ b/src/Buildin/EcsDefaultWorldSingletonProvider.cs @@ -0,0 +1,23 @@ +namespace DCFApixels.DragonECS +{ + public class EcsDefaultWorldSingletonProvider : EcsWorldProvider + { + private static EcsDefaultWorldSingletonProvider _instance; + public static EcsDefaultWorldSingletonProvider Instance + { + get + { + if (_instance == null) + { + _instance = FindOrCreateSingleton("DefaultSingletonProvider"); + } + return _instance; + } + } + + protected override EcsDefaultWorld BuildWorld() + { + return new EcsDefaultWorld(); + } + } +} diff --git a/src/EntityTemplate/EntityTemplatePreset.cs.meta b/src/Buildin/EcsDefaultWorldSingletonProvider.cs.meta similarity index 83% rename from src/EntityTemplate/EntityTemplatePreset.cs.meta rename to src/Buildin/EcsDefaultWorldSingletonProvider.cs.meta index 10e7c2d..ee5180f 100644 --- a/src/EntityTemplate/EntityTemplatePreset.cs.meta +++ b/src/Buildin/EcsDefaultWorldSingletonProvider.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 54d84d8749e68c044b4f13a512808a67 +guid: 7592c6e5a68845c4abeac089e561d8c7 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Extensions/UnityComponents.cs b/src/Buildin/UnityComponents.cs similarity index 53% rename from src/Extensions/UnityComponents.cs rename to src/Buildin/UnityComponents.cs index 39c006f..c645acb 100644 --- a/src/Extensions/UnityComponents.cs +++ b/src/Buildin/UnityComponents.cs @@ -6,89 +6,93 @@ using UnityEngine; namespace DCFApixels.DragonECS { [Serializable] - [DebugColor(255 / 3, 255, 0)] + [MetaColor(255 / 3, 255, 0)] public struct UnityComponent : IEcsComponent, IEnumerable//IntelliSense hack where T : Component { public T obj; - public UnityComponent(T obj) => this.obj = obj; + public UnityComponent(T obj) + { + this.obj = obj; + } IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack } - - public class UnityComponentInitializer : TemplateComponentInitializer> where T : Component + #region Unity Component Templates + public class UnityComponentTemplate : ComponentTemplateBase> where T : Component { public override string Name => "UnityComponent/" + typeof(T).Name; - public sealed override void Add(EcsWorld w, int e) => w.GetPool>().Add(e) = component; - public override void OnValidate(GameObject gameObject) + public sealed override void Apply(int worldID, int entityID) + { + EcsWorld.GetPool>>(worldID).TryAddOrGet(entityID) = component; + } + public override void OnValidate(UnityEngine.Object obj) { if (component.obj == null) - component.obj = gameObject.GetComponent(); + { + if (obj is GameObject go) + { + component.obj = go.GetComponent(); + } + } } } + [Serializable] + public sealed class UnityComponentRigitBodyInitializer : UnityComponentTemplate { } + [Serializable] + public sealed class UnityComponentAnimatorInitializer : UnityComponentTemplate { } + [Serializable] + public sealed class UnityComponentCharacterControllerInitializer : UnityComponentTemplate { } + #endregion + #region Collider Templates [Serializable] - public sealed class UnityComponentRigitBodyInitializer : UnityComponentInitializer - { - } - - [Serializable] - public sealed class UnityComponentAnimatorInitializer : UnityComponentInitializer - { - } - [Serializable] - public sealed class UnityComponentCharacterControllerInitializer : UnityComponentInitializer - { - } - - #region Colliders - [Serializable] - public sealed class UnityComponentColliderInitializer : UnityComponentInitializer + public sealed class UnityComponentColliderTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Collider/" + nameof(Collider); } [Serializable] - public sealed class UnityComponentBoxColliderInitializer : UnityComponentInitializer + public sealed class UnityComponentBoxColliderTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Collider/" + nameof(BoxCollider); } [Serializable] - public sealed class UnityComponentSphereColliderInitializer : UnityComponentInitializer + public sealed class UnityComponentSphereColliderTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Collider/" + nameof(SphereCollider); } [Serializable] - public sealed class UnityComponentCapsuleColliderInitializer : UnityComponentInitializer + public sealed class UnityComponentCapsuleColliderTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Collider/" + nameof(CapsuleCollider); } [Serializable] - public sealed class UnityComponentMeshColliderInitializer : UnityComponentInitializer + public sealed class UnityComponentMeshColliderTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Collider/" + nameof(MeshCollider); } #endregion - #region Joints + #region Joint Templates [Serializable] - public sealed class UnityComponentJointInitializer : UnityComponentInitializer + public sealed class UnityComponentJointTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Joint/" + nameof(Joint); } [Serializable] - public sealed class UnityComponentFixedJointInitializer : UnityComponentInitializer + public sealed class UnityComponentFixedJointTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Joint/" + nameof(FixedJoint); } [Serializable] - public sealed class UnityComponentCharacterJointInitializer : UnityComponentInitializer + public sealed class UnityComponentCharacterJointTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Joint/" + nameof(CharacterJoint); } [Serializable] - public sealed class UnityComponentConfigurableJointInitializer : UnityComponentInitializer + public sealed class UnityComponentConfigurableJointTemplate : UnityComponentTemplate { public override string Name => "UnityComponent/Joint/" + nameof(ConfigurableJoint); } diff --git a/src/Extensions/UnityComponents.cs.meta b/src/Buildin/UnityComponents.cs.meta similarity index 83% rename from src/Extensions/UnityComponents.cs.meta rename to src/Buildin/UnityComponents.cs.meta index a32753d..5fb8d60 100644 --- a/src/Extensions/UnityComponents.cs.meta +++ b/src/Buildin/UnityComponents.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 47a8547ed46c26e4bb6a68651ad40be0 +guid: 637d69c48b6c0164abe654cd7f5ceb07 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Extensions/Runners.cs b/src/Buildin/UnityGameCyclieProcesses.cs similarity index 58% rename from src/Extensions/Runners.cs rename to src/Buildin/UnityGameCyclieProcesses.cs index 992136a..aa086c1 100644 --- a/src/Extensions/Runners.cs +++ b/src/Buildin/UnityGameCyclieProcesses.cs @@ -1,4 +1,5 @@ -using DCFApixels.DragonECS.RunnersCore; +using DCFApixels.DragonECS.Internal; +using DCFApixels.DragonECS.RunnersCore; namespace DCFApixels.DragonECS { @@ -10,7 +11,7 @@ namespace DCFApixels.DragonECS { public static void DrawGizmos(this EcsPipeline systems) { - systems.GetRunner().DrawGizmos(systems); + systems.GetRunnerInstance().DrawGizmos(systems); } } @@ -20,9 +21,9 @@ namespace DCFApixels.DragonECS } public static class IEcsLateRunSystemExtensions { - public static void LateRun(this EcsPipeline systems) + public static void LateRun(this EcsPipeline pipeline) { - systems.GetRunner().LateRun(systems); + pipeline.GetRunnerInstance().LateRun(pipeline); } } public interface IEcsFixedRunProcess : IEcsProcess @@ -33,14 +34,14 @@ namespace DCFApixels.DragonECS { public static void FixedRun(this EcsPipeline pipeline) { - pipeline.GetRunner().FixedRun(pipeline); + pipeline.GetRunnerInstance().FixedRun(pipeline); } } namespace Internal { - [DebugColor(DebugColor.Orange)] - public class EcsLateGizmosSystemRunner : EcsRunner, IEcsGizmosProcess + [MetaColor(MetaColor.Orange)] + public class EcsLateGizmosRunner : EcsRunner, IEcsGizmosProcess { #if DEBUG && !DISABLE_DEBUG private EcsProfilerMarker[] _markers; @@ -48,10 +49,10 @@ namespace DCFApixels.DragonECS public void DrawGizmos(EcsPipeline pipeline) { #if DEBUG && !DISABLE_DEBUG - for (int i = 0; i < targets.Length; i++) + for (int i = 0; i < Process.Length; i++) { using (_markers[i].Auto()) - targets[i].DrawGizmos(pipeline); + Process[i].DrawGizmos(pipeline); } #else foreach (var item in targets) item.DrawGizmos(pipeline); @@ -61,17 +62,17 @@ namespace DCFApixels.DragonECS #if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { - _markers = new EcsProfilerMarker[targets.Length]; - for (int i = 0; i < targets.Length; i++) + _markers = new EcsProfilerMarker[Process.Length]; + 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 } - [DebugColor(DebugColor.Orange)] - public class EcsLateRunSystemRunner : EcsRunner, IEcsLateRunProcess + [MetaColor(MetaColor.Orange)] + public class EcsLateRunRunner : EcsRunner, IEcsLateRunProcess { #if DEBUG && !DISABLE_DEBUG private EcsProfilerMarker[] _markers; @@ -79,10 +80,12 @@ namespace DCFApixels.DragonECS public void LateRun(EcsPipeline pipeline) { #if DEBUG && !DISABLE_DEBUG - for (int i = 0; i < targets.Length; i++) + for (int i = 0; i < Process.Length; i++) { using (_markers[i].Auto()) - targets[i].LateRun(pipeline); + { + Process[i].LateRun(pipeline); + } } #else foreach (var item in targets) item.LateRun(pipeline); @@ -92,16 +95,16 @@ namespace DCFApixels.DragonECS #if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { - _markers = new EcsProfilerMarker[targets.Length]; - for (int i = 0; i < targets.Length; i++) + _markers = new EcsProfilerMarker[Process.Length]; + 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 } - [DebugColor(DebugColor.Orange)] - public class EcsFixedRunSystemRunner : EcsRunner, IEcsFixedRunProcess + [MetaColor(MetaColor.Orange)] + public class EcsFixedRunRunner : EcsRunner, IEcsFixedRunProcess { #if DEBUG && !DISABLE_DEBUG private EcsProfilerMarker[] _markers; @@ -109,10 +112,12 @@ namespace DCFApixels.DragonECS public void FixedRun(EcsPipeline pipeline) { #if DEBUG && !DISABLE_DEBUG - for (int i = 0; i < targets.Length; i++) + for (int i = 0; i < Process.Length; i++) { using (_markers[i].Auto()) - targets[i].FixedRun(pipeline); + { + Process[i].FixedRun(pipeline); + } } #else foreach (var item in targets) item.FixedRun(pipeline); @@ -122,10 +127,10 @@ namespace DCFApixels.DragonECS #if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { - _markers = new EcsProfilerMarker[targets.Length]; - for (int i = 0; i < targets.Length; i++) + _markers = new EcsProfilerMarker[Process.Length]; + 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 diff --git a/src/EntityTemplate/TemplateComponent.cs.meta b/src/Buildin/UnityGameCyclieProcesses.cs.meta similarity index 83% rename from src/EntityTemplate/TemplateComponent.cs.meta rename to src/Buildin/UnityGameCyclieProcesses.cs.meta index 77e0d5d..f2b4894 100644 --- a/src/EntityTemplate/TemplateComponent.cs.meta +++ b/src/Buildin/UnityGameCyclieProcesses.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0ce52308e352f734e8a21c5ae282c246 +guid: 9b692b77d059ff445912bada1712ccab MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Extensions/UnityGameObject.cs b/src/Buildin/UnityGameObject.cs similarity index 90% rename from src/Extensions/UnityGameObject.cs rename to src/Buildin/UnityGameObject.cs index 83959b4..be8159c 100644 --- a/src/Extensions/UnityGameObject.cs +++ b/src/Buildin/UnityGameObject.cs @@ -6,7 +6,7 @@ using UnityEditor; namespace DCFApixels.DragonECS { - [DebugColor(DebugColor.Cyan)] + [MetaColor(MetaColor.Cyan)] public readonly struct UnityGameObject : IEcsComponent { public readonly GameObject gameObject; @@ -60,12 +60,11 @@ namespace DCFApixels.DragonECS 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); newGameObject.AddComponent().ConnectWith(result); - // self.GetPool().Add(result.id) = #if UNITY_EDITOR if (icon != GameObjectIcon.NONE) { @@ -84,7 +83,6 @@ namespace DCFApixels.DragonECS EditorGUIUtility.SetIconForObject(newGameObject, (Texture2D)iconContent.image); } #endif - return result; } } diff --git a/src/Extensions/UnityGameObject.cs.meta b/src/Buildin/UnityGameObject.cs.meta similarity index 83% rename from src/Extensions/UnityGameObject.cs.meta rename to src/Buildin/UnityGameObject.cs.meta index 1b88100..7ec5d76 100644 --- a/src/Extensions/UnityGameObject.cs.meta +++ b/src/Buildin/UnityGameObject.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 909b2b01fa1e58b4e9e739827e36cff4 +guid: 398c78166eea90647a60b91b2b9a0f0b MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Connectors/EcsDefaultWorldProvider.cs b/src/Connectors/EcsDefaultWorldProvider.cs deleted file mode 100644 index 40b1351..0000000 --- a/src/Connectors/EcsDefaultWorldProvider.cs +++ /dev/null @@ -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 - { - private static EcsDefaultWorldProvider _single; - public static EcsDefaultWorldProvider Single - { - get - { - if (_single == null) - _single = FindOrCreateSingle(); - return _single; - } - } - } -} diff --git a/src/Connectors/EcsEntityConnect.cs b/src/Connectors/EcsEntityConnect.cs index ba4d384..8492720 100644 --- a/src/Connectors/EcsEntityConnect.cs +++ b/src/Connectors/EcsEntityConnect.cs @@ -18,13 +18,13 @@ namespace DCFApixels.DragonECS private EcsWorld _world; [SerializeField] - private EntityTemplatePreset[] _entityTemplatePresets; + private ScriptableEntityTemplate[] _scriptableTemplates; [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 @@ -38,7 +38,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _world; } - public bool IsAlive + public bool IsConected { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _entity.IsAlive; @@ -69,70 +69,157 @@ namespace DCFApixels.DragonECS _entity = entlong.NULL; } } - public void ApplyTemplates() => ApplyTemplatesFor(_entity.ID); + public void ApplyTemplates() + { + ApplyTemplatesFor(_entity.ID); + } public void ApplyTemplatesFor(int entityID) { - foreach (var t in _entityTemplatePresets) - t.Apply(_world, entityID); - foreach (var t in _entityTemplates) - t.Apply(_world, entityID); + foreach (var t in _scriptableTemplates) + { + t.Apply(_world.id, entityID); + } + foreach (var t in _monoTemplates) + { + t.Apply(_world.id, entityID); + } } } } - #if UNITY_EDITOR - -namespace DCFApixels.DragonECS.Editors +namespace DCFApixels.DragonECS.Unity.Editors { using System.Collections.Generic; using UnityEditor; [CustomEditor(typeof(EcsEntityConnect))] + [CanEditMultipleObjects] public class EcsEntityEditor : Editor { - private EcsEntityConnect Target => (EcsEntityConnect)target; - private bool _isInit = false; + private EcsEntityConnect Target => (EcsEntityConnect)target; + private bool IsMultipleTargets => targets.Length > 1; private void Init() { if (_isInit) + { return; - + } _isInit = true; } public override void OnInspectorGUI() { 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)) - EditorGUILayout.IntField(id); + DrawConnectStatus(targets); + 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 - 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")) { - Target.SetTemplates_Editor(Target.GetComponents()); - + Target.SetTemplates_Editor(Target.GetComponents()); EditorUtility.SetDirty(target); } if (GUILayout.Button("Autoset Templates Cascade")) { foreach (var item in Target.GetComponentsInChildren()) { - item.SetTemplates_Editor(item.GetComponents()); + item.SetTemplates_Editor(item.GetComponents()); EditorUtility.SetDirty(item); } } + } - if (Target.IsAlive) + private void DrawComponents() + { + if (Target.IsConected) { List comps = new List(); Target.World.GetComponents(Target.Entity.ID, comps); diff --git a/src/Connectors/EcsWorldProvider.cs b/src/Connectors/EcsWorldProvider.cs index 3217499..48cbbbd 100644 --- a/src/Connectors/EcsWorldProvider.cs +++ b/src/Connectors/EcsWorldProvider.cs @@ -9,43 +9,50 @@ namespace DCFApixels.DragonECS [Serializable] public abstract class EcsWorldProviderBase : ScriptableObject { - public abstract EcsWorld WorldRaw { get; } - public abstract EcsWorld GetRaw(Func builder = null); + public abstract bool IsEmpty { get; } + public abstract void SetRaw(EcsWorld world); + public abstract EcsWorld GetRaw(); } [Serializable] public abstract class EcsWorldProvider : EcsWorldProviderBase where TWorld : EcsWorld { - private static TWorld _world; - public sealed override EcsWorld WorldRaw => _world; - public override EcsWorld GetRaw(Func 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 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) { } + private TWorld _world; - protected static TProvider FindOrCreateSingle() where TProvider : EcsWorldProvider + #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() where TProvider : EcsWorldProvider + { + return FindOrCreateSingleton(typeof(TProvider).Name + "Singleton"); + } + protected static TProvider FindOrCreateSingleton(string name) where TProvider : EcsWorldProvider { - string name = typeof(TProvider).Name + "Single"; TProvider instance = Resources.Load(name); if (instance == null) { @@ -62,5 +69,42 @@ namespace DCFApixels.DragonECS } 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 } -} \ No newline at end of file +} + +#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 \ No newline at end of file diff --git a/src/Debug/DebugService/UnityDebugService.cs b/src/Debug/DebugService/UnityDebugService.cs index 361d821..20d3097 100644 --- a/src/Debug/DebugService/UnityDebugService.cs +++ b/src/Debug/DebugService/UnityDebugService.cs @@ -18,6 +18,7 @@ namespace DCFApixels.DragonECS if (v is Exception e) { Debug.LogException(e); + return; } bool hasTag = string.IsNullOrEmpty(tag) == false; diff --git a/src/Debug/Editor/DebugMonitorPrefs.cs b/src/Debug/Editor/DebugMonitorPrefs.cs index b502b93..3b32eb0 100644 --- a/src/Debug/Editor/DebugMonitorPrefs.cs +++ b/src/Debug/Editor/DebugMonitorPrefs.cs @@ -1,7 +1,7 @@ #if UNITY_EDITOR using UnityEditor; -namespace DCFApixels.DragonECS.Editors +namespace DCFApixels.DragonECS.Unity.Editors { [FilePath("DragonECS/DebugMonitorPrefs.prefs", FilePathAttribute.Location.ProjectFolder)] public class DebugMonitorPrefs : ScriptableSingleton diff --git a/src/Debug/Editor/EcsEditor.cs b/src/Debug/Editor/EcsEditor.cs index 51ff38e..1a673e4 100644 --- a/src/Debug/Editor/EcsEditor.cs +++ b/src/Debug/Editor/EcsEditor.cs @@ -1,48 +1,83 @@ #if UNITY_EDITOR +using DCFApixels.DragonECS.Unity.Internal; using System; using System.Reflection; using System.Runtime.InteropServices; using UnityEditor; -using UnityEditor.UI; using UnityEngine; -namespace DCFApixels.DragonECS.Editors +namespace DCFApixels.DragonECS.Unity.Editors { public static class EcsGUI { + private static GUIStyle _grayStyle; private static GUIStyle _greenStyle; private static GUIStyle _redStyle; + private static GUILayoutOption[] _defaultParams; private static bool _isInit = false; private static void Init() { if (_isInit) + { 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)); _redStyle = EcsEditor.GetStyle(new Color32(255, 0, 75, 100)); _isInit = true; } + + private const string CONNECTED = "Connected"; + private const string NOT_CONNECTED = "Not connected"; + private const string UNDETERMINED_CONNECTED = "---"; public static void DrawConnectStatus(Rect position, bool status) { Init(); if (status) - GUI.Box(position, "Connected", _greenStyle); + { + GUI.Box(position, CONNECTED, _greenStyle); + } 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 void DrawConnectStatus(bool status, params GUILayoutOption[] options) { Init(); + if(options == null || options.Length <= 0) + { + options = _defaultParams; + } if (status) - GUILayout.Box("Connected", _greenStyle, GUILayout.ExpandWidth(true)); + { + GUILayout.Box(CONNECTED, _greenStyle, options); + } 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); } } } diff --git a/src/Debug/Systems/PipelineDebugSystem.cs b/src/Debug/Systems/PipelineDebugSystem.cs index c76d447..8f4efa3 100644 --- a/src/Debug/Systems/PipelineDebugSystem.cs +++ b/src/Debug/Systems/PipelineDebugSystem.cs @@ -1,29 +1,30 @@ using DCFApixels.DragonECS.Unity.Debug; -using System.Reflection; using UnityEngine; +using System.Linq; namespace DCFApixels.DragonECS { - [DebugHide, DebugColor(DebugColor.Gray)] - public class PipelineDebugSystem : IEcsPreInitProcess + [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)] + public class PipelineDebugSystem : IEcsPreInit, IEcsPipelineMember { + public EcsPipeline Pipeline { get; set; } private string _monitorName; public PipelineDebugSystem(string monitorName = "Pipeline") { _monitorName = monitorName; } - void IEcsPreInitProcess.PreInit(EcsPipeline pipeline) + void IEcsPreInit.PreInit() { PipelineDebugMonitor monitor = new GameObject(EcsConsts.DEBUG_PREFIX + _monitorName).AddComponent(); monitor.source = this; - monitor.pipeline = pipeline; + monitor.pipeline = Pipeline; monitor.monitorName = _monitorName; PipelineProcessesDebugMonitor processesMonitor = new GameObject(EcsConsts.DEBUG_PREFIX + "Processes Matrix").AddComponent(); processesMonitor.transform.parent = monitor.transform; processesMonitor.source = this; - processesMonitor.pipeline = pipeline; + processesMonitor.pipeline = Pipeline; processesMonitor.monitorName = "Processes Matrix"; //foreach (var item in pipeline.AllSystems) //Вырезано пока не сделаю TODO в SystemDebugMonitor @@ -46,295 +47,295 @@ namespace DCFApixels.DragonECS internal PipelineDebugSystem source; internal EcsPipeline pipeline; } +} + #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; - using DCFApixels.DragonECS.RunnersCore; - using System; - using System.Collections.Generic; - using System.Linq; - using UnityEditor; + private MetaColorAttribute _fakeDebugColorAttribute = new MetaColorAttribute(190, 190, 190); + private Type _debugColorAttributeType = typeof(MetaColorAttribute); + private GUIStyle _headerStyle; + private GUIStyle _interfacesStyle; + private Color _interfaceColor = new Color(0.96f, 1f, 0.16f); + 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); - private Type _debugColorAttributeType = typeof(DebugColorAttribute); - private GUIStyle _headerStyle; - private GUIStyle _interfacesStyle; - private Color _interfaceColor = new Color(0.96f, 1f, 0.16f); - private PipelineDebugMonitor Target => (PipelineDebugMonitor)target; + systemsListStyle = new GUIStyle(EditorStyles.miniLabel); + systemsListStyle.wordWrap = true; - - private GUIStyle systemsListStyle; - - public override void OnInspectorGUI() + if (Target.source == null) + return; + if (_headerStyle == null) { - systemsListStyle = new GUIStyle(EditorStyles.miniLabel); - systemsListStyle.wordWrap = true; - - if (Target.source == null) - return; - if (_headerStyle == null) - { - _headerStyle = new GUIStyle(EditorStyles.boldLabel); - _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(); + _headerStyle = new GUIStyle(EditorStyles.boldLabel); + _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; } - 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) - { - 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(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(); + DrawSystem(item); } + 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(); - if (CheckIsHidden(type)) - return; - - //Color color = (GetAttribute(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().Select(o => o.GetType().Name)), systemsListStyle); - GUILayout.EndVertical(); - } - - private TAttribute GetAttribute(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() != null; + DrawRunner(item.Value); } + GUILayout.EndVertical(); } - [CustomEditor(typeof(PipelineProcessesDebugMonitor))] - public class PipelineProcessesDebugMonitorEditor : Editor + private void DrawSystem(IEcsProcess system) { - private bool _isInit = false; - private List _processesList = new List(); - private Dictionary _processeIndexes = new Dictionary(); - - private PipelineProcessesDebugMonitor Target => (PipelineProcessesDebugMonitor)target; - private Type systemInterfaceType = typeof(IEcsProcess); - - private IEcsProcess[] _systems; - private void Init() + if (system is SystemsLayerMarkerSystem markerSystem) { - 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() == null).ToArray(); + GUILayout.EndVertical(); + GUILayout.BeginVertical(EcsEditor.GetStyle(Color.black, 0.2f)); - int i = 0; - foreach (var system in _systems) - { - foreach (var intr in system.GetType().GetInterfaces()) - { - if (systemInterfaceType.IsAssignableFrom(intr) && systemInterfaceType != intr && (showHidden || intr.GetCustomAttribute() == 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 systeNames = new List(); - - 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(); + GUILayout.BeginHorizontal(); + GUILayout.Label("<"); + GUILayout.Label($"{markerSystem.name}", EditorStyles.boldLabel); + GUILayout.Label(">", GUILayout.ExpandWidth(false)); + GUILayout.EndHorizontal(); + return; } - private class ProcessData + Type type = system.GetType(); + + if (CheckIsHidden(type)) + return; + + string name = EcsEditor.GetGenericName(type); + //Color color = (GetAttribute(type) ?? _fakeDebugColorAttribute).GetUnityColor(); + Color color = EcsDebugUtility.GetColor(type).ToUnityColor(); + + GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f)); + if (DebugMonitorPrefs.instance.IsShowInterfaces) { - public Type interfaceType; - public string name; - public BitMask systemsBitMask; + GUILayout.Label(string.Join(", ", type.GetInterfaces().Select(o => o.Name)), _interfacesStyle); } + GUILayout.Label(name, EditorStyles.boldLabel); + GUILayout.EndVertical(); + } + + private void DrawRunner(IEcsRunner runner) + { + Type type = runner.GetType(); + if (CheckIsHidden(type)) + return; + + //Color color = (GetAttribute(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().Select(o => o.GetType().Name)), systemsListStyle); + GUILayout.EndVertical(); + } + + private TAttribute GetAttribute(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() != null; + } + } + + [CustomEditor(typeof(PipelineProcessesDebugMonitor))] + public class PipelineProcessesDebugMonitorEditor : Editor + { + private bool _isInit = false; + private List _processesList = new List(); + private Dictionary _processeIndexes = new Dictionary(); + + 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() == 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() == 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 systeNames = new List(); + + 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 diff --git a/src/Debug/Systems/WorldDebugSystem.cs b/src/Debug/Systems/WorldDebugSystem.cs index fee56cb..003ed6e 100644 --- a/src/Debug/Systems/WorldDebugSystem.cs +++ b/src/Debug/Systems/WorldDebugSystem.cs @@ -1,10 +1,11 @@ using DCFApixels.DragonECS.Unity.Debug; using UnityEngine; +using System.Linq; namespace DCFApixels.DragonECS { - [DebugHide, DebugColor(DebugColor.Gray)] - public class WorldDebugSystem : IEcsRunProcess + [MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)] + public class WorldDebugSystem : IEcsRun { private string _monitorName; private EcsWorld _ecsWorld; @@ -27,7 +28,7 @@ namespace DCFApixels.DragonECS poolsmonitor.monitorName = "pools"; } - public void Run(EcsPipeline pipeline) + public void Run() { } } @@ -65,116 +66,112 @@ namespace DCFApixels.DragonECS internal WorldDebugSystem source; internal EcsWorld world; } +} #if UNITY_EDITOR - namespace Editors +namespace DCFApixels.DragonECS.Unity.Editors +{ + using UnityEditor; + + [CustomEditor(typeof(WorldPoolsMonitor))] + public class WorldPoolsMonitorEditor : Editor { - using System.Linq; - using System.Reflection; - using UnityEditor; + private static Vector2 _poolBlockMinSize = new Vector2(80, 160); + private static Vector2 _poolProgressBasrSize = _poolBlockMinSize * new Vector2(1f, 0.8f); - [CustomEditor(typeof(WorldPoolsMonitor))] - public class WorldPoolsMonitorEditor : Editor + private WorldPoolsMonitor Target => (WorldPoolsMonitor)target; + + private Vector2 _scroll; + + public override void OnInspectorGUI() { - private static Vector2 _poolBlockMinSize = new Vector2(80, 160); - private static Vector2 _poolProgressBasrSize = _poolBlockMinSize * new Vector2(1f, 0.8f); + _scroll = GUILayout.BeginScrollView(_scroll, GUILayout.Height(800f)); - private WorldPoolsMonitor Target => (WorldPoolsMonitor)target; + var pools = Target.world.AllPools.ToArray().Where(o => !o.IsNullOrDummy()).OfType(); - 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)); - - var pools = Target.world.AllPools.ToArray().Where(o => !o.IsNullOrDummy()).OfType(); - - 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) { - if (++x >= widthCount) - { - x = 0; - y++; - } - - DrawPoolBlock(pool, new Rect(newPoolBlockSize.x * x, newPoolBlockSize.y * y, newPoolBlockSize.x, newPoolBlockSize.y)); + x = 0; + 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) - { - int count = pool.Count; - int capacity = pool.Capacity < 0 ? count : pool.Capacity; + private void DrawPoolBlock(IEcsPool pool, Rect position) + { + var meta = pool.GetMeta(); - Color defaultContentColor = GUI.contentColor; - GUI.contentColor = Color.black * 0.925f; + int count = pool.Count; + 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); - progressBar.width = position.width; - progressBar.center = position.center - Vector2.up * _poolBlockMinSize.y * 0.09f; + EditorGUI.DrawRect(position, Color.black * 0.16f); + 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); - var debugColor = pool.ComponentType.GetCustomAttribute(); - if (debugColor != null) - { - mainColor = debugColor.GetUnityColor(); - } - Color backgroundColor = mainColor * 0.3f + Color.white * 0.2f; + Color mainColor = meta.Color.ToUnityColor(); + 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); - textStyle0.alignment = TextAnchor.MiddleCenter; + GUIStyle textStyle0 = new GUIStyle(EditorStyles.miniBoldLabel); + textStyle0.alignment = TextAnchor.MiddleCenter; - Color foregroundColor = mainColor; - EditorGUI.DrawRect(progressBar, foregroundColor); - GUI.Label(progressBar, count.ToString(), textStyle0); + Color foregroundColor = mainColor; + EditorGUI.DrawRect(progressBar, foregroundColor); + GUI.Label(progressBar, count.ToString(), textStyle0); - GUIStyle textStyle1 = new GUIStyle(EditorStyles.miniBoldLabel); - textStyle1.alignment = TextAnchor.UpperCenter; - GUI.Label(AddMargin(position, 3f, 3f), "Total\r\n" + capacity, textStyle1); + GUIStyle textStyle1 = new GUIStyle(EditorStyles.miniBoldLabel); + textStyle1.alignment = TextAnchor.UpperCenter; + GUI.Label(AddMargin(position, 3f, 3f), "Total\r\n" + capacity, textStyle1); - GUI.contentColor = defaultContentColor; - GUIStyle textStyle2 = new GUIStyle(EditorStyles.miniBoldLabel); - textStyle2.wordWrap = true; - textStyle2.alignment = TextAnchor.LowerCenter; - string name = EcsEditor.GetGenericName(pool.ComponentType); - GUIContent label = new GUIContent(name, $"{name} e:{count}"); - GUI.Label(AddMargin(position, -10f, 3f), label, textStyle2); + GUI.contentColor = defaultContentColor; + GUIStyle textStyle2 = new GUIStyle(EditorStyles.miniBoldLabel); + textStyle2.wordWrap = true; + textStyle2.alignment = TextAnchor.LowerCenter; + string name = EcsEditor.GetGenericName(pool.ComponentType); + GUIContent label = new GUIContent(name, $"{name} e:{count}"); + GUI.Label(AddMargin(position, -10f, 3f), label, textStyle2); - } + } - private Rect AddMargin(Rect rect, Vector2 value) - { - return AddMargin(rect, value.x, value.y); - } - private Rect AddMargin(Rect rect, float x, float y) - { - rect.yMax -= y; - rect.yMin += y; - rect.xMax -= x; - rect.xMin += x; - return rect; - } + private Rect AddMargin(Rect rect, Vector2 value) + { + return AddMargin(rect, value.x, value.y); + } + private Rect AddMargin(Rect rect, float x, float y) + { + rect.yMax -= y; + rect.yMin += y; + rect.xMax -= x; + rect.xMin += x; + return rect; } } -#endif } +#endif + diff --git a/src/EntityTemplate/Editor.meta b/src/EntityTemplate/Editor.meta new file mode 100644 index 0000000..9b140d9 --- /dev/null +++ b/src/EntityTemplate/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d8c6da13649cc094e80f3ec624bad02b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/EntityTemplate/Editor/EntityTemplateEditor.cs b/src/EntityTemplate/Editor/EntityTemplateEditor.cs new file mode 100644 index 0000000..4f31b38 --- /dev/null +++ b/src/EntityTemplate/Editor/EntityTemplateEditor.cs @@ -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 diff --git a/src/EntityTemplate/EntityTemplateEditor.cs.meta b/src/EntityTemplate/Editor/EntityTemplateEditor.cs.meta similarity index 100% rename from src/EntityTemplate/EntityTemplateEditor.cs.meta rename to src/EntityTemplate/Editor/EntityTemplateEditor.cs.meta diff --git a/src/EntityTemplate/EntityTemplate.cs b/src/EntityTemplate/EntityTemplate.cs deleted file mode 100644 index 26cc481..0000000 --- a/src/EntityTemplate/EntityTemplate.cs +++ /dev/null @@ -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]; - } - } -} diff --git a/src/EntityTemplate/EntityTemplateEditor.cs b/src/EntityTemplate/EntityTemplateEditor.cs deleted file mode 100644 index 95f379b..0000000 --- a/src/EntityTemplate/EntityTemplateEditor.cs +++ /dev/null @@ -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()?.description; - // Color panelColor = customInitializer != null ? customInitializer.Color : initializerType.GetCustomAttribute()?.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 -} diff --git a/src/EntityTemplate/EntityTemplatePreset.cs b/src/EntityTemplate/EntityTemplatePreset.cs deleted file mode 100644 index 2de34e3..0000000 --- a/src/EntityTemplate/EntityTemplatePreset.cs +++ /dev/null @@ -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]; - } - } -} diff --git a/src/EntityTemplate/ITemplate.cs b/src/EntityTemplate/ITemplate.cs deleted file mode 100644 index 9a45baa..0000000 --- a/src/EntityTemplate/ITemplate.cs +++ /dev/null @@ -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; - } - } -} diff --git a/src/EntityTemplate/ITemplateNode.cs b/src/EntityTemplate/ITemplateNode.cs new file mode 100644 index 0000000..b2c9967 --- /dev/null +++ b/src/EntityTemplate/ITemplateNode.cs @@ -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 + //} +} diff --git a/src/EntityTemplate/ITemplate.cs.meta b/src/EntityTemplate/ITemplateNode.cs.meta similarity index 100% rename from src/EntityTemplate/ITemplate.cs.meta rename to src/EntityTemplate/ITemplateNode.cs.meta diff --git a/src/EntityTemplate/TemplateComponent.cs b/src/EntityTemplate/TemplateComponent.cs deleted file mode 100644 index 54bb644..0000000 --- a/src/EntityTemplate/TemplateComponent.cs +++ /dev/null @@ -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(); - //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(); - if (atr == null) return string.Empty; - return atr.description; - } - #endregion - } - [Serializable] - public abstract class TemplateComponentInitializer : 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 Types => _types; - internal static ReadOnlySpan Dummies => _dummies; - - static TemplateBrowsableTypeCache() - { - List types = new List(); - 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() != null); - - types.AddRange(targetTypes.Where(type => interfaceType.IsAssignableFrom(type))); - - foreach (var t in targetTypes) - { - if (t.IsSubclassOf(typeof(TemplateComponentInitializer<>))) - { - if (t.HasAttribute()) - 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 -} diff --git a/src/EntityTemplate/Templates.meta b/src/EntityTemplate/Templates.meta new file mode 100644 index 0000000..7e9abc7 --- /dev/null +++ b/src/EntityTemplate/Templates.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 14555d6350df03d448d362de7b6a31c1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/EntityTemplate/Templates/ComponentTemplateBase.cs b/src/EntityTemplate/Templates/ComponentTemplateBase.cs new file mode 100644 index 0000000..9d12a76 --- /dev/null +++ b/src/EntityTemplate/Templates/ComponentTemplateBase.cs @@ -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 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 Tags { get { return Array.Empty(); } } + 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 : ComponentTemplateBase, IComponentTemplate + { + private static TypeMetaDataCached _meta = EcsDebugUtility.GetCachedTypeMeta(); + [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 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 : ComponentTemplateBase, IComponentTemplate + where T : struct, IEcsComponent + { + public override void Apply(int worldID, int entityID) + { + EcsWorld.GetPool>(worldID).TryAddOrGet(entityID) = component; + } + } + public abstract class TagComponentTemplate : ComponentTemplateBase, IComponentTemplate + where T : struct, IEcsTagComponent + { + public override void Apply(int worldID, int entityID) + { + EcsWorld.GetPool>(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 Types => _types; + internal static ReadOnlySpan Dummies => _dummies; + + static ComponentTemplateTypeCache() + { + List types = new List(); + 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() != 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 + diff --git a/src/EntityTemplate/EntityTemplate.cs.meta b/src/EntityTemplate/Templates/ComponentTemplateBase.cs.meta similarity index 83% rename from src/EntityTemplate/EntityTemplate.cs.meta rename to src/EntityTemplate/Templates/ComponentTemplateBase.cs.meta index 3a14226..8ee6928 100644 --- a/src/EntityTemplate/EntityTemplate.cs.meta +++ b/src/EntityTemplate/Templates/ComponentTemplateBase.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3c96e3aedd5a69443af75096e5561265 +guid: b532f9d8441035d49b9acb99ea23c231 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/EntityTemplate/Templates/MonoEntityTemplate.cs b/src/EntityTemplate/Templates/MonoEntityTemplate.cs new file mode 100644 index 0000000..3e7d248 --- /dev/null +++ b/src/EntityTemplate/Templates/MonoEntityTemplate.cs @@ -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(); + } + #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 + } +} diff --git a/src/Extensions/Runners.cs.meta b/src/EntityTemplate/Templates/MonoEntityTemplate.cs.meta similarity index 83% rename from src/Extensions/Runners.cs.meta rename to src/EntityTemplate/Templates/MonoEntityTemplate.cs.meta index 2b4d105..38b24c0 100644 --- a/src/Extensions/Runners.cs.meta +++ b/src/EntityTemplate/Templates/MonoEntityTemplate.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 385a6c66660032944ad2cce7130715d7 +guid: 351338ca92ace49499f450172d857af6 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/EntityTemplate/Templates/ScriptableEntityTemplate.cs b/src/EntityTemplate/Templates/ScriptableEntityTemplate.cs new file mode 100644 index 0000000..95dde5a --- /dev/null +++ b/src/EntityTemplate/Templates/ScriptableEntityTemplate.cs @@ -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(); + } + #endregion + + #region UnityEvents + private void OnValidate() + { + if (_components == null) { return; } + foreach (var item in _components) + { + item.OnValidate(this); + } + } + #endregion + } +} diff --git a/src/EntityTemplate/Templates/ScriptableEntityTemplate.cs.meta b/src/EntityTemplate/Templates/ScriptableEntityTemplate.cs.meta new file mode 100644 index 0000000..7d1bf18 --- /dev/null +++ b/src/EntityTemplate/Templates/ScriptableEntityTemplate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d2b62f9703592042befb46ac1fee09c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Extensions/Systems.cs b/src/Extensions/Systems.cs deleted file mode 100644 index 0c8f39d..0000000 --- a/src/Extensions/Systems.cs +++ /dev/null @@ -1,42 +0,0 @@ -using DCFApixels.DragonECS.Internal; -using System.Collections.Generic; - -namespace DCFApixels.DragonECS -{ - [DebugHide, DebugColor(DebugColor.Grey)] - public class DeleteOneFrameComponentFixedSystem : IEcsFixedRunProcess, IEcsInject - where TComponent : struct, IEcsComponent - { - private sealed class Aspect : EcsAspect - { - public EcsPool pool; - public Aspect(Builder b) => pool = b.Include(); - } - List _worlds = new List(); - 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()) - { - 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(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(), layerName); - return b; - } - } -} diff --git a/src/Extensions/Systems.cs.meta b/src/Extensions/Systems.cs.meta deleted file mode 100644 index 21f2963..0000000 --- a/src/Extensions/Systems.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e8c608fea9f3569409826ec54affa822 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/Utils/BitMask.cs b/src/Utils/BitMask.cs index 17c9b07..f31f7bb 100644 --- a/src/Utils/BitMask.cs +++ b/src/Utils/BitMask.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.CompilerServices; -namespace DCFApixels.DragonECS.Editors +namespace DCFApixels.DragonECS.Unity.Internal { internal class BitMask { @@ -21,21 +21,30 @@ namespace DCFApixels.DragonECS.Editors public bool this[int index] { [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)] set { if (value) + { _data[index >> OFFSET] |= (1 << (index & MOD_MASK)); + } else + { _data[index >> OFFSET] &= ~(1 << (index & MOD_MASK)); + } } } public void Resize(int newSize) { if (newSize <= _size) + { return; + } _size = newSize / DATA_BITS + 1; Array.Resize(ref _data, _size); diff --git a/src/Utils/DebugColorAttributeExt.cs b/src/Utils/DebugColorAttributeExt.cs deleted file mode 100644 index 29c8da0..0000000 --- a/src/Utils/DebugColorAttributeExt.cs +++ /dev/null @@ -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); - } - } -} diff --git a/src/Utils/MetaColorExstensions.cs b/src/Utils/MetaColorExstensions.cs new file mode 100644 index 0000000..18238e6 --- /dev/null +++ b/src/Utils/MetaColorExstensions.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +namespace DCFApixels.DragonECS +{ + public static class MetaColorExstensions + { + public static Color ToUnityColor(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(this T self) where T : IMetaColor + { + return new Color32(self.R, self.G, self.B, self.A); + } + } +} diff --git a/src/Utils/DebugColorAttributeExt.cs.meta b/src/Utils/MetaColorExstensions.cs.meta similarity index 100% rename from src/Utils/DebugColorAttributeExt.cs.meta rename to src/Utils/MetaColorExstensions.cs.meta diff --git a/src/Utils/SparseArray.cs b/src/Utils/SparseArray.cs index 5699919..340f17f 100644 --- a/src/Utils/SparseArray.cs +++ b/src/Utils/SparseArray.cs @@ -6,7 +6,7 @@ using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -namespace DCFApixels.DragonECS.Editors +namespace DCFApixels.DragonECS.Unity.Internal { internal class SparseArray {