Skip to content

Commit

Permalink
🛠 MonoBehaviour SimulationController implementation, Bugfixes
Browse files Browse the repository at this point in the history
- Implemented CoroutineMonoSimulationController
- Various bugfixes for Event running and scheduling
- Added missing/Improved existing documentation comments
- Cleanup
  • Loading branch information
dolejska-daniel committed Dec 24, 2020
1 parent cebb1a3 commit eedbebf
Show file tree
Hide file tree
Showing 14 changed files with 100 additions and 35 deletions.
Empty file modified LICENSE
100644 → 100755
Empty file.
Empty file modified README.md
100644 → 100755
Empty file.
45 changes: 45 additions & 0 deletions Scripts/CoroutineMonoSimulationController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Collections;
using UnityEngine;
using UnityDES.Events;

namespace UnityDES
{
/// <summary>
/// The MonoBehaviour proxy class of <see cref="SimulationController"/>.
/// Simulation ticks will also be run in a coroutine.
/// </summary>
public class CoroutineMonoSimulationController : MonoBehaviour, ISimulationController<EventBase<SimulationTime>, SimulationTime>
{
//==========================================================================dd==
// MonoBehaviour METHODS
//==========================================================================dd==

public int TicksPerFrame;

protected virtual void Start()
{
Controller = new SimulationController(TicksPerFrame);
StartCoroutine("RunAvailableTicksCoroutine");
}

//==========================================================================dd==
// ISimulationController METHODS
//==========================================================================dd==

protected SimulationController Controller { get; set; }

public SimulationTime SimulationTime => Controller.SimulationTime;

public int SimulationSpeed { get => Controller.SimulationSpeed; set => Controller.SimulationSpeed = value; }

public bool Reschedule(EventBase<SimulationTime> @event) => Controller.Reschedule(@event);

public void RunAvailableTicks(float deltaTime) => Controller.RunAvailableTicks(deltaTime);

public IEnumerator RunAvailableTicksCoroutine() => Controller.RunAvailableTicksCoroutine();

public void Schedule(EventBase<SimulationTime> @event, int tickCount = 1) => Controller.Schedule(@event, tickCount);

public bool Unschedule(EventBase<SimulationTime> @event) => Controller.Unschedule(@event);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 0 additions & 16 deletions Scripts/Event.cs

This file was deleted.

3 changes: 2 additions & 1 deletion Scripts/Events/EventBase.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using UnityDES.Utils;

namespace UnityDES.Events
{
Expand All @@ -13,6 +12,8 @@ public abstract class EventBase<TKey> : IEvent<EventBase<TKey>, TKey>
{
public TKey QueueKey { get; set; }

public TKey SimulationTime { get => QueueKey; }

public IEnumerator<BehaviourResult> BehaviourCycle { get; protected set; }

/// <summary>
Expand Down
8 changes: 8 additions & 0 deletions Scripts/Events/SimulationTimeEvent.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@

namespace UnityDES.Events
{
/// <summary>
/// Simple base class for any event implementations with <see cref="SimulationTime"/> as a queue key.
/// </summary>
public abstract class SimulationTimeEvent : EventBase<SimulationTime>
{
protected SimulationTimeEvent(int ticksPerFrame) : base()
{
QueueKey = new SimulationTime(ticksPerFrame);
}

protected override void IncreaseKey(float time) => QueueKey.DoTick(time);
}
}
2 changes: 1 addition & 1 deletion Scripts/ISimulationController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public interface ISimulationController<TEvent, TKey>
/// <remarks>
/// This method expects to be called every rendered frame.
/// </remarks>
void RunAvailableTicks();
void RunAvailableTicks(float deltaTime);

/// <summary>
/// Adds the event (<paramref name="event"/>) to the simulation.
Expand Down
26 changes: 21 additions & 5 deletions Scripts/SimulationController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using UnityEngine;
using UnityDES.Utils;
using UnityDES.Events;
using System;

namespace UnityDES
{
Expand All @@ -13,6 +14,8 @@ public class SimulationController : ISimulationController<EventBase<SimulationTi
{
public SimulationTime SimulationTime { get; protected set; }

public float DeltaTime { get; protected set; }

public int SimulationSpeed { get; set; } = 1;

/// <summary>
Expand All @@ -39,23 +42,36 @@ public IEnumerator RunAvailableTicksCoroutine()
{
while (true)
{
RunAvailableTicks();
RunAvailableTicks(Time.deltaTime);
yield return null;
}
}

public void RunAvailableTicks()
public void RunAvailableTicks() => RunAvailableTicks(Time.deltaTime);

public void RunAvailableTicks(float deltaTime)
{
DeltaTime += deltaTime;

// calculate number of ticks to be run
var tickCount = SimulationTime.TicksPerFrame * Time.deltaTime;
var tickCount = (float)Math.Floor(SimulationTime.TicksPerFrame * DeltaTime);

// run the ticks
// if any ticks are run, subtract the number of ticks from the passed time
DeltaTime -= tickCount * SimulationTime.TickLength;
// adjust simulation speed
tickCount *= SimulationSpeed;

// run the calculated number of ticks
for (; tickCount > 0; tickCount--)
{
RunTick();
}
}

/// <summary>
/// Runs all available events for current simulation time.
/// Accordingly updates current simulation time after all events have been processed.
/// </summary>
public void RunTick()
{
// get the first event in the queue
Expand All @@ -71,7 +87,7 @@ public void RunTick()
}

// update the simulation time
SimulationTime.DoTick(SimulationSpeed);
SimulationTime.DoTick();
}

public void Schedule(EventBase<SimulationTime> @event, int tickCount = 1)
Expand Down
6 changes: 4 additions & 2 deletions Scripts/SimulationTime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

namespace UnityDES
{
/// <summary>
/// Structure representing concrete time position within the simulation.
/// </summary>
public class SimulationTime
{
/// <summary>
Expand All @@ -24,7 +27,7 @@ public class SimulationTime
/// <summary>
/// Time length of a single tick of the simulation time.
/// </summary>
public float TickLength { get; }
public float TickLength { get => 1f / TicksPerFrame; }

public SimulationTime(SimulationTime simTime)
: this(simTime.TicksPerFrame, simTime.Frame, simTime.Tick)
Expand All @@ -34,7 +37,6 @@ public SimulationTime(SimulationTime simTime)
public SimulationTime(int ticksPerFrame, int frame = 0, int tick = 0)
{
TicksPerFrame = ticksPerFrame;
TickLength = 1f / ticksPerFrame;
Frame = frame;
Tick = tick;
}
Expand Down
13 changes: 8 additions & 5 deletions Scripts/Utils/Heap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,14 @@ protected void SiftDown(int nodeIndex, int nodeCount)
var nextNodeIndex = nodeIndex;

var left = LeftChildIndex(nodeIndex);
if (left < nodeCount && IsGreaterThan(left, nextNodeIndex))
if (left < nodeCount && ShouldBeParentOf(left, nextNodeIndex))
{
// the value of the left subnode is greater than the value of the root
nextNodeIndex = left;
}

var right = RightChildIndex(nodeIndex);
if (right < nodeCount && IsGreaterThan(right, nextNodeIndex))
if (right < nodeCount && ShouldBeParentOf(right, nextNodeIndex))
{
// the value of the right subnode is greater than both the value of the left subnode and the root
nextNodeIndex = right;
Expand Down Expand Up @@ -176,7 +176,7 @@ protected void SiftUp(int nodeIndex)
return;

var parentNodeIndex = ParentIndex(nodeIndex);
if (IsGreaterThan(nodeIndex, parentNodeIndex))
if (ShouldBeParentOf(nodeIndex, parentNodeIndex))
{
SwapNodes(nodeIndex, parentNodeIndex);
SiftUp(parentNodeIndex);
Expand Down Expand Up @@ -326,8 +326,11 @@ protected void SwapNodes(int indexA, int indexB)
///
/// <param name="indexA">Index of the first node</param>
/// <param name="indexB">Index of the second node</param>
/// <returns><c>&gt;0</c> if value in node at <paramref name="indexA"/> is greater, <c>&lt;0</c> if the value is smaller or <c>0</c> if the values are equal</returns>
protected abstract bool IsGreaterThan(int indexA, int indexB);
/// <returns>
/// <c>True</c> if value in node at <paramref name="indexA"/> should be parent of value in node at <paramref name="indexB"/>,
/// <c>False</c> if it is the other way around or the values are equal
/// </returns>
protected abstract bool ShouldBeParentOf(int indexA, int indexB);

public void CopyTo(TItem[] array, int arrayIndex) => Items.CopyTo(array, arrayIndex);

Expand Down
5 changes: 3 additions & 2 deletions Scripts/Utils/MaxHeap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
namespace UnityDES.Utils
{
/// <summary>
///
/// Max version of heap structure (and sort).
/// Topmost items on the heap will be items with the largest values.
/// </summary>
public class MaxHeap<V> : Heap<V>
{
Expand All @@ -12,7 +13,7 @@ public MaxHeap(IEnumerable<V> items = null, IComparer<V> comparer = null)
{
}

protected override bool IsGreaterThan(int indexA, int indexB)
protected override bool ShouldBeParentOf(int indexA, int indexB)
{
return Comparer.Compare(Items[indexA], Items[indexB]) > 0;
}
Expand Down
5 changes: 3 additions & 2 deletions Scripts/Utils/MinHeap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
namespace UnityDES.Utils
{
/// <summary>
///
/// Min version of heap structure (and sort).
/// Topmost items on the heap will be items with the smallest values.
/// </summary>
public class MinHeap<V> : Heap<V>
{
Expand All @@ -12,7 +13,7 @@ public MinHeap(IEnumerable<V> items = null, IComparer<V> comparer = null)
{
}

protected override bool IsGreaterThan(int indexA, int indexB)
protected override bool ShouldBeParentOf(int indexA, int indexB)
{
return Comparer.Compare(Items[indexA], Items[indexB]) < 0;
}
Expand Down
4 changes: 4 additions & 0 deletions Tests/EventTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public class EventTests

public class PublicTestEvent : SimulationTimeEvent
{
public PublicTestEvent(int ticksPerFrame = 10) : base(ticksPerFrame)
{
}

public int State { get; protected set; } = 0;

public override IEnumerator<BehaviourResult> Behaviour()
Expand Down

0 comments on commit eedbebf

Please sign in to comment.