diff --git a/CBSVisualizer/CBSVisualizer.Common/CBSVisualizer.Common.csproj b/CBSVisualizer/CBSVisualizer.Common/CBSVisualizer.Common.csproj index c2a9a5c1840e81f27607cafad8e1846512477103..f6a4ed07d99b090f85173c3b763aed92015e7d2b 100644 --- a/CBSVisualizer/CBSVisualizer.Common/CBSVisualizer.Common.csproj +++ b/CBSVisualizer/CBSVisualizer.Common/CBSVisualizer.Common.csproj @@ -5,7 +5,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="log4net" Version="2.0.9" /> + <PackageReference Include="log4net" Version="2.0.11" /> <PackageReference Include="Prism.Core" Version="7.2.0.1422" /> </ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer.Common/Interfaces/IQueue.cs b/CBSVisualizer/CBSVisualizer.Common/Interfaces/IQueue.cs index 9e84a6855c906e16462a1bba9b5f7c28f9fd8bcd..f4e36fc0d88af90203120fcf7d171368a984c5ca 100644 --- a/CBSVisualizer/CBSVisualizer.Common/Interfaces/IQueue.cs +++ b/CBSVisualizer/CBSVisualizer.Common/Interfaces/IQueue.cs @@ -1,14 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using CBSVisualizer.Messaging; -using CBSVisualizer.Messaging.Events; +using CBSVisualizer.Messaging.Models; namespace CBSVisualizer.Common.Interfaces { + /// <summary> + /// An implementation of this interface is kept by each queue. + /// This implementation handles ONLY the credit. + /// </summary> public interface IQueue { public long Credit @@ -18,25 +15,67 @@ namespace CBSVisualizer.Common.Interfaces public long IdleSlope { - get; set; } - public ObservableCollection<PriorityPacket> Queue - { - set; - } + /// <summary> + /// Determines if the QueueViewModel is currently allowed to send a packet. + /// </summary> + /// <returns>true if the internal rules of this IQueue allow it, false otherwise</returns> + /// <param name="sendCandidate">the packet that could be send if the internal condition is fulfilled</param> + bool CanSendPacket(PriorityPacket sendCandidate); + + /// <summary> + /// Called when the simulation starts. + /// </summary> + void OnSimulationStarted(); + + /// <summary> + /// Called when the simulation stops. + /// </summary> + void OnSimulationStopped(); + + /// <summary> + /// Called when the gate is opened. + /// </summary> + void OnGateOpened(); + + /// <summary> + /// Called when the gate is closed. + /// </summary> + void OnGateClosed(); + + /// <summary> + /// Called if the packet was accepted. + /// </summary> + void OnPacketAccepted(); - Task OnGateOpened(); + /// <summary> + /// Called if the packet was denied due to pre-closing. + /// </summary> + void OnPacketDeniedPreClosing(); - Task OnGateClosed(); + /// <summary> + /// Called if the packet was denied due to a higher priority packet. + /// </summary> + void OnPacketDeniedHigherPriority(); - Task OnPacketResponse(PacketSubmitResult result); + /// <summary> + /// Called if the transmission was preempted. + /// </summary> + void OnTransmissionPreempted(); - Task OnTransmissionStarted(long bytesPerSecond); + /// <summary> + /// Called when the transmission has started. + /// </summary> - Task OnPacketPreempted(int leftoverBytes); + void OnTransmissionStarted(); - Task OnTransmissionFinished(); + /// <summary> + /// Called when the transmission has finished. + /// </summary> + /// <param name="sentPacket"> the packet that was sent</param> + /// <param name="bytesPerSecond">the transmission bitrate in bytes per second.</param> + void OnTransmissionFinished(PriorityPacket sentPacket, long bytesPerSecond); } } diff --git a/CBSVisualizer/CBSVisualizer.Common/SynchronizationExtensions.cs b/CBSVisualizer/CBSVisualizer.Common/SynchronizationExtensions.cs index a355df6d37276bd5ce3d67f949bf45b13c8e9975..fe8c7e15c7bcdd4f6d4722959237400ed495a5d7 100644 --- a/CBSVisualizer/CBSVisualizer.Common/SynchronizationExtensions.cs +++ b/CBSVisualizer/CBSVisualizer.Common/SynchronizationExtensions.cs @@ -1,6 +1,7 @@ using CBSVisualizer.Messaging; using System.Collections.ObjectModel; using System.Linq; +using CBSVisualizer.Messaging.Models; namespace CBSVisualizer.Common { diff --git a/CBSVisualizer/CBSVisualizer.Core/CBSVisualizer.Core.csproj b/CBSVisualizer/CBSVisualizer.Core/CBSVisualizer.Core.csproj index f6367ccf057ab1a69986a6badf1692ef55a4cdb1..420b73a2984a8ceb109a665c939b123abbea8439 100644 --- a/CBSVisualizer/CBSVisualizer.Core/CBSVisualizer.Core.csproj +++ b/CBSVisualizer/CBSVisualizer.Core/CBSVisualizer.Core.csproj @@ -5,7 +5,7 @@ <AssemblyName>CBSVisualizer.Core</AssemblyName> </PropertyGroup> <ItemGroup> - <PackageReference Include="log4net" Version="2.0.9" /> + <PackageReference Include="log4net" Version="2.0.11" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> </ItemGroup> </Project> \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/CBSVisualizer.Messaging.csproj b/CBSVisualizer/CBSVisualizer.MessagingCore/CBSVisualizer.Messaging.csproj index 73d623a9496bb488d4af18a20db7f3bf2a2bcd0c..a7797547b6883ccf49d6e63615436169825628eb 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/CBSVisualizer.Messaging.csproj +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/CBSVisualizer.Messaging.csproj @@ -5,7 +5,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="log4net" Version="2.0.9" /> + <PackageReference Include="log4net" Version="2.0.11" /> <PackageReference Include="Prism.Core" Version="7.2.0.1422" /> </ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/CreditChangedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/CreditChangedEvent.cs index 6eea1f8e5bd287facb5615b9dabb4d8b8ff7a3e8..a66c728f3da882f561d808abe49da7fb55bb1bae 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/CreditChangedEvent.cs +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/CreditChangedEvent.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Prism.Events; +using Prism.Events; -namespace CBSVisualizer.Messaging.Events +namespace CBSVisualizer.Messaging.Events.Charts { public class CreditChangedEvent : PubSubEvent<(int Prio, long Credit)> { diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/PacketCountChangedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/PacketCountChangedEvent.cs index c61db7740b1e74d2ec4159ea62222d9435e3a9cf..17b3673d47203f025a52285791dafd836bec27fc 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/PacketCountChangedEvent.cs +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Charts/PacketCountChangedEvent.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Prism.Events; +using Prism.Events; -namespace CBSVisualizer.Messaging.Events +namespace CBSVisualizer.Messaging.Events.Charts { public class PacketCountChangedEvent : PubSubEvent<(int Prio, long NewCount)> { diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/GateOpenedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/GateOpenedEvent.cs deleted file mode 100644 index ea1eb9caad572c450e945fa2a3c7aa585d25df84..0000000000000000000000000000000000000000 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/GateOpenedEvent.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Prism.Events; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace CBSVisualizer.Messaging.Events -{ - public class GateOpenedEvent : PubSubEvent<(int OpenedTime, ISet<int> OpenedGates)> - { - } -} diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/GlobalGateOpenedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/GlobalGateOpenedEvent.cs new file mode 100644 index 0000000000000000000000000000000000000000..f222ec28f0d67f4c0c9eac3ef6be7b6f8e43e498 --- /dev/null +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/GlobalGateOpenedEvent.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; +using Prism.Events; + +namespace CBSVisualizer.Messaging.Events.Queue +{ + public class GlobalGateOpenedEvent : PubSubEvent<(int OpenedTime, ISet<int> OpenedGates)> + { + } +} diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketArrivedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketArrivedEvent.cs index 6435c7f58fbd0f3cbb2ff6e21d9eb4fefd16c1fe..6d486427bbaa17d1abd3e8920b29c0e4bb39a412 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketArrivedEvent.cs +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketArrivedEvent.cs @@ -1,11 +1,7 @@ -using Prism.Events; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using CBSVisualizer.Messaging.Models; +using Prism.Events; -namespace CBSVisualizer.Messaging.Events +namespace CBSVisualizer.Messaging.Events.Queue { public class PacketArrivedEvent : PubSubEvent<PriorityPacket> { diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketResponseEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitRequestEvent.cs similarity index 65% rename from CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketResponseEvent.cs rename to CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitRequestEvent.cs index e034bd35e216d1adace6baf103ad0b2777b16329..a0a639ed5d9b4ff39a4ba6f5aa2c9c0ee07c6006 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketResponseEvent.cs +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitRequestEvent.cs @@ -7,7 +7,7 @@ using Prism.Events; namespace CBSVisualizer.Messaging.Events.Queue { - public class PacketResponseEvent : PubSubEvent<(int Priority, PacketSubmitResult Result)> + public class PacketSubmitRequestEvent : PubSubEvent<ISet<int>> { } } diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitResponseEvent.cs similarity index 77% rename from CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitEvent.cs rename to CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitResponseEvent.cs index 51690fd74df03c1fac905e8d7dde54690159244f..0f3ac4f12b92a546cde37dfda4228b0411e8ed4f 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitEvent.cs +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitResponseEvent.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using CBSVisualizer.Messaging.Models; using Prism.Events; namespace CBSVisualizer.Messaging.Events.Queue @@ -11,7 +12,7 @@ namespace CBSVisualizer.Messaging.Events.Queue /// Sent from the queue to the link when it received a GateOpenedEvent. /// The payload is the packet that should be transmitted (or PriorityPacket.NoPacket) if we don't have any packets to transmit. /// </summary> - public class PacketSubmitEvent : PubSubEvent<PriorityPacket> + public class PacketSubmitResponseEvent : PubSubEvent<PriorityPacket> { } } diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitResultEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitResultEvent.cs new file mode 100644 index 0000000000000000000000000000000000000000..641c85f72e47b2dbd58ac946f5c25c4ae3048f56 --- /dev/null +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/PacketSubmitResultEvent.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Prism.Events; + +namespace CBSVisualizer.Messaging.Events.Queue +{ + public enum PacketSubmitResult + { + /// <summary> + /// The packet was accepted and will be sent. + /// </summary> + Accepted, + + /// <summary> + /// The packet was denied due to pre-closing. + /// </summary> + DeniedPreClosing, + + /// <summary> + /// The packet was denied due to a higher-prio packet. + /// </summary> + DeniedHigherPriority + } + + public class PacketSubmitResultEvent : PubSubEvent<(int Priority, PacketSubmitResult Result)> + { + } +} diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/QueueGateOpenedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/QueueGateOpenedEvent.cs new file mode 100644 index 0000000000000000000000000000000000000000..260d2a607931a47ba01fd4498ca2f124d1ca26e0 --- /dev/null +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/QueueGateOpenedEvent.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Prism.Events; + +namespace CBSVisualizer.Messaging.Events.Queue +{ + public class QueueGateOpenedEvent : PubSubEvent<ISet<int>> + { + } +} diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/RegisterLinkCallbackEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/RegisterLinkCallbackEvent.cs deleted file mode 100644 index 21304feb3849df82c630a62d71df1da1c59718a7..0000000000000000000000000000000000000000 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/RegisterLinkCallbackEvent.cs +++ /dev/null @@ -1,76 +0,0 @@ -using Prism.Events; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace CBSVisualizer.Messaging.Events -{ - public enum PacketSubmitResult - { - /// <summary> - /// The packet was accepted and will be sent. - /// </summary> - Accepted, - - /// <summary> - /// The packet was denied due to pre-closing. - /// </summary> - DeniedPreClosing, - - /// <summary> - /// The packet was - /// </summary> - DeniedHigherPrio - } - public interface ILinkCallback - { - /// <summary> - /// </summary> - /// <returns>the priority of the gate this callback belongs to</returns> - int GetPriority(); - - /// <summary> - /// Allows to perform necessary initialization operations. - /// </summary> - /// <returns></returns> - void Initialize(); - - /// <summary> - /// Called by the link when the gate of this queue has been opened. - /// </summary> - /// <param name="trySubmitFirstPacket">Called with the packet that should be sent. Returns the result of the attempt (Accepted or Denied because of whatever reason). </param> - void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket); - - /// <summary> - /// Called by the link if the gate of the queue has been closed. - /// </summary> - void GateClosed(); - - /// <summary> - /// Called by the gate if the transmission of the given packet has been preempted. - /// </summary> - /// <param name="preemptedPacket"> the preempted packet.</param> - /// <param name="leftoverBytes"> the bytes that are left to sent.</param> - void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes); - - /// <summary> - /// Called by the link when the transmission has started. - /// </summary> - /// <param name="bytesPerSecondRate"> the rate in bytes per second. </param> - void TransmissionStarted(long bytesPerSecondRate); - - /// <summary> - /// Called when the transmission of the last packet has been completed. - /// </summary> - void TransmissionCompleted(); - } - - /// <summary> - /// Used to register callbacks for different events that happen at the link. - /// </summary> - public class RegisterLinkCallbackEvent : PubSubEvent<ILinkCallback> - { - } -} diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/TransmissionFinishedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/TransmissionFinishedEvent.cs index 4b25797e8ef5f002d8e860f31e75c01147e66962..dba806418bd733a1f0e394f3192ec174fb58f90b 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/TransmissionFinishedEvent.cs +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Queue/TransmissionFinishedEvent.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Prism.Events; +using Prism.Events; namespace CBSVisualizer.Messaging.Events.Queue { diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStartedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStartedEvent.cs index 27a98321cff6b0c437d041022073002c374d6af9..9832ae73c45f8216561071ecf38fef02be5d96ba 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStartedEvent.cs +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStartedEvent.cs @@ -1,11 +1,6 @@ using Prism.Events; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace CBSVisualizer.Messaging.Events +namespace CBSVisualizer.Messaging.Events.Simulation { public class SimulationStartedEvent : PubSubEvent { diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStoppedEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStoppedEvent.cs index abf51a17a15c47caf3d5b0a7312007d276aeee73..3692413ec8a900f74638b91475d0ceaa7ba97be2 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStoppedEvent.cs +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/Simulation/SimulationStoppedEvent.cs @@ -1,11 +1,6 @@ using Prism.Events; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace CBSVisualizer.Messaging.Events +namespace CBSVisualizer.Messaging.Events.Simulation { public class SimulationStoppedEvent : PubSubEvent { diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Models/PriorityPacket.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Models/PriorityPacket.cs index 4600cc0b4c897659acc1146c6a86ac006ceeb511..0ab7fdbfa4e054a07c0282b6accd2a99177e9071 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Models/PriorityPacket.cs +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Models/PriorityPacket.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace CBSVisualizer.Messaging +namespace CBSVisualizer.Messaging.Models { public class PriorityPacket { @@ -13,7 +7,7 @@ namespace CBSVisualizer.Messaging private static readonly int PREEMPTION_TRAILER_SIZE_BYTES = 12; - public static PriorityPacket NoPacket { get; } = new PriorityPacket(int.MaxValue, int.MaxValue) { UniqueId = -1 }; + public static PriorityPacket NoPacket { get; } = new PriorityPacket(-1, int.MaxValue) { UniqueId = -1 }; /// <summary> /// The unique ID of the packet. @@ -40,13 +34,7 @@ namespace CBSVisualizer.Messaging /// </summary> public int TrailerBytes { get; private set; } - public int Size - { - get - { - return PayloadBytes + HeaderBytes + TrailerBytes; - } - } + public int Size => PayloadBytes + HeaderBytes + TrailerBytes; private static long currentId = 0; @@ -78,8 +66,6 @@ namespace CBSVisualizer.Messaging public override string ToString() { - - return $"ID: {UniqueId} Priority: {Priority}, Size: {Size}"; } } diff --git a/CBSVisualizer/CBSVisualizer.Modules.Charts/ViewModels/ChartsViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Charts/ViewModels/ChartsViewModel.cs index 54ee7b065482e7b3ea3f5773fa9c91fc484f2615..de8a7e7ad5ba66027b41cf50ba49130a993a1b12 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Charts/ViewModels/ChartsViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Charts/ViewModels/ChartsViewModel.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using CBSVisualizer.Core.Mvvm; using CBSVisualizer.Messaging.Events; +using CBSVisualizer.Messaging.Events.Charts; using Prism.Events; using Prism.Regions; using SciChart.Charting.Model.ChartSeries; @@ -20,8 +21,6 @@ namespace CBSVisualizer.Modules.Charts.ViewModels get; } = new ObservableConcurrentDictionary<int, ObservableCollection<IRenderableSeriesViewModel>>(); - public Func<double, string> Formatter { get; } = x => new DateTime((long) x).ToString("HH:mm:ss"); - public ChartsViewModel(IRegionManager regionManager, IEventAggregator eventAggregator) : base(regionManager) { @@ -59,20 +58,21 @@ namespace CBSVisualizer.Modules.Charts.ViewModels for (var idx = 0; idx <= 7; idx++) { + QueueSeries[idx] = new ObservableCollection<IRenderableSeriesViewModel> { new LineRenderableSeriesViewModel { StrokeThickness = 1, AntiAliasing = true, - DataSeries = new XyDataSeries<DateTime, double> { SeriesName = $"Queue {idx} Packets" }, + DataSeries = new XyDataSeries<DateTime, double> { SeriesName = $"Queue {idx} Packets"}, StyleKey = "PacketStyle", }, new LineRenderableSeriesViewModel { StrokeThickness = 1, AntiAliasing = true, - DataSeries = new XyDataSeries<DateTime, double> { SeriesName = $"Queue {idx} Credit" }, + DataSeries = new XyDataSeries<DateTime, double> { SeriesName = $"Queue {idx} Credit"}, StyleKey = "CreditStyle", } }; diff --git a/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml b/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml index ae844e2b72359c19fa11d23f2a9dbbcceedf57d2..f7c43911a6a023d948214a3c17112b1d6068808c 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml +++ b/CBSVisualizer/CBSVisualizer.Modules.Charts/Views/Charts.xaml @@ -10,28 +10,24 @@ prism:ViewModelLocator.AutoWireViewModel="True" > <UserControl.Resources> <Style TargetType="s:FastLineRenderableSeries" x:Key="PacketStyle"> - <Setter Property="StrokeDashArray" Value="5 5"/> - <Setter Property="StrokeThickness" Value="4"/> + <Setter Property="StrokeThickness" Value="1"/> <Setter Property="Stroke" Value="Orange"/> <Setter Property="SelectedSeriesStyle"> <Setter.Value> <Style TargetType="s:FastLineRenderableSeries"> - <Setter Property="StrokeDashArray" Value="5 5"/> - <Setter Property="StrokeThickness" Value="3"/> + <Setter Property="StrokeThickness" Value="1"/> <Setter Property="Stroke" Value="Orange"/> </Style> </Setter.Value> </Setter> </Style> <Style TargetType="s:FastLineRenderableSeries" x:Key="CreditStyle"> - <Setter Property="StrokeDashArray" Value="5 5"/> - <Setter Property="StrokeThickness" Value="4"/> + <Setter Property="StrokeThickness" Value="1"/> <Setter Property="Stroke" Value="Blue"/> <Setter Property="SelectedSeriesStyle"> <Setter.Value> <Style TargetType="s:FastLineRenderableSeries"> - <Setter Property="StrokeDashArray" Value="5 5"/> - <Setter Property="StrokeThickness" Value="3"/> + <Setter Property="StrokeThickness" Value="1"/> <Setter Property="Stroke" Value="Blue"/> </Style> </Setter.Value> @@ -56,15 +52,16 @@ <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10" LegendPlacement="Inside" GetLegendDataFor="AllSeries" ShowVisibilityCheckboxes="True"/> + <s:SeriesValueModifier/> </s:ModifierGroup> </s:SciChartSurface.ChartModifier> <s:SciChartSurface.XAxis> - <s:DateTimeAxis AutoRange="Always"/> + <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/> </s:SciChartSurface.XAxis> <s:SciChartSurface.YAxis> - <s:NumericAxis AutoRange="Always"/> + <s:NumericAxis AutoRange="Always" /> </s:SciChartSurface.YAxis> </s:SciChartSurface> @@ -75,11 +72,12 @@ <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10" LegendPlacement="Inside" GetLegendDataFor="AllSeries" ShowVisibilityCheckboxes="True"/> + <s:SeriesValueModifier/> </s:ModifierGroup> </s:SciChartSurface.ChartModifier> <s:SciChartSurface.XAxis> - <s:DateTimeAxis AutoRange="Always"/> + <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/> </s:SciChartSurface.XAxis> <s:SciChartSurface.YAxis> @@ -94,11 +92,12 @@ <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10" LegendPlacement="Inside" GetLegendDataFor="AllSeries" ShowVisibilityCheckboxes="True"/> + <s:SeriesValueModifier/> </s:ModifierGroup> </s:SciChartSurface.ChartModifier> <s:SciChartSurface.XAxis> - <s:DateTimeAxis AutoRange="Always"/> + <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/> </s:SciChartSurface.XAxis> <s:SciChartSurface.YAxis> @@ -113,11 +112,12 @@ <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10" LegendPlacement="Inside" GetLegendDataFor="AllSeries" ShowVisibilityCheckboxes="True"/> + <s:SeriesValueModifier/> </s:ModifierGroup> </s:SciChartSurface.ChartModifier> <s:SciChartSurface.XAxis> - <s:DateTimeAxis AutoRange="Always"/> + <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/> </s:SciChartSurface.XAxis> <s:SciChartSurface.YAxis> @@ -132,11 +132,12 @@ <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10" LegendPlacement="Inside" GetLegendDataFor="AllSeries" ShowVisibilityCheckboxes="True"/> + <s:SeriesValueModifier/> </s:ModifierGroup> </s:SciChartSurface.ChartModifier> <s:SciChartSurface.XAxis> - <s:DateTimeAxis AutoRange="Always"/> + <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/> </s:SciChartSurface.XAxis> <s:SciChartSurface.YAxis> @@ -151,11 +152,12 @@ <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10" LegendPlacement="Inside" GetLegendDataFor="AllSeries" ShowVisibilityCheckboxes="True"/> + <s:SeriesValueModifier/> </s:ModifierGroup> </s:SciChartSurface.ChartModifier> <s:SciChartSurface.XAxis> - <s:DateTimeAxis AutoRange="Always"/> + <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/> </s:SciChartSurface.XAxis> <s:SciChartSurface.YAxis> @@ -170,11 +172,12 @@ <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10" LegendPlacement="Inside" GetLegendDataFor="AllSeries" ShowVisibilityCheckboxes="True"/> + <s:SeriesValueModifier/> </s:ModifierGroup> </s:SciChartSurface.ChartModifier> <s:SciChartSurface.XAxis> - <s:DateTimeAxis AutoRange="Always"/> + <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/> </s:SciChartSurface.XAxis> <s:SciChartSurface.YAxis> @@ -189,11 +192,12 @@ <s:LegendModifier ShowLegend="True" Orientation="Horizontal" Margin="10" LegendPlacement="Inside" GetLegendDataFor="AllSeries" ShowVisibilityCheckboxes="True"/> + <s:SeriesValueModifier/> </s:ModifierGroup> </s:SciChartSurface.ChartModifier> <s:SciChartSurface.XAxis> - <s:DateTimeAxis AutoRange="Always"/> + <s:DateTimeAxis AutoRange="Always" SubDayTextFormatting="HH:mm:ss:fff"/> </s:SciChartSurface.XAxis> <s:SciChartSurface.YAxis> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj b/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj index 88a26a2c12a0e0f46aaf73769beed328a4c7a3ad..4bd8f21495747622572cea900f63cf161b85c9f7 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj @@ -5,8 +5,8 @@ <AssemblyName>CBSVisualizer.Modules.Link</AssemblyName> </PropertyGroup> <ItemGroup> - <PackageReference Include="log4net" Version="2.0.9" /> - <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> + <PackageReference Include="log4net" Version="2.0.11" /> + <PackageReference Include="MaterialDesignThemes" Version="3.2.0" /> <PackageReference Include="ParallelExtensionsExtras" Version="1.2.0" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> </ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs index b380d057c92a28cb8627a53477257823b53de76b..23472656e19a489174f274292185b45830af0091 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs @@ -1,61 +1,42 @@ using System; -using CBSVisualizer.Common; -using CBSVisualizer.Core.Mvvm; -using CBSVisualizer.Messaging; -using CBSVisualizer.Messaging.Events; -using CBSVisualizer.Services.SchedulingService.Interface; -using CBSVisualizer.Services.SettingsService.Implementation; -using log4net; -using Prism.Events; -using Prism.Regions; -using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; -using System.Net.Sockets; +using System.Reflection; using System.Threading; using System.Threading.Tasks; +using CBSVisualizer.Common; +using CBSVisualizer.Core.Mvvm; using CBSVisualizer.Messaging.Events.Queue; +using CBSVisualizer.Messaging.Events.Simulation; +using CBSVisualizer.Messaging.Models; +using CBSVisualizer.Services.SchedulingService.Interface; +using CBSVisualizer.Services.SettingService.Implementation; +using log4net; +using Prism.Events; +using Prism.Regions; namespace CBSVisualizer.Modules.Link.ViewModels { public class LinkViewModel : RegionViewModelBase, IDisposable { - public ObservableConcurrentDictionary<int, ValueContainer<bool>> GateStatusDictionary { get; } = - new ObservableConcurrentDictionary<int, ValueContainer<bool>> - { - [0] = new ValueContainer<bool>(false), - [1] = new ValueContainer<bool>(false), - [2] = new ValueContainer<bool>(false), - [3] = new ValueContainer<bool>(false), - [4] = new ValueContainer<bool>(false), - [5] = new ValueContainer<bool>(false), - [6] = new ValueContainer<bool>(false), - [7] = new ValueContainer<bool>(false), - }; - - private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private const string BitrateSettingKey = "bitrate"; - private readonly SettingService settingService; - private int transmittableBytes; - private readonly ConcurrentDictionary<int, PriorityPacket> sendCandidates = - new ConcurrentDictionary<int, PriorityPacket> - { - [0] = PriorityPacket.NoPacket, - [1] = PriorityPacket.NoPacket, - [2] = PriorityPacket.NoPacket, - [3] = PriorityPacket.NoPacket, - [4] = PriorityPacket.NoPacket, - [5] = PriorityPacket.NoPacket, - [6] = PriorityPacket.NoPacket, - [7] = PriorityPacket.NoPacket, - }; + private static readonly ILog Log = + LogManager.GetLogger(MethodBase.GetCurrentMethod()?.DeclaringType); + private readonly IEventAggregator eventAggregator; - private CancellationTokenSource tokenSrc = new CancellationTokenSource(); - private readonly BlockingCollection<PriorityPacket> sendQueue = new BlockingCollection<PriorityPacket>(new ConcurrentQueue<PriorityPacket>()); - public LinkViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, ISchedulingService schedulingService, SettingService settingService) + private readonly ConcurrentBag<PriorityPacket> sendCandidates = new ConcurrentBag<PriorityPacket>(); + + private readonly SettingService settingService; + + private Thread gateThread; + private CancellationTokenSource gateOpenedTokenSrc = new CancellationTokenSource(); + + public LinkViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, + ISchedulingService schedulingService, SettingService settingService) : base(regionManager) { var scheduler = schedulingService; @@ -64,56 +45,64 @@ namespace CBSVisualizer.Modules.Link.ViewModels InitializeQueueEventHandlers(); InitializeSimulationHandlers(scheduler); - InitializeSendingThread(); } - private void InitializeSendingThread() - { - new Thread(() => + public ObservableConcurrentDictionary<int, ValueContainer<bool>> GateStatusDictionary { get; } = + new ObservableConcurrentDictionary<int, ValueContainer<bool>> { - while (true) - { - var packetInTransit = sendQueue.Take(); - - // Send the packet that we've just selected. - eventAggregator.GetEvent<TransmissionStartedEvent>().Publish((packetInTransit.Priority, - settingService.GetSettingValue<int>(BitrateSettingKey))); - - Thread.Sleep(TimeSpan.FromSeconds(packetInTransit.Size / - settingService.GetSettingValue<double>(BitrateSettingKey))); + [0] = new ValueContainer<bool>(false), + [1] = new ValueContainer<bool>(false), + [2] = new ValueContainer<bool>(false), + [3] = new ValueContainer<bool>(false), + [4] = new ValueContainer<bool>(false), + [5] = new ValueContainer<bool>(false), + [6] = new ValueContainer<bool>(false), + [7] = new ValueContainer<bool>(false) + }; - eventAggregator.GetEvent<TransmissionFinishedEvent>().Publish(packetInTransit.Priority); - } - }).Start(); + public void Dispose() + { + gateOpenedTokenSrc?.Dispose(); } private void InitializeQueueEventHandlers() { - eventAggregator.GetEvent<GateOpenedEvent>().Subscribe(tuple => + eventAggregator.GetEvent<GlobalGateOpenedEvent>().Subscribe(tuple => { - log.Info($"The gates [{string.Join(", ", tuple.OpenedGates)}] have been opened for {tuple.OpenedTime} ms."); + // Set the status lamps accordingly. + SetStatusLamps(tuple.OpenedGates); - tokenSrc.Cancel(); - tokenSrc = new CancellationTokenSource(); + Log.Info( + $"The gates [{string.Join(", ", tuple.OpenedGates)}] have been opened for {tuple.OpenedTime} ms."); - Task.Run(async () => - { - try - { - await HandleGateOpened(tuple); - } - catch (TaskCanceledException) - { - } - }); + StopGateThread(); + + gateOpenedTokenSrc = new CancellationTokenSource(); + + // Calculate transmittable bytes. + var transmittableBytes = settingService.GetSettingValue<int>(BitrateSettingKey) * tuple.OpenedTime / 1000; + + eventAggregator.GetEvent<QueueGateOpenedEvent>().Publish(tuple.OpenedGates); + + gateThread = new Thread(() => HandleGateOpened(tuple.OpenedGates, transmittableBytes)); + gateThread.Start(); }); - eventAggregator.GetEvent<PacketSubmitEvent>().Subscribe(packet => + eventAggregator.GetEvent<PacketSubmitResponseEvent>().Subscribe(packet => { - sendCandidates[packet.Priority] = packet; + sendCandidates.Add(packet); }); } + private void StopGateThread() + { + gateOpenedTokenSrc.Cancel(); + if (gateThread != null && gateThread.IsAlive) + { + gateThread.Join(); + } + } + private void InitializeSimulationHandlers(ISchedulingService scheduler) { eventAggregator.GetEvent<SimulationStartedEvent>().Subscribe(async () => @@ -121,18 +110,18 @@ namespace CBSVisualizer.Modules.Link.ViewModels // Start scheduling. try { - log.Info("Simulation started."); + Log.Info("Simulation started."); await scheduler.StartScheduling().ConfigureAwait(false); } catch (TaskCanceledException) { - log.Info("Scheduling was cancelled by button press."); + Log.Info("Scheduling was cancelled by button press."); } }, true); eventAggregator.GetEvent<SimulationStoppedEvent>().Subscribe(() => { - tokenSrc.Cancel(); + gateOpenedTokenSrc?.Cancel(); // Stop the scheduler scheduler.StopScheduling(); @@ -140,80 +129,109 @@ namespace CBSVisualizer.Modules.Link.ViewModels // Reset all gate status lamps. SetStatusLamps(new HashSet<int>()); - log.Info("Simulation stopped"); + // Terminate sending thread. + StopGateThread(); + + Log.Info("Simulation stopped"); }, true); } - private async Task HandleGateOpened((int OpenedTime, ISet<int> OpenedGates) infoTuple) + private void HandleGateOpened(ISet<int> openedGates, int byteBudget) { - // Set the status lamps accordingly. - SetStatusLamps(infoTuple.OpenedGates); + // Copy transmittable bytes. + var totalBudget = byteBudget; - // Reset the packet in transit. - var packetInTransit = PriorityPacket.NoPacket; + while (!gateOpenedTokenSrc.IsCancellationRequested) + { + totalBudget = PerformCycle(openedGates, totalBudget); + } + } - // Calculate the transmittable bytes. - transmittableBytes = (settingService.GetSettingValue<int>(BitrateSettingKey) / 1000) * infoTuple.OpenedTime; + private int PerformCycle(ISet<int> openedGates, int cycleByteBudget) + { + // Init byte budget. + var cycleBudget = cycleByteBudget; - while (transmittableBytes > 0 && !tokenSrc.IsCancellationRequested) - { + // Cleanup the previous send candidates and request new packets from the queues with opened gates. + sendCandidates.Clear(); + eventAggregator.GetEvent<PacketSubmitRequestEvent>().Publish(openedGates); + + // Await all packets to arrive. + AwaitPacketArrival(openedGates.Count); - foreach (var openedGate in infoTuple.OpenedGates.OrderByDescending(packet => packet)) + // When all packets have arrived, sort them descending and check if we can send them in time. + var selectedPacket = PriorityPacket.NoPacket; + foreach (var sendCandidate in sendCandidates.Except(Enumerable.Repeat(PriorityPacket.NoPacket, 1)) + .OrderByDescending(packet => packet.Priority)) + { + if (selectedPacket == PriorityPacket.NoPacket && CanSendInTime(sendCandidate, cycleBudget)) { - if (tokenSrc.IsCancellationRequested) - { - return; - } - - // If we've already selected a packet for transmission, notify and continue. - if (packetInTransit != PriorityPacket.NoPacket) - { - eventAggregator.GetEvent<PacketResponseEvent>() - .Publish((openedGate, PacketSubmitResult.DeniedHigherPrio)); - continue; - } - - - // If we can send the send candidate in time, we notify him. - if (sendCandidates[openedGate] != PriorityPacket.NoPacket && - CanSendInTime(sendCandidates[openedGate])) - { - packetInTransit = sendCandidates[openedGate]; - transmittableBytes -= packetInTransit.Size; - eventAggregator.GetEvent<PacketResponseEvent>() - .Publish((openedGate, PacketSubmitResult.Accepted)); - - sendQueue.Add(packetInTransit); - sendCandidates[openedGate] = PriorityPacket.NoPacket; - } - else if (sendCandidates[openedGate] != PriorityPacket.NoPacket) - { - eventAggregator.GetEvent<PacketResponseEvent>() - .Publish((openedGate, PacketSubmitResult.DeniedPreClosing)); - } - } + // If we can send it in time and there was nothing selected yet... + // ... reduce transmittable bytes. + cycleBudget -= sendCandidate.Size; + + // ... notify the queue that its packet was selected. + eventAggregator.GetEvent<PacketSubmitResultEvent>() + .Publish((sendCandidate.Priority, PacketSubmitResult.Accepted)); - if (packetInTransit == PriorityPacket.NoPacket) + //... add it to the sending queue. + selectedPacket = sendCandidate; + } + else if (selectedPacket == PriorityPacket.NoPacket && !CanSendInTime(sendCandidate, cycleBudget)) { - continue; + // If nothing was selected and we cannot send in time, the packet was denied due to pre-closing. + // Notify the queue. + eventAggregator.GetEvent<PacketSubmitResultEvent>() + .Publish((sendCandidate.Priority, PacketSubmitResult.DeniedPreClosing)); } - - if (tokenSrc.IsCancellationRequested) + else { - return; + // Otherwise, the packet was denied due to higher prio. + // Notify the queue. + eventAggregator.GetEvent<PacketSubmitResultEvent>() + .Publish((sendCandidate.Priority, PacketSubmitResult.DeniedHigherPriority)); } + } + + // Send the packet that we've just selected. + if (selectedPacket != PriorityPacket.NoPacket) + { + TransmitPacket(selectedPacket); + } + + + return cycleBudget; + } - packetInTransit = PriorityPacket.NoPacket; + private void TransmitPacket(PriorityPacket selectedPacket) + { + Log.Info($"Sending {selectedPacket}..."); + eventAggregator.GetEvent<TransmissionStartedEvent>().Publish((selectedPacket.Priority, + settingService.GetSettingValue<int>(BitrateSettingKey))); + + Thread.Sleep(TimeSpan.FromSeconds(selectedPacket.Size / + settingService.GetSettingValue<double>(BitrateSettingKey))); + + Log.Info($"Transmission of {selectedPacket} finished!"); + eventAggregator.GetEvent<TransmissionFinishedEvent>().Publish(selectedPacket.Priority); + } + + private void AwaitPacketArrival(int openedGatesCount) + { + while (!gateOpenedTokenSrc.IsCancellationRequested && sendCandidates.Count != openedGatesCount) + { + Debug.WriteLine($"{Thread.CurrentThread.ManagedThreadId}: Awaiting {openedGatesCount}, having {sendCandidates.Count}"); + Thread.Sleep(50); } } - private bool CanSendInTime(PriorityPacket packet) + private bool CanSendInTime(PriorityPacket packet, int budget) { - return packet.Size <= transmittableBytes; + return packet.Size <= budget; } /// <summary> - /// Sets the status lamps according to the set. + /// Sets the status lamps according to the set. /// </summary> /// <param name="openedGates">the set containing the opened gates</param> private void SetStatusLamps(ICollection<int> openedGates) @@ -223,11 +241,5 @@ namespace CBSVisualizer.Modules.Link.ViewModels GateStatusDictionary[key].Value = openedGates.Contains(key); } } - - public void Dispose() - { - tokenSrc?.Dispose(); - sendQueue?.Dispose(); - } } } \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj index 390006bb7dc98c42cafd102ccbc279905ca926cb..e6f31b2b3b5c9b174e43a8b1b6ad2a88b307b033 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj @@ -5,8 +5,8 @@ <AssemblyName>CBSVisualizer.Modules.MenuBar</AssemblyName> </PropertyGroup> <ItemGroup> - <PackageReference Include="log4net" Version="2.0.9" /> - <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> + <PackageReference Include="log4net" Version="2.0.11" /> + <PackageReference Include="MaterialDesignThemes" Version="3.2.0" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> </ItemGroup> <ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs index c94c3c881febff7d49816adb0b76ade8603e9e95..51033fb23fbdd61e12bad61d9b684c84533bf842 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs @@ -4,29 +4,23 @@ using log4net; using Prism.Commands; using System.Threading; using System.Threading.Tasks; +using CBSVisualizer.Messaging.Events.Queue; +using CBSVisualizer.Messaging.Models; namespace CBSVisualizer.Modules.MenuBar.ViewModels { public partial class MenuBarViewModel { - private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + public DelegateCommand StartLoadGeneration { get; } - public DelegateCommand StartLoadGeneration { get; private set; } - - public DelegateCommand StopLoadGeneration { get; private set; } + public DelegateCommand StopLoadGeneration { get; } private bool loadGenerationInProgress = false; private bool LoadGenerationInProgress { - get - { - return loadGenerationInProgress; - } + get => loadGenerationInProgress; - set - { - SetProperty(ref loadGenerationInProgress, value); - } + set => SetProperty(ref loadGenerationInProgress, value); } private CancellationTokenSource tokenSource = new CancellationTokenSource(); @@ -51,20 +45,16 @@ namespace CBSVisualizer.Modules.MenuBar.ViewModels private async Task GenerateLoad() { - int packetCount = 0; - while (!tokenSource.IsCancellationRequested) { eventAggregator.GetEvent<PacketArrivedEvent>().Publish(GenerateRandomPacket()); await Task.Delay(settings.GetSettingValue<int>("interarrival_time")); - log.Info($"I've generated {++packetCount} packets"); } } private PriorityPacket GenerateRandomPacket() { PriorityPacket ret = packetService.GeneratePacket(); - log.Info(ret); return ret; } } diff --git a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs index ee49c0fc51ea31ae7fe3126a61faa90c701eef0b..880c210236aef8720c3d12cc07b8fe0d3505aba6 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs @@ -1,7 +1,8 @@ using CBSVisualizer.Core.Mvvm; using CBSVisualizer.Messaging.Events; +using CBSVisualizer.Messaging.Events.Simulation; using CBSVisualizer.Services.PacketService.Interface; -using CBSVisualizer.Services.SettingsService.Implementation; +using CBSVisualizer.Services.SettingService.Implementation; using Prism.Commands; using Prism.Events; using Prism.Regions; diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj index 4028604f50fa2c2ce55fe7dfe3128eeca4aca053..ca0e11e4edfcc015da7acb86d4d2ec1a2e7f525f 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj @@ -5,8 +5,8 @@ <AssemblyName>CBSVisualizer.Modules.Queue.QueueGroup</AssemblyName> </PropertyGroup> <ItemGroup> - <PackageReference Include="log4net" Version="2.0.9" /> - <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> + <PackageReference Include="log4net" Version="2.0.11" /> + <PackageReference Include="MaterialDesignThemes" Version="3.2.0" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> </ItemGroup> <ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/QueueGroupModule.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/QueueGroupModule.cs index 8bc55b4cfc34ca6c9f89563a3fe100ad72c7fbdf..93a7dd701af2046583c9b99351817295159afab8 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/QueueGroupModule.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/QueueGroupModule.cs @@ -1,10 +1,9 @@ using CBSVisualizer.Core; -using CBSVisualizer.Modules.Queue.QueueGroup.Views; using Prism.Ioc; using Prism.Modularity; using Prism.Regions; -namespace CBSVisualizer.Modules.Queue.QueueGroup +namespace CBSVisualizer.Modules.QueueGroup { public class QueueGroupModule : IModule { diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/ViewModels/QueueGroupViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/ViewModels/QueueGroupViewModel.cs index 81bc3b6cecbedc1da0d6d89adf78ee2c6368d31d..46a91e57c3d0ca04f6d6f51a5a28f4b05de5919d 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/ViewModels/QueueGroupViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/ViewModels/QueueGroupViewModel.cs @@ -1,16 +1,7 @@ using CBSVisualizer.Core.Mvvm; -using CBSVisualizer.Modules.Queue.ViewModels; -using Prism.Commands; -using Prism.Mvvm; using Prism.Regions; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace CBSVisualizer.Modules.Queue.QueueGroup.ViewModels +namespace CBSVisualizer.Modules.QueueGroup.ViewModels { public class QueueGroupViewModel : RegionViewModelBase { diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml index 091e5a5f3f375a74b022b2c3597034f7ec6a13df..82db6dfb6169f3c925f8798646a3d434a6730499 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml @@ -1,7 +1,6 @@ -<UserControl x:Class="CBSVisualizer.Modules.Queue.QueueGroup.Views.QueueGroup" +<UserControl x:Class="CBSVisualizer.Modules.QueueGroup.Views.QueueGroup" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:local="clr-namespace:CBSVisualizer.Modules.Queue.QueueGroup.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs index f9174517046edf5d5e791795b9c0d837b080d670..72b4c92eec965491512a3a7d4034ef444a5c04a2 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs @@ -1,37 +1,24 @@ -using CBSVisualizer.Modules.Queue.ViewModels; +using System.Windows.Controls; +using CBSVisualizer.Modules.Queue.ViewModels; using CBSVisualizer.Services.PacketService.Interface; +using CBSVisualizer.Services.SettingService.Implementation; using Prism.Events; -using Prism.Ioc; using Prism.Regions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; -namespace CBSVisualizer.Modules.Queue.QueueGroup.Views +namespace CBSVisualizer.Modules.QueueGroup.Views { /// <summary> /// Interaction logic for ViewA.xaml /// </summary> public partial class QueueGroup : UserControl { - public QueueGroup(IRegionManager regionManager, IEventAggregator eventAggregator, IPacketService packetService) + public QueueGroup(IRegionManager regionManager, IEventAggregator eventAggregator, IPacketService packetService, SettingService settingService) { InitializeComponent(); for (int prio = 7; prio >= 0; prio--) { - Queue.Views.Queue newQueue = new Queue.Views.Queue(new QueueViewModel(regionManager, eventAggregator, prio, packetService)); + Queue.Views.Queue newQueue = new Queue.Views.Queue(new QueueViewModel(regionManager, eventAggregator, prio, packetService, settingService)); Grid.SetRow(newQueue, 7 - prio); Grid.Children.Add(newQueue); } diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj b/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj index 44a18e90abdee68d8ccfa3c53825e3578dd46e4a..5759bee39f2b1a03229c7d44779833e97cc530be 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj @@ -5,8 +5,8 @@ <AssemblyName>CBSVisualizer.Modules.Queue</AssemblyName> </PropertyGroup> <ItemGroup> - <PackageReference Include="log4net" Version="2.0.9" /> - <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> + <PackageReference Include="log4net" Version="2.0.11" /> + <PackageReference Include="MaterialDesignThemes" Version="3.2.0" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> </ItemGroup> <ItemGroup> @@ -14,5 +14,6 @@ <ProjectReference Include="..\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> <ProjectReference Include="..\CBSVisualizer.MessagingCore\CBSVisualizer.Messaging.csproj" /> <ProjectReference Include="..\CBSVisualizer.Services.PacketService\CBSVisualizer.Services.PacketService.csproj" /> + <ProjectReference Include="..\CBSVisualizer.Services.SettingsService\CBSVisualizer.Services.SettingService.csproj" /> </ItemGroup> </Project> \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/CbsQueueBase.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/CbsQueueBase.cs new file mode 100644 index 0000000000000000000000000000000000000000..afd71c4342f442d7cce09925ab8a313a3a085054 --- /dev/null +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/CbsQueueBase.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Diagnostics; +using System.Reflection; +using CBSVisualizer.Common.Interfaces; +using CBSVisualizer.Messaging.Events.Charts; +using CBSVisualizer.Messaging.Models; +using log4net; +using Prism.Events; +using Prism.Mvvm; + +namespace CBSVisualizer.Modules.Queue.QueueImplementations +{ + internal abstract class CbsQueueBase : BindableBase, IQueue + { + protected readonly IEventAggregator EventAggregator; + protected readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod()?.DeclaringType); + protected readonly int Priority; + protected readonly ReadOnlyCollection<PriorityPacket> ReadOnlyQueue; + private readonly object creditLock = new object(); + + private long lastUpdateTimestamp; + + private long credit; + + private long internalSlopeBytesPerSecond; + + protected CbsQueueBase(int priority, ReadOnlyCollection<PriorityPacket> readOnlyQueue, + IEventAggregator eventAggregator) + { + Priority = priority; + ReadOnlyQueue = readOnlyQueue; + EventAggregator = eventAggregator; + PropertyChanged += HandleCreditChanged; + } + + public long Credit + { + get + { + lock (creditLock) + { + return credit; + } + } + protected set + { + lock (creditLock) + { + SetProperty(ref credit, value); + } + } + } + + public long IdleSlope + { + private get; + set; + } + + public bool CanSendPacket(PriorityPacket sendCandidate) + { + UpdateUsingInternalSlope(); + return Credit >= 0; + } + + public void OnSimulationStarted() + { + // Reset everything. + Credit = 0; + internalSlopeBytesPerSecond = 0; + lastUpdateTimestamp = 0; + } + + public void OnSimulationStopped() + { + } + + public void OnGateOpened() + { + ApplyDefaultCreditRule(); + } + + public abstract void OnGateClosed(); + + public void OnPacketAccepted() + { + UpdateUsingInternalSlope(); + Debug.WriteLine($"Queue {Priority}: My Packet was accepted."); + } + + public abstract void OnPacketDeniedPreClosing(); + + public void OnPacketDeniedHigherPriority() + { + UpdateUsingInternalSlope(); + Debug.WriteLine($"Queue {Priority}: My Packet was denied due to higher priority."); + } + + public void OnTransmissionPreempted() + { + UpdateUsingInternalSlope(); + } + + protected void UpdateUsingInternalSlope() + { + UpdateCredit(internalSlopeBytesPerSecond); + } + + public void OnTransmissionStarted() + { + UpdateCredit(0); + } + + public void OnTransmissionFinished(PriorityPacket packetInTransit, long bytesPerSecond) + { + // Update credit manually. + Credit += (IdleSlope - bytesPerSecond) * packetInTransit.Size / bytesPerSecond; + + ApplyDefaultCreditRule(); + } + + private void HandleCreditChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName != null && e.PropertyName.Equals("Credit")) + { + EventAggregator.GetEvent<CreditChangedEvent>().Publish((Priority, Credit)); + } + } + + private void ApplyDefaultCreditRule() + { + UpdateUsingInternalSlope(); + if (ReadOnlyQueue.Count > 0 || Credit < 0) + { + UpdateCredit(IdleSlope); + } + else + { + UpdateCredit(0); + } + } + + /// <summary> + /// Updates the credit with the current internal slope and restarts the timer. + /// </summary> + /// <param name="newInternalSlopeBytesPerSecond">the new internal slope.</param> + protected void UpdateCredit(long newInternalSlopeBytesPerSecond) + { + lock (creditLock) + { + var now = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + + var deltaCredit = 0L; + if (lastUpdateTimestamp != 0) + { + deltaCredit = internalSlopeBytesPerSecond * (now - lastUpdateTimestamp) / 1000; + } + + Credit += deltaCredit; + + // Update the internal slope and the min value. + internalSlopeBytesPerSecond = newInternalSlopeBytesPerSecond; + + // Reset update timestamp. + lastUpdateTimestamp = now; + } + } + } +} \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/FrozenBehaviourQueue.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/FrozenBehaviourQueue.cs new file mode 100644 index 0000000000000000000000000000000000000000..142f1d7271ff2e8ea5e0cd360688c0c5d74a2c9d --- /dev/null +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/FrozenBehaviourQueue.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CBSVisualizer.Messaging.Models; +using Prism.Events; + +namespace CBSVisualizer.Modules.Queue.QueueImplementations +{ + internal class FrozenBehaviourQueue : CbsQueueBase + { + public FrozenBehaviourQueue(int priority, ReadOnlyCollection<PriorityPacket> readOnlyQueue, IEventAggregator eventAggregator) + : base(priority, readOnlyQueue, eventAggregator) + { + } + + public override void OnGateClosed() + { + // Nothing happens here, as the credit is frozen in the Pre-Closing. + } + + /// <summary> + /// The credit is frozen in the pre-closing phase. + /// </summary> + public override void OnPacketDeniedPreClosing() + { + UpdateCredit(0); + } + } +} diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/NoCbsQueue.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/NoCbsQueue.cs index 445627309655496f4ccef9be5ea432bcbda48f7e..35a1bc567a8fc53d1f5dfaeee7dc36cb5e558231 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/NoCbsQueue.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/NoCbsQueue.cs @@ -1,83 +1,56 @@ -using System.Collections.ObjectModel; -using System.Threading.Tasks; -using CBSVisualizer.Common; -using CBSVisualizer.Common.Interfaces; -using CBSVisualizer.Messaging; -using CBSVisualizer.Messaging.Events; -using CBSVisualizer.Messaging.Events.Queue; -using log4net; -using Prism.Events; +using CBSVisualizer.Common.Interfaces; +using CBSVisualizer.Messaging.Models; namespace CBSVisualizer.Modules.Queue.QueueImplementations { - class NoCbsQueue : IQueue + internal class NoCbsQueue : IQueue { public long Credit { get; } = 0; + public long IdleSlope { get; set; } - public long IdleSlope { get; set; } = 0; + public bool CanSendPacket(PriorityPacket sendCandidate) + { + return true; + } - private ObservableCollection<PriorityPacket> queue; - private readonly IEventAggregator eventAggregator; - private readonly int priority; - private PriorityPacket lastSubmittedPacket = PriorityPacket.NoPacket; - private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod()?.DeclaringType); + public void OnSimulationStarted() + { + } + + public void OnSimulationStopped() + { + } - public ObservableCollection<PriorityPacket> Queue + public void OnGateOpened() { - set => queue = value; } - public NoCbsQueue(int priority, IEventAggregator eventAggregator) + public void OnGateClosed() { - this.eventAggregator = eventAggregator; - this.priority = priority; } - public Task OnGateOpened() + public void OnPacketAccepted() { - // Try to send a packet if we have any available. - lastSubmittedPacket = queue.GetFirstSynchronized(); - eventAggregator.GetEvent<PacketSubmitEvent>().Publish(lastSubmittedPacket); - return Task.CompletedTask; } - public Task OnGateClosed() + public void OnPacketDeniedPreClosing() { - // Do nothing. - return Task.CompletedTask; } - public Task OnTransmissionStarted(long bytesPerSecond) + public void OnPacketDeniedHigherPriority() { - // Do nothing :-) - return Task.CompletedTask; } - public Task OnPacketPreempted(int leftoverBytes) + public void OnTransmissionPreempted() { - // Add a new packet with the leftover bytes and the preemption headers. - queue.PrependSynchronized(new PriorityPacket(priority, leftoverBytes)); - return Task.CompletedTask; } - public Task OnTransmissionFinished() + public void OnTransmissionStarted() { - // Try to submit the next packet. - return OnGateOpened(); } - public Task OnPacketResponse(PacketSubmitResult result) + public void OnTransmissionFinished(PriorityPacket packetInTransit, long bytesPerSecond) { - if (result == PacketSubmitResult.Accepted) - { - queue.RemoveSynchronized(lastSubmittedPacket); - lastSubmittedPacket = PriorityPacket.NoPacket; - return Task.CompletedTask; - } - else - { - return OnGateOpened(); - } } } } diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/ReturnToZeroQueue.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/ReturnToZeroQueue.cs new file mode 100644 index 0000000000000000000000000000000000000000..0a8e33946f3d2cfdcd64be2ba685813dc8d4d5b9 --- /dev/null +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/ReturnToZeroQueue.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CBSVisualizer.Messaging.Models; +using Prism.Events; + +namespace CBSVisualizer.Modules.Queue.QueueImplementations +{ + internal class ReturnToZeroQueue : CbsQueueBase + { + public ReturnToZeroQueue(int priority, ReadOnlyCollection<PriorityPacket> readOnlyQueue, IEventAggregator eventAggregator) : base(priority, readOnlyQueue, eventAggregator) + { + } + + void HandleReturnToZero() + { + UpdateUsingInternalSlope(); + if (Credit > 0) + { + UpdateCredit(0); + Credit = 0; + } + } + + public override void OnGateClosed() + { + HandleReturnToZero(); + } + + public override void OnPacketDeniedPreClosing() + { + HandleReturnToZero(); + } + } +} diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/StandardBehaviourQueue.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/StandardBehaviourQueue.cs new file mode 100644 index 0000000000000000000000000000000000000000..eee2f124cb8c0474da9becb9e56f1e1142ee9b61 --- /dev/null +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/QueueImplementations/StandardBehaviourQueue.cs @@ -0,0 +1,30 @@ +using System.Collections.ObjectModel; +using CBSVisualizer.Messaging.Models; +using Prism.Events; + +namespace CBSVisualizer.Modules.Queue.QueueImplementations +{ + internal class StandardBehaviourQueue : CbsQueueBase + { + public StandardBehaviourQueue(int priority, ReadOnlyCollection<PriorityPacket> readOnlyQueue, IEventAggregator eventAggregator) : + base(priority, readOnlyQueue, eventAggregator) + { + } + + /// <summary> + /// The standard behaviour, labelled (S) considers that the credit + /// increases up to gate-close event, and is frozen while the gate is + /// closed. + /// </summary> + public override void OnGateClosed() + { + UpdateCredit(0); + } + + public override void OnPacketDeniedPreClosing() + { + // Credit increases up to the GateClosingEvent, so do nothing on pre-closing. + UpdateUsingInternalSlope(); + } + } +} diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs index 0df43c13ca333f7d3f500cd5a2065633216df69f..9ba6cda7bc09634803b6a084dd23bcb9eedd5fd4 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs @@ -1,24 +1,26 @@ -using CBSVisualizer.Core.Mvvm; -using CBSVisualizer.Messaging; -using CBSVisualizer.Messaging.Events; -using CBSVisualizer.Services.PacketService.Interface; -using log4net; -using Prism.Commands; -using Prism.Events; -using Prism.Regions; -using System; -using System.Collections.ObjectModel; +using System.Collections.ObjectModel; using System.Collections.Specialized; -using System.Threading; +using System.ComponentModel; +using System.Reflection; using System.Threading.Tasks; using CBSVisualizer.Common; using CBSVisualizer.Common.Interfaces; +using CBSVisualizer.Core.Mvvm; +using CBSVisualizer.Messaging.Events.Charts; using CBSVisualizer.Messaging.Events.Queue; +using CBSVisualizer.Messaging.Events.Simulation; +using CBSVisualizer.Messaging.Models; using CBSVisualizer.Modules.Queue.QueueImplementations; +using CBSVisualizer.Services.PacketService.Interface; +using CBSVisualizer.Services.SettingService.Implementation; +using log4net; +using Prism.Commands; +using Prism.Events; +using Prism.Regions; namespace CBSVisualizer.Modules.Queue.ViewModels { - public sealed partial class QueueViewModel : RegionViewModelBase + public sealed class QueueViewModel : RegionViewModelBase { public enum CreditBehaviour { @@ -35,90 +37,128 @@ namespace CBSVisualizer.Modules.Queue.ViewModels ReturnToZero } - private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod()?.DeclaringType); + private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod()?.DeclaringType); private readonly IEventAggregator eventAggregator; private readonly IPacketService packetService; + private volatile bool transmissionFinishedPending; + private IQueue queueImplementation; + private CreditBehaviour selectedCreditBehaviour; + private long idleSlope; + private SettingService settings; + + public QueueViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, int priority, + IPacketService packetService, SettingService settings) : + base(regionManager) + { + this.eventAggregator = eventAggregator; + this.packetService = packetService; + this.settings = settings; + + Priority = priority; + HandleLabels(); + + // Register handlers for the different events. + RegisterPacketEventHandlers(); + RegisterLinkEventHandlers(); + RegisterSimulationStartedEventHandlers(); + + PropertyChanged += HandleCreditBehaviourChanged; + Queue.CollectionChanged += QueueChangedHandler; + + QueueImplementation = new NoCbsQueue(); + } + public IQueue QueueImplementation { get => queueImplementation; - set => SetProperty(ref queueImplementation, value); } - private CreditBehaviour selectedCreditBehaviour; public CreditBehaviour SelectedCreditBehaviour { get => selectedCreditBehaviour; - set => SetProperty(ref selectedCreditBehaviour, value); } + + public long IdleSlope + { + get => idleSlope; + set => SetProperty(ref idleSlope, value); + } + public int Priority { get; } public string PrioLabel { get; private set; } public string PacketLabel { get; private set; } public ObservableCollection<PriorityPacket> Queue { get; } = new ObservableCollection<PriorityPacket>(); - public int IdleSlope { get; set; } = 100; public DelegateCommand GeneratePacketOnClick { get; private set; } - public QueueViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, int prio, IPacketService packetService) : - base(regionManager) + private void RegisterSimulationStartedEventHandlers() { - this.eventAggregator = eventAggregator; - this.packetService = packetService; - this.QueueImplementation = new NoCbsQueue(prio, eventAggregator) + eventAggregator.GetEvent<SimulationStartedEvent>().Subscribe(async () => { - Queue = Queue - }; - - Priority = prio; - HandleLabels(); - - // Register handlers for the different events. - RegisterPacketEventHandlers(); - RegisterLinkEventHandlers(); + QueueImplementation.IdleSlope = idleSlope; + await Task.Run(QueueImplementation.OnSimulationStarted); + }); - PropertyChanged += HandleCreditBehaviourChanged; - Queue.CollectionChanged += QueueChangedHandler; + eventAggregator.GetEvent<SimulationStoppedEvent>().Subscribe(async () => + { + await Task.Run(QueueImplementation.OnSimulationStopped); + }); } private void RegisterLinkEventHandlers() { - eventAggregator.GetEvent<GateOpenedEvent>().Subscribe(async tuple => + eventAggregator.GetEvent<QueueGateOpenedEvent>().Subscribe(async openedGates => { - if (tuple.OpenedGates == null) - { - return; - } - - if (tuple.OpenedGates.Contains(Priority)) + if (openedGates.Contains(Priority)) { - await QueueImplementation.OnGateOpened().ConfigureAwait(false); + await Task.Run(QueueImplementation.OnGateOpened); } else { - await QueueImplementation.OnGateClosed().ConfigureAwait(false); + await Task.Run(QueueImplementation.OnGateClosed); } }); eventAggregator.GetEvent<PacketPreemptedEvent>().Subscribe(async tuple => { - if (tuple.Priority != Priority) + var (priority, leftoverBytes) = tuple; + if (priority != Priority) { return; } - Log.Info($"Queue {Priority}: Packet was preempted!"); - await QueueImplementation.OnPacketPreempted(tuple.LeftoverBytes).ConfigureAwait(false); + transmissionFinishedPending = false; + + // Prepend leftover bytes and call queue implementation. + Queue.PrependSynchronized(new PriorityPacket(priority, leftoverBytes)); + await Task.Run(QueueImplementation.OnTransmissionPreempted); }); - eventAggregator.GetEvent<PacketResponseEvent>().Subscribe(async tuple => + eventAggregator.GetEvent<PacketSubmitResultEvent>().Subscribe(async tuple => { - if (tuple.Priority != Priority) + var (priority, result) = tuple; + if (priority != Priority) { return; } - await QueueImplementation.OnPacketResponse(tuple.Result).ConfigureAwait(false); + + // If the last submitted packet was accepted, remove the first packet from the queue. + // Otherwise, just call the corresponding handler. + if (result == PacketSubmitResult.Accepted) + { + transmissionFinishedPending = true; + await Task.Run(QueueImplementation.OnPacketAccepted); + } else if (result == PacketSubmitResult.DeniedHigherPriority) + { + await Task.Run(QueueImplementation.OnPacketDeniedHigherPriority); + } + else + { + await Task.Run(QueueImplementation.OnPacketDeniedPreClosing); + } }); eventAggregator.GetEvent<TransmissionFinishedEvent>().Subscribe(async priority => @@ -127,18 +167,39 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { return; } - Log.Info($"Queue {Priority}: Transmission finished!"); - await QueueImplementation.OnTransmissionFinished().ConfigureAwait(false); + + transmissionFinishedPending = false; + await Task.Run(() => QueueImplementation.OnTransmissionFinished(Queue.GetRemoveFirstSynchronized(), settings.GetSettingValue<long>("bitrate"))); }); eventAggregator.GetEvent<TransmissionStartedEvent>().Subscribe(async tuple => { - if (tuple.Priority != Priority) + var (priority, bytesPerSecond) = tuple; + if (priority != Priority) { return; } - Log.Info($"Queue {Priority}: Transmission started!"); - await QueueImplementation.OnTransmissionStarted(tuple.BytesPerSecond).ConfigureAwait(false); + + await Task.Run(QueueImplementation.OnTransmissionStarted); + }); + + + eventAggregator.GetEvent<PacketSubmitRequestEvent>().Subscribe(openedGates => + { + if (!openedGates.Contains(Priority)) + { + return; + } + + var sendCandidate = Queue.GetFirstSynchronized(); + if (!QueueImplementation.CanSendPacket(sendCandidate) || transmissionFinishedPending || sendCandidate == PriorityPacket.NoPacket ) + { + eventAggregator.GetEvent<PacketSubmitResponseEvent>().Publish(PriorityPacket.NoPacket); + } + else + { + eventAggregator.GetEvent<PacketSubmitResponseEvent>().Publish(sendCandidate); + } }); } @@ -167,15 +228,25 @@ namespace CBSVisualizer.Modules.Queue.ViewModels } } - private void HandleCreditBehaviourChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + private void HandleCreditBehaviourChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName != null && e.PropertyName.Equals("SelectedCreditBehaviour")) { - // TODO: Select appropriate credit behaviour. - queueImplementation = new NoCbsQueue(Priority, eventAggregator) + switch (SelectedCreditBehaviour) { - Queue = Queue - }; + case CreditBehaviour.Standard: + QueueImplementation = new StandardBehaviourQueue(Priority, new ReadOnlyCollection<PriorityPacket>(Queue), eventAggregator); + break; + case CreditBehaviour.Frozen: + QueueImplementation = new FrozenBehaviourQueue(Priority, new ReadOnlyCollection<PriorityPacket>(Queue), eventAggregator); + break; + case CreditBehaviour.ReturnToZero: + QueueImplementation = new ReturnToZeroQueue(Priority, new ReadOnlyCollection<PriorityPacket>(Queue), eventAggregator); + break; + default: + QueueImplementation = new NoCbsQueue(); + break; + } } } @@ -183,20 +254,14 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { eventAggregator.GetEvent<PacketArrivedEvent>().Subscribe(packet => { - if (packet.Priority != Priority) - { - return; - } + if (packet.Priority != Priority) return; Queue.AddSynchronized(packet); }); GeneratePacketOnClick = new DelegateCommand(async () => { - await Task.Run(() => - { - Queue.AddSynchronized(packetService.GeneratePacket(Priority)); - }); + await Task.Run(() => { Queue.AddSynchronized(packetService.GeneratePacket(Priority)); }); }); } } diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml index 9643543231c88b1cc8c6374799c2cf9dedea277c..0ab958531a191fb80d44a1e630b538adbac83576 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml @@ -2,7 +2,6 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" - xmlns:local="clr-namespace:CBSVisualizer.Modules.Queue.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" @@ -32,7 +31,7 @@ <TextBox materialDesign:HintAssist.Hint="Idle Slope [byte/s]" Style="{StaticResource MaterialDesignFloatingHintTextBox}" - x:Name="CreditRateTextBox" Text="{Binding QueueImplementation.IdleSlope}" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center" TextAlignment="Center" Grid.RowSpan="2"/> + x:Name="CreditRateTextBox" Text="{Binding IdleSlope}" Grid.Column="2" Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center" TextAlignment="Center" /> <ComboBox Style="{StaticResource MaterialDesignFloatingHintComboBox}" materialDesign:TextFieldAssist.UnderlineBrush="{DynamicResource SecondaryAccentBrush}" diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs index e20fa113f4e700db0a74d685dd072d612c2a6c5a..e926813e478310808e9e844ac5cb601f6e8d8949 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs @@ -38,11 +38,13 @@ namespace CBSVisualizer.Modules.Queue.Views private static ObservableCollection<CreditBehaviour> InitList() { - ObservableCollection<CreditBehaviour> ret = new ObservableCollection<CreditBehaviour>(); - ret.Add(CreditBehaviour.NoCbs); - ret.Add(CreditBehaviour.Frozen); - ret.Add(CreditBehaviour.Standard); - ret.Add(CreditBehaviour.ReturnToZero); + ObservableCollection<CreditBehaviour> ret = new ObservableCollection<CreditBehaviour> + { + CreditBehaviour.NoCbs, + CreditBehaviour.Frozen, + CreditBehaviour.Standard, + CreditBehaviour.ReturnToZero + }; return ret; } } diff --git a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj index f9da61e23557705f8f1ba54d825927701759910a..93b5cac740f9c2c01488040115f411df5dc33ab1 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj @@ -5,8 +5,8 @@ <AssemblyName>CBSVisualizer.Modules.SettingsDialog</AssemblyName> </PropertyGroup> <ItemGroup> - <PackageReference Include="log4net" Version="2.0.9" /> - <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> + <PackageReference Include="log4net" Version="2.0.11" /> + <PackageReference Include="MaterialDesignThemes" Version="3.2.0" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> </ItemGroup> <ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/ViewModels/SettingsDialogViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/ViewModels/SettingsDialogViewModel.cs index ad966f202e8564bfd697996917b7818ac820f16b..90d59d4b4c050d3b8a19ac55dcb2878abed8ca0d 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/ViewModels/SettingsDialogViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/ViewModels/SettingsDialogViewModel.cs @@ -1,8 +1,8 @@ using CBSVisualizer.Core.Mvvm; -using CBSVisualizer.Services.SettingsService.Implementation; using Prism.Regions; using Prism.Services.Dialogs; using System; +using CBSVisualizer.Services.SettingService.Implementation; namespace CBSVisualizer.Modules.SettingsDialog.ViewModels { diff --git a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/Views/SettingsDialog.xaml b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/Views/SettingsDialog.xaml index 6488678fc334cb4fd0427971e58494d2a1435c21..0c7bea91fa5fbcccb274c796da0bd02dba0d21ac 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/Views/SettingsDialog.xaml +++ b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/Views/SettingsDialog.xaml @@ -2,7 +2,6 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CBSVisualizer.Modules.SettingsDialog.Views" - xmlns:settings="clr-namespace:CBSVisualizer.Services.SettingsService.Types;assembly=CBSVisualizer.Services.SettingsService" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" @@ -10,6 +9,8 @@ xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:settings="clr-namespace:CBSVisualizer.Services.SettingService.Types;assembly=CBSVisualizer.Services.SettingsService" + xmlns:abstract="clr-namespace:CBSVisualizer.Services.SettingService.Types.Abstract;assembly=CBSVisualizer.Services.SettingsService" TextElement.Foreground="{DynamicResource MaterialDesignBody}" Background="{DynamicResource MaterialDesignPaper}" TextElement.FontWeight="Medium" @@ -59,7 +60,7 @@ </GroupBox> </DataTemplate> - <DataTemplate DataType="{x:Type settings:SettingGroup}"> + <DataTemplate DataType="{x:Type abstract:SettingGroup}"> <GroupBox Header="{Binding GroupName}"> <ItemsControl ItemsSource="{Binding Members}" /> </GroupBox> diff --git a/CBSVisualizer/CBSVisualizer.Services.GateControlListService/CBSVisualizer.Services.GateControlListService.csproj b/CBSVisualizer/CBSVisualizer.Services.GateControlListService/CBSVisualizer.Services.GateControlListService.csproj deleted file mode 100644 index 723cd685d3a48fff964017fccea5fc52f4743bbe..0000000000000000000000000000000000000000 --- a/CBSVisualizer/CBSVisualizer.Services.GateControlListService/CBSVisualizer.Services.GateControlListService.csproj +++ /dev/null @@ -1,15 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFramework>net5.0</TargetFramework> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="Prism.Core" Version="7.2.0.1422" /> - </ItemGroup> - - <ItemGroup> - <ProjectReference Include="..\Messaging\CBSVisualizer.Messaging\CBSVisualizer.Messaging.csproj" /> - </ItemGroup> - -</Project> diff --git a/CBSVisualizer/CBSVisualizer.Services.GateControlListService/GateControlListService.cs b/CBSVisualizer/CBSVisualizer.Services.GateControlListService/GateControlListService.cs deleted file mode 100644 index 5e69ed4e778807ea53781cefaaa56540c33d6462..0000000000000000000000000000000000000000 --- a/CBSVisualizer/CBSVisualizer.Services.GateControlListService/GateControlListService.cs +++ /dev/null @@ -1,72 +0,0 @@ -using CBSVisualizer.Messaging.Events; -using Prism.Events; -using System; -using System.Collections.Generic; -using System.Threading; - -namespace CBSVisualizer.Services.GateControlListService -{ - public class GateControlListService - { - /// <summary> - /// The time between a GateOpened and its GateClosedEvent. - /// </summary> - public const int MILLISECONDS_BETWEEN_EVENTS = 300; - - private readonly HashSet<int> QUEUE_0_SET = InitZeroQueueSet(); - - private readonly HashSet<int> OTHER_QUEUES_SET = InitOtherQueuesSet(); - - private volatile bool linkActive = false; - - private Thread eventSchedulerThread; - - private IEventAggregator eventAggregator; - - public GateControlListService(IEventAggregator eventAggregator) - { - this.eventAggregator = eventAggregator; - - eventAggregator.GetEvent<LinkActiveEvent>().Subscribe(() => - { - linkActive = true; - - eventSchedulerThread = new Thread(HandleEventScheduling); - eventSchedulerThread.Start(); - }); - eventAggregator.GetEvent<LinkDeactivatedEvent>().Subscribe(() => - { - linkActive = false; - eventSchedulerThread.Join(); - }); - } - - private void HandleEventScheduling(object obj) - { - while (linkActive) - { - // TODO: Implement this. - } - } - - private static HashSet<int> InitOtherQueuesSet() - { - HashSet<int> newSet = new HashSet<int>(); - newSet.Add(1); - newSet.Add(2); - newSet.Add(3); - newSet.Add(4); - newSet.Add(5); - newSet.Add(6); - newSet.Add(7); - return newSet; - } - - private static HashSet<int> InitZeroQueueSet() - { - HashSet<int> newSet = new HashSet<int>(); - newSet.Add(0); - return newSet; - } - } -} \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Services.PacketService/Implementation/RandomPacketService.cs b/CBSVisualizer/CBSVisualizer.Services.PacketService/Implementation/RandomPacketService.cs index be5b66a7cab5bdb8b0d2c16ee72359a8770e0e6e..6d9d3741fef760212aa989388a25fa5c7b26497b 100644 --- a/CBSVisualizer/CBSVisualizer.Services.PacketService/Implementation/RandomPacketService.cs +++ b/CBSVisualizer/CBSVisualizer.Services.PacketService/Implementation/RandomPacketService.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using CBSVisualizer.Messaging.Models; namespace CBSVisualizer.Services.PacketService.Implementation { diff --git a/CBSVisualizer/CBSVisualizer.Services.PacketService/Interface/IPacketService.cs b/CBSVisualizer/CBSVisualizer.Services.PacketService/Interface/IPacketService.cs index 0b7ca4c7af53071b4507b212f86373a57d7c8de3..89c925b7c683fc298dca958f1941bf30f824daf2 100644 --- a/CBSVisualizer/CBSVisualizer.Services.PacketService/Interface/IPacketService.cs +++ b/CBSVisualizer/CBSVisualizer.Services.PacketService/Interface/IPacketService.cs @@ -1,6 +1,7 @@ using CBSVisualizer.Messaging; using System; using System.Net.Mail; +using CBSVisualizer.Messaging.Models; namespace CBSVisualizer.Services.PacketService.Interface { diff --git a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/CBSVisualizer.Services.SchedulingService.csproj b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/CBSVisualizer.Services.SchedulingService.csproj index 20f292c650d0f693a36b2cb1468a1c85fad4880b..13ebb9059a91f1e78b5ef81e096896cfe67189c9 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/CBSVisualizer.Services.SchedulingService.csproj +++ b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/CBSVisualizer.Services.SchedulingService.csproj @@ -5,7 +5,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="log4net" Version="2.0.9" /> + <PackageReference Include="log4net" Version="2.0.11" /> <PackageReference Include="Prism.Core" Version="7.2.0.1422" /> </ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs index 8d88e5e46c38b8fc28dab41359acbd1ddbcebab6..1d325fda668be6c352bae7dd3c325a79eec804bb 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs @@ -1,27 +1,26 @@ using CBSVisualizer.Messaging.Events; using CBSVisualizer.Services.SchedulingService.Interface; -using CBSVisualizer.Services.SettingsService.Implementation; using log4net; using Prism.Events; using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using CBSVisualizer.Messaging.Events.Queue; namespace CBSVisualizer.Services.SchedulingService.Implementation { public class RandomSchedulingService : ISchedulingService { private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - private const int ProcessingDelayMs = 1500; private const string MinDelaySettingKey = "random_scheduler_min_delay"; private const string MaxDelaySettingKey = "random_scheduler_max_delay"; private CancellationTokenSource tokenSource; private readonly Random random = new Random(); - private readonly SettingService settings; + private readonly SettingService.Implementation.SettingService settings; private readonly IEventAggregator eventAggregator; - public RandomSchedulingService(IEventAggregator aggregator, SettingService settingService) + public RandomSchedulingService(IEventAggregator aggregator, SettingService.Implementation.SettingService settingService) { settings = settingService; eventAggregator = aggregator; @@ -38,20 +37,20 @@ namespace CBSVisualizer.Services.SchedulingService.Implementation // Publish GateOpenedEvent for the high prio queue. Log.Info("Publishing GateOpenedEvent [High Prio]"); - eventAggregator.GetEvent<GateOpenedEvent>().Publish((OpenedTime: highPrioOpenedTime, OpenedGates: new HashSet<int> { 7 })); + eventAggregator.GetEvent<GlobalGateOpenedEvent>().Publish((OpenedTime: highPrioOpenedTime, OpenedGates: new HashSet<int> { 7 })); // Wait for the specified time. - await Task.Delay(highPrioOpenedTime + ProcessingDelayMs, tokenSource.Token); + await Task.Delay(highPrioOpenedTime, tokenSource.Token); // Get the opening time for the low prio. var lowPrioOpenedTime = GetRandomWaitingTime(); // Publish another GateOpenedEvent for the other queues. Log.Info("Publishing GateOpenedEvent [Lower Prio]"); - eventAggregator.GetEvent<GateOpenedEvent>().Publish((OpenedTime: lowPrioOpenedTime, OpenedGates: new HashSet<int> { 0, 1, 2, 3, 4, 5, 6 })); + eventAggregator.GetEvent<GlobalGateOpenedEvent>().Publish((OpenedTime: lowPrioOpenedTime, OpenedGates: new HashSet<int> { 0, 1, 2, 3, 4, 5, 6 })); // Wait for the specified time again. - await Task.Delay(lowPrioOpenedTime + ProcessingDelayMs, tokenSource.Token); + await Task.Delay(lowPrioOpenedTime, tokenSource.Token); } } diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/CBSVisualizer.Services.SettingService.csproj b/CBSVisualizer/CBSVisualizer.Services.SettingsService/CBSVisualizer.Services.SettingService.csproj index 6ba72c0c5c7caf355fbd9215255973bf80481707..eda9d73f06d6235e9421e4ce3541bb4321da4ddf 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/CBSVisualizer.Services.SettingService.csproj +++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/CBSVisualizer.Services.SettingService.csproj @@ -7,7 +7,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="log4net" Version="2.0.9" /> + <PackageReference Include="log4net" Version="2.0.11" /> <PackageReference Include="Ookii.Dialogs.Wpf" Version="1.1.0" /> <PackageReference Include="Prism.Core" Version="7.2.0.1422" /> </ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs index a14d183572169550d609269f3b744662ee514b53..d4f53f405dbcdee903b9257292417b69256aa2bc 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs @@ -1,12 +1,11 @@ -using CBSVisualizer.Services.SettingsService.Types; -using System; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using System.Text; -using System.Threading.Tasks; +using CBSVisualizer.Services.SettingService.Types; +using CBSVisualizer.Services.SettingService.Types.Abstract; -namespace CBSVisualizer.Services.SettingsService.Implementation +namespace CBSVisualizer.Services.SettingService.Implementation { public class SettingService { diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/Setting.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/Setting.cs index 2c0b93af5768c256e50e4af6d706b03563a78c0a..f882a9ee6a14c2bc39c8dda8d3533a0bca5c516b 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/Setting.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/Setting.cs @@ -1,11 +1,7 @@ -using Prism.Mvvm; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System; +using Prism.Mvvm; -namespace CBSVisualizer.Services.SettingsService.Types +namespace CBSVisualizer.Services.SettingService.Types.Abstract { public class Setting : BindableBase { diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/SettingGroup.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/SettingGroup.cs index 4e1a965e16449060ee1326505d1132d1ae8c2c23..5bd1d43d3a17e5adb78afdd9cbf682b16bb5e10c 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/SettingGroup.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/Abstract/SettingGroup.cs @@ -1,12 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Configuration; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.ObjectModel; -namespace CBSVisualizer.Services.SettingsService.Types +namespace CBSVisualizer.Services.SettingService.Types.Abstract { public class SettingGroup { diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/BooleanSetting.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/BooleanSetting.cs index 7db018036c88776802e2a2c97c3bab1bef792a9d..44d30119ce0e95117e97a9ffdf60e53fdda46de5 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/BooleanSetting.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/BooleanSetting.cs @@ -1,11 +1,6 @@ -using Prism.Mvvm; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using CBSVisualizer.Services.SettingService.Types.Abstract; -namespace CBSVisualizer.Services.SettingsService.Types +namespace CBSVisualizer.Services.SettingService.Types { public class BooleanSetting : Setting<bool> { diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/PathSetting.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/PathSetting.cs index 3d37dc393f9b22d4f345fdce8d51b39c37b83c1a..cbd978e1be6c0a6a70de0b78f0d833a49e20c1ee 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/PathSetting.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/PathSetting.cs @@ -1,9 +1,9 @@ -using Prism.Commands; +using CBSVisualizer.Services.SettingService.Types.Abstract; using Microsoft.Win32; -using System; using Ookii.Dialogs.Wpf; +using Prism.Commands; -namespace CBSVisualizer.Services.SettingsService.Types +namespace CBSVisualizer.Services.SettingService.Types { public enum SelectionMode diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/SelectionSetting.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/SelectionSetting.cs index 9a9db697b3ea87e51191494767dd2ebc4717407e..19bd6d73e114fc4d065d52b55966c37f2108a741 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/SelectionSetting.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/SelectionSetting.cs @@ -1,11 +1,8 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using CBSVisualizer.Services.SettingService.Types.Abstract; -namespace CBSVisualizer.Services.SettingsService.Types +namespace CBSVisualizer.Services.SettingService.Types { public class SelectionSetting : Setting<string> { diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/StringSetting.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/StringSetting.cs index e5a20f16a7aebb7aa893bd070d6608a1b52aecb9..d7798131ea2f251711d5b5139ebc7170d7101fa1 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/StringSetting.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Types/StringSetting.cs @@ -1,11 +1,6 @@ -using Prism.Commands; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using CBSVisualizer.Services.SettingService.Types.Abstract; -namespace CBSVisualizer.Services.SettingsService.Types +namespace CBSVisualizer.Services.SettingService.Types { public class StringSetting : Setting<string> { diff --git a/CBSVisualizer/CBSVisualizer/App.xaml.cs b/CBSVisualizer/CBSVisualizer/App.xaml.cs index edc32b1bbb17622552a8148a1b8b454b78d9dc52..6b3c9e03a17f239339242535bde5a65122ab8260 100644 --- a/CBSVisualizer/CBSVisualizer/App.xaml.cs +++ b/CBSVisualizer/CBSVisualizer/App.xaml.cs @@ -2,16 +2,16 @@ using CBSVisualizer.Views; using System.Windows; using Prism.Modularity; -using CBSVisualizer.Services.SettingsService.Implementation; using CBSVisualizer.Services.SchedulingService.Implementation; -using CBSVisualizer.Modules.Queue.QueueGroup; using CBSVisualizer.Modules.Link; using CBSVisualizer.Modules.SettingsDialog; using CBSVisualizer.Modules.MenuBar; using CBSVisualizer.Modules.Charts; +using CBSVisualizer.Modules.QueueGroup; using CBSVisualizer.Services.PacketService.Implementation; using CBSVisualizer.Services.PacketService.Interface; using CBSVisualizer.Services.SchedulingService.Interface; +using CBSVisualizer.Services.SettingService.Implementation; using SciChart.Charting.Visuals; namespace CBSVisualizer diff --git a/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj b/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj index a34f54c868506f60c713a2343f501a8f50e037fa..bcbaa66d6567ea90fd752e55753b680e4a8c33c3 100644 --- a/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj +++ b/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj @@ -7,8 +7,8 @@ <AssemblyName>CBSVisualizer</AssemblyName> </PropertyGroup> <ItemGroup> - <PackageReference Include="log4net" Version="2.0.9" /> - <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> + <PackageReference Include="log4net" Version="2.0.11" /> + <PackageReference Include="MaterialDesignThemes" Version="3.2.0" /> <PackageReference Include="Prism.DryIoc" Version="7.2.0.1422" /> </ItemGroup> <ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml b/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml index e8f27f4db3919e229369693c8ae02230b5e07b50..5478e0ce5b4f4ffc5946ff4888652c9ee10863e9 100644 --- a/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml +++ b/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml @@ -18,7 +18,7 @@ </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> - <ColumnDefinition Width="*"/> + <ColumnDefinition Width="0.4*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.MenuBarRegion}" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3"/>