From 3aeb8bf252f3b5cd62ba310927201e27be0a5977 Mon Sep 17 00:00:00 2001 From: thatcosmonaut Date: Fri, 22 Nov 2019 10:16:19 -0800 Subject: [PATCH 1/6] 0.17.0-preview1 --- encompass-cs/encompass-cs.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/encompass-cs/encompass-cs.csproj b/encompass-cs/encompass-cs.csproj index fb545c4..12042c9 100644 --- a/encompass-cs/encompass-cs.csproj +++ b/encompass-cs/encompass-cs.csproj @@ -3,7 +3,7 @@ netstandard2.0 Encompass EncompassECS.Framework - 0.16.0 + 0.17.0-preview1 Evan Hemsley true Moonside Games @@ -26,4 +26,4 @@ - \ No newline at end of file + From 71846a9a09a280b4fa769ae6b6440676a578c1c7 Mon Sep 17 00:00:00 2001 From: thatcosmonaut Date: Fri, 22 Nov 2019 10:25:54 -0800 Subject: [PATCH 2/6] update circleCI config --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e7978c2..c922620 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -43,4 +43,4 @@ workflows: branches: ignore: /.*/ tags: - only: /^\d+\.\d+\.\d+(-rc\d+)?$/ + only: /^\d+\.\d+\.\d+(-preview\d+)?$/ From f05b7f725dc4f756f6ba6cac16438fc8723367de Mon Sep 17 00:00:00 2001 From: thatcosmonaut Date: Fri, 22 Nov 2019 13:14:36 -0800 Subject: [PATCH 3/6] remove time dilation priority system in favor of averaging --- .../Attributes/TimeDilationPriority.cs | 15 ---- encompass-cs/Engine.cs | 30 +++---- .../TimeDilationPriorityConflictException.cs | 12 --- .../TimeDilationPriorityUndefinedException.cs | 12 --- encompass-cs/Renderer.cs | 10 +++ encompass-cs/TimeManager.cs | 87 ++++++++++--------- encompass-cs/WorldBuilder.cs | 26 ------ test/EngineTest.cs | 77 ++++++---------- 8 files changed, 93 insertions(+), 176 deletions(-) delete mode 100644 encompass-cs/Attributes/TimeDilationPriority.cs delete mode 100644 encompass-cs/Exceptions/TimeDilationPriorityConflictException.cs delete mode 100644 encompass-cs/Exceptions/TimeDilationPriorityUndefinedException.cs diff --git a/encompass-cs/Attributes/TimeDilationPriority.cs b/encompass-cs/Attributes/TimeDilationPriority.cs deleted file mode 100644 index c833e9b..0000000 --- a/encompass-cs/Attributes/TimeDilationPriority.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Encompass -{ - [AttributeUsage(AttributeTargets.Class)] - public class TimeDilationPriority : Attribute - { - public int timeDilationPriority; - - public TimeDilationPriority(int timeDilationPriority) - { - this.timeDilationPriority = timeDilationPriority; - } - } -} diff --git a/encompass-cs/Engine.cs b/encompass-cs/Engine.cs index 9ec8870..23228fe 100644 --- a/encompass-cs/Engine.cs +++ b/encompass-cs/Engine.cs @@ -27,7 +27,6 @@ namespace Encompass /// /// Used when activating time dilation. Lower priority overrides higher priority. /// - internal int? timeDilationPriority = null; private EntityManager entityManager; private MessageManager messageManager; @@ -139,9 +138,9 @@ namespace Encompass /// /// Returns true if an Entity with the specified ID exists. /// - internal bool EntityExists(Guid entityID) + protected bool EntityExists(Entity entity) { - return entityManager.EntityExists(entityID); + return entityManager.EntityExists(entity.ID); } /// @@ -699,15 +698,10 @@ namespace Encompass componentManager.MarkForRemoval(componentID); } - private void CheckTimeDilationPriorityExists() - { - if (!timeDilationPriority.HasValue) { throw new TimeDilationPriorityUndefinedException("Engines that activate time dilation must use the TimeDilationPriority attribute."); } - } - /// /// Activates the Encompass time dilation system. - /// If activating time dilation, make sure the TimeDilationPriority attribute is set or an exception will be thrown. /// Engines that have the IgnoresTimeDilation property will ignore all time dilation. + /// If multiple time dilations are active they will be averaged. /// /// The time dilation factor, which is multiplied by real delta time. /// The time that will elapse before time is fully dilated, in real time. @@ -715,14 +709,13 @@ namespace Encompass /// The time that will elapse before time is fully undilated. public void ActivateTimeDilation(double factor, double easeInTime, double activeTime, double easeOutTime) { - CheckTimeDilationPriorityExists(); - timeManager.ActivateTimeDilation(factor, easeInTime, activeTime, easeOutTime, timeDilationPriority.Value); + timeManager.ActivateTimeDilation(factor, easeInTime, activeTime, easeOutTime); } /// /// Activates the Encompass time dilation system. - /// If activating time dilation, make sure the TimeDilationPriority attribute is set or an exception will be thrown. /// Engines that have the IgnoresTimeDilation property will ignore all time dilation. + /// If multiple time dilations are active they will be averaged. /// /// The time dilation factor, which is multiplied by real delta time. /// The time that will elapse before time is fully dilated, in real time. @@ -731,14 +724,13 @@ namespace Encompass /// The time that will elapse before time is fully undilated. public void ActivateTimeDilation(double factor, double easeInTime, System.Func easeInFunction, double activeTime, double easeOutTime) { - CheckTimeDilationPriorityExists(); - timeManager.ActivateTimeDilation(factor, easeInTime, easeInFunction, activeTime, easeOutTime, timeDilationPriority.Value); + timeManager.ActivateTimeDilation(factor, easeInTime, easeInFunction, activeTime, easeOutTime); } /// /// Activates the Encompass time dilation system. - /// If activating time dilation, make sure the TimeDilationPriority attribute is set or an exception will be thrown. /// Engines that have the IgnoresTimeDilation property will ignore all time dilation. + /// If multiple time dilations are active they will be averaged. /// /// The time dilation factor, which is multiplied by real delta time. /// The time that will elapse before time is fully dilated, in real time. @@ -747,14 +739,13 @@ namespace Encompass /// An easing function for the easing out of time dilation. public void ActivateTimeDilation(double factor, double easeInTime, double activeTime, double easeOutTime, System.Func easeOutFunction) { - CheckTimeDilationPriorityExists(); - timeManager.ActivateTimeDilation(factor, easeInTime, activeTime, easeOutTime, easeOutFunction, timeDilationPriority.Value); + timeManager.ActivateTimeDilation(factor, easeInTime, activeTime, easeOutTime, easeOutFunction); } /// /// Activates the Encompass time dilation system. - /// If activating time dilation, make sure the TimeDilationPriority attribute is set or an exception will be thrown. /// Engines that have the IgnoresTimeDilation property will ignore all time dilation. + /// If multiple time dilations are active they will be averaged. /// /// The time dilation factor, which is multiplied by real delta time. /// The time that will elapse before time is fully dilated, in real time. @@ -764,8 +755,7 @@ namespace Encompass /// An easing function for the easing out of time dilation. public void ActivateTimeDilation(double factor, double easeInTime, System.Func easeInFunction, double activeTime, double easeOutTime, System.Func easeOutFunction) { - CheckTimeDilationPriorityExists(); - timeManager.ActivateTimeDilation(factor, easeInTime, easeInFunction, activeTime, easeOutTime, easeOutFunction, timeDilationPriority.Value); + timeManager.ActivateTimeDilation(factor, easeInTime, easeInFunction, activeTime, easeOutTime, easeOutFunction); } } } diff --git a/encompass-cs/Exceptions/TimeDilationPriorityConflictException.cs b/encompass-cs/Exceptions/TimeDilationPriorityConflictException.cs deleted file mode 100644 index cf7c109..0000000 --- a/encompass-cs/Exceptions/TimeDilationPriorityConflictException.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Encompass.Exceptions -{ - public class TimeDilationPriorityConflictException : Exception - { - public TimeDilationPriorityConflictException( - string format, - params object[] args - ) : base(string.Format(format, args)) { } - } -} diff --git a/encompass-cs/Exceptions/TimeDilationPriorityUndefinedException.cs b/encompass-cs/Exceptions/TimeDilationPriorityUndefinedException.cs deleted file mode 100644 index 1baf332..0000000 --- a/encompass-cs/Exceptions/TimeDilationPriorityUndefinedException.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Encompass.Exceptions -{ - public class TimeDilationPriorityUndefinedException : Exception - { - public TimeDilationPriorityUndefinedException( - string format, - params object[] args - ) : base(string.Format(format, args)) { } - } -} diff --git a/encompass-cs/Renderer.cs b/encompass-cs/Renderer.cs index 922876f..cb30820 100644 --- a/encompass-cs/Renderer.cs +++ b/encompass-cs/Renderer.cs @@ -29,6 +29,16 @@ namespace Encompass return entityManager.GetEntity(entityID); } + protected IEnumerable ReadEntities() where TComponent : struct, IComponent + { + return ReadComponentsIncludingEntity().Select(tuple => tuple.Item2); + } + + protected Entity ReadEntity() where TComponent : struct, IComponent + { + return ReadComponentIncludingEntity().Item2; + } + protected IEnumerable ReadComponents() where TComponent : struct, IComponent { return componentManager.GetComponentsByType().Select(tuple => tuple.Item2); diff --git a/encompass-cs/TimeManager.cs b/encompass-cs/TimeManager.cs index 7187091..4c23dee 100644 --- a/encompass-cs/TimeManager.cs +++ b/encompass-cs/TimeManager.cs @@ -1,73 +1,76 @@ +using System.Collections.Generic; +using System.Linq; + namespace Encompass { internal class TimeManager { - private TimeDilationData timeDilationData = new TimeDilationData { factor = 1 }; - private bool newTimeDilationData = false; - private TimeDilationData nextFrameTimeDilationData = new TimeDilationData { factor = 1 }; + private List timeDilationDatas = new List(); private double Linear(double t, double b, double c, double d) { return c * t / d + b; } - private int minPriority = int.MaxValue; public double TimeDilationFactor { get { - return timeDilationData.Factor; + return timeDilationDatas.Count == 0 ? 1 : timeDilationDatas.Select(data => data.Factor).Average(); } } public bool TimeDilationActive { - get => TimeDilationFactor != 1; + get => timeDilationDatas.Count != 0; } public void Update(double dt) { - if (newTimeDilationData) + for (var i = timeDilationDatas.Count - 1; i >= 0; i--) { - timeDilationData = nextFrameTimeDilationData; - } + var data = timeDilationDatas[i]; - timeDilationData.elapsedTime += dt; - newTimeDilationData = false; - minPriority = int.MaxValue; - } + data.elapsedTime += dt; - public void ActivateTimeDilation(double factor, double easeInTime, double activeTime, double easeOutTime, int priority) - { - ActivateTimeDilation(factor, easeInTime, Linear, activeTime, easeOutTime, Linear, priority); - } - - public void ActivateTimeDilation(double factor, double easeInTime, System.Func easeInFunction, double activeTime, double easeOutTime, int priority) - { - ActivateTimeDilation(factor, easeInTime, easeInFunction, activeTime, easeOutTime, Linear, priority); - } - - public void ActivateTimeDilation(double factor, double easeInTime, double activeTime, double easeOutTime, System.Func easeOutFunction, int priority) - { - ActivateTimeDilation(factor, easeInTime, Linear, activeTime, easeOutTime, easeOutFunction, priority); - } - - public void ActivateTimeDilation(double factor, double easeInTime, System.Func easeInFunction, double activeTime, double easeOutTime, System.Func easeOutFunction, int priority) - { - if (priority <= minPriority) - { - newTimeDilationData = true; - nextFrameTimeDilationData = new TimeDilationData + if (data.elapsedTime > data.easeInTime + data.activeTime + data.easeOutTime) { - elapsedTime = 0, - easeInTime = easeInTime, - easeInFunction = easeInFunction, - activeTime = activeTime, - easeOutTime = easeOutTime, - easeOutFunction = easeOutFunction, - factor = factor - }; + timeDilationDatas.RemoveAt(i); + } + else + { + timeDilationDatas[i] = data; + } } } + + public void ActivateTimeDilation(double factor, double easeInTime, double activeTime, double easeOutTime) + { + ActivateTimeDilation(factor, easeInTime, Linear, activeTime, easeOutTime, Linear); + } + + public void ActivateTimeDilation(double factor, double easeInTime, System.Func easeInFunction, double activeTime, double easeOutTime) + { + ActivateTimeDilation(factor, easeInTime, easeInFunction, activeTime, easeOutTime, Linear); + } + + public void ActivateTimeDilation(double factor, double easeInTime, double activeTime, double easeOutTime, System.Func easeOutFunction) + { + ActivateTimeDilation(factor, easeInTime, Linear, activeTime, easeOutTime, easeOutFunction); + } + + public void ActivateTimeDilation(double factor, double easeInTime, System.Func easeInFunction, double activeTime, double easeOutTime, System.Func easeOutFunction) + { + timeDilationDatas.Add(new TimeDilationData + { + elapsedTime = 0, + easeInTime = easeInTime, + easeInFunction = easeInFunction, + activeTime = activeTime, + easeOutTime = easeOutTime, + easeOutFunction = easeOutFunction, + factor = factor + }); + } } } diff --git a/encompass-cs/WorldBuilder.cs b/encompass-cs/WorldBuilder.cs index a44e452..fb68653 100644 --- a/encompass-cs/WorldBuilder.cs +++ b/encompass-cs/WorldBuilder.cs @@ -234,22 +234,8 @@ namespace Encompass var writePriorities = new Dictionary>(); var writeMessageToEngines = new Dictionary>(); - var timeDilationPriorities = new Dictionary>(); - foreach (var engine in engines) { - var timeDilationPriorityAttribute = engine.GetType().GetCustomAttribute(); - - if (timeDilationPriorityAttribute != null) - { - engine.timeDilationPriority = timeDilationPriorityAttribute.timeDilationPriority; - if (!timeDilationPriorities.ContainsKey(timeDilationPriorityAttribute.timeDilationPriority)) - { - timeDilationPriorities.Add(timeDilationPriorityAttribute.timeDilationPriority, new HashSet()); - } - timeDilationPriorities[timeDilationPriorityAttribute.timeDilationPriority].Add(engine); - } - if (engine.GetType().GetCustomAttribute() != null) { engine.usesTimeDilation = false; @@ -344,18 +330,6 @@ namespace Encompass throw new EngineWriteConflictException(errorString); } - foreach (var timeDilationEngines in timeDilationPriorities) - { - var priority = timeDilationEngines.Key; - var engines = timeDilationEngines.Value; - if (engines.Count > 1) - { - var errorString = "Multiple Engines have the same Time Dilation Priority value: "; - errorString += string.Join(", ", engines); - throw new TimeDilationPriorityConflictException(errorString); - } - } - var engineOrder = new List(); foreach (var engine in engineGraph.TopologicalSort()) { diff --git a/test/EngineTest.cs b/test/EngineTest.cs index 849371a..889fc3f 100644 --- a/test/EngineTest.cs +++ b/test/EngineTest.cs @@ -960,7 +960,6 @@ namespace Tests static double dilatedDeltaTime; - [TimeDilationPriority(0)] class ActivateTimeDilationEngine : Engine { public override void Update(double dt) @@ -1001,54 +1000,39 @@ namespace Tests dilatedDeltaTime.Should().BeApproximately(0.3, 0.01); } - class ActivateTimeDilationWithoutPriorityEngine : Engine + class ActivateTimeDilationLowerFactorEngine : Engine { + private bool activated = false; + public override void Update(double dt) { - ActivateTimeDilation(0.2, 1, 1, 1); - } - } - - [Test] - public void ActivateTimeDilationWithoutPriorityThrows() - { - var worldBuilder = new WorldBuilder(); - worldBuilder.AddEngine(new ActivateTimeDilationWithoutPriorityEngine()); - - var world = worldBuilder.Build(); - - Assert.Throws(() => world.Update(0.01)); - } - - [TimeDilationPriority(0)] - class ActivateTimeDilationLowerPriorityEngine : Engine - { - public override void Update(double dt) - { - if (!TimeDilationActive) + if (!activated) { ActivateTimeDilation(0.2, 1, 1, 1); - } - else - { - dilatedDeltaTime = dt; + activated = true; } } } - [TimeDilationPriority(1)] - class ActivateTimeDilationHigherPriorityEngine : Engine + class ActivateTimeDilationHigherFactorEngine : Engine + { + private bool activated = false; + + public override void Update(double dt) + { + if (!activated) + { + ActivateTimeDilation(0.5, 1, 1, 1); + activated = true; + } + } + } + + class ReadDilatedDeltaTimeEngine : Engine { public override void Update(double dt) { - if (!TimeDilationActive) - { - ActivateTimeDilation(0.5, 1, 1, 1); - } - else - { - dilatedDeltaTime = dt; - } + dilatedDeltaTime = dt; } } @@ -1056,26 +1040,21 @@ namespace Tests public void MultipleActivateTimeDilation() { var worldBuilder = new WorldBuilder(); - worldBuilder.AddEngine(new ActivateTimeDilationLowerPriorityEngine()); - worldBuilder.AddEngine(new ActivateTimeDilationHigherPriorityEngine()); + worldBuilder.AddEngine(new ReadDilatedDeltaTimeEngine()); + worldBuilder.AddEngine(new ActivateTimeDilationLowerFactorEngine()); + worldBuilder.AddEngine(new ActivateTimeDilationHigherFactorEngine()); var world = worldBuilder.Build(); world.Update(0.01); // activate time dilation - world.Update(0.5); + world.Update(0.5); // 0.3 and 0.375 - dilatedDeltaTime.Should().BeApproximately(0.3, 0.01); - } + dilatedDeltaTime.Should().BeApproximately(0.3375, 0.01); - [Test] - public void MultipleActivateTimeDilationWithDuplicatePriority() - { - var worldBuilder = new WorldBuilder(); - worldBuilder.AddEngine(new ActivateTimeDilationEngine()); - worldBuilder.AddEngine(new ActivateTimeDilationLowerPriorityEngine()); + world.Update(5); - Assert.Throws(() => worldBuilder.Build()); + dilatedDeltaTime.Should().BeApproximately(5, 0.01); } static double undilatedDeltaTime; From dea3ad591e0f2fbd366c88ce3d99e9d79b474280 Mon Sep 17 00:00:00 2001 From: thatcosmonaut Date: Fri, 22 Nov 2019 13:18:43 -0800 Subject: [PATCH 4/6] test tweak --- test/EngineTest.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/EngineTest.cs b/test/EngineTest.cs index 889fc3f..a9dbbb4 100644 --- a/test/EngineTest.cs +++ b/test/EngineTest.cs @@ -1028,11 +1028,13 @@ namespace Tests } } + static bool timeDilationActive; class ReadDilatedDeltaTimeEngine : Engine { public override void Update(double dt) { dilatedDeltaTime = dt; + timeDilationActive = TimeDilationActive; } } @@ -1051,10 +1053,12 @@ namespace Tests world.Update(0.5); // 0.3 and 0.375 dilatedDeltaTime.Should().BeApproximately(0.3375, 0.01); + timeDilationActive.Should().BeTrue(); world.Update(5); dilatedDeltaTime.Should().BeApproximately(5, 0.01); + timeDilationActive.Should().BeFalse(); } static double undilatedDeltaTime; From 3ca8c50e8256dc2387b3a81dc0c45ab5e0e339dc Mon Sep 17 00:00:00 2001 From: thatcosmonaut Date: Fri, 22 Nov 2019 13:19:00 -0800 Subject: [PATCH 5/6] 0.17.0-preview2 --- encompass-cs/encompass-cs.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/encompass-cs/encompass-cs.csproj b/encompass-cs/encompass-cs.csproj index 12042c9..7aa0c8a 100644 --- a/encompass-cs/encompass-cs.csproj +++ b/encompass-cs/encompass-cs.csproj @@ -3,7 +3,7 @@ netstandard2.0 Encompass EncompassECS.Framework - 0.17.0-preview1 + 0.17.0-preview2 Evan Hemsley true Moonside Games From 6275e0290c990c71eb40f4f4599b6aa6ffd9a112 Mon Sep 17 00:00:00 2001 From: thatcosmonaut Date: Fri, 22 Nov 2019 13:26:58 -0800 Subject: [PATCH 6/6] todo notes --- TODO | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index b6feb3e..2822a8e 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,11 @@ -- implement IImmutableComponent and ITimedComponent +- immutable component system? + +- method to remove all components of a type without destroying Entities +- method to remove a component of a type without destroying entity + +- auto destroy entities that no longer have components + +- fast lookup for messages that contain entity references instead of `Where` loop? - look at test coverage - docs