From 10b307ba4b3e33eb8891f1808be6436d33bd9f61 Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Sun, 6 Sep 2020 16:46:50 +0200 Subject: [PATCH 01/17] Fix "How many bytes do I have left to send before the gate closes?" mechanism + add processing delay to scheduler. --- .../ViewModels/LinkViewModel.cs | 46 ++++++++++++------- .../Implementation/RandomSchedulingService.cs | 5 +- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs index d2902db..36a4752 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs @@ -148,6 +148,11 @@ namespace CBSVisualizer.Modules.Link.ViewModels { await Task.Run(async () => { + var bitrate = settingService.GetSettingValue<int>("bitrate"); + var remainingBytes = infoTuple.OpenedTime * (bitrate / 1000); + + log.Info($"The link can send {remainingBytes} until the next GateCloseEvent."); + while (!tokenSource.IsCancellationRequested) { // Scan the callbacks for the highest-prio queue that wants to send a packet. @@ -157,10 +162,11 @@ namespace CBSVisualizer.Modules.Link.ViewModels { if (packetInTransit == PriorityPacket.NoPacket) { - if (CanSendInTime(infoTuple.OpenedTime, packet)) + if (CanSendInTime(ref remainingBytes, packet)) { activeQueue = queue; packetInTransit = packet; + log.Info($"Packet {packetInTransit} of queue {activeQueue} has been scheduled for transit."); return PacketSubmitResult.Accepted; } else @@ -181,37 +187,43 @@ namespace CBSVisualizer.Modules.Link.ViewModels continue; } - log.Info($"Packet {packetInTransit} of queue {activeQueue} has been scheduled for transit."); - // Once a packet was selected for transmission, we send it. transmittedBytes = 0; - var bitrate = settingService.GetSettingValue<int>("bitrate"); await linkCallbacks[activeQueue].TransmissionStarted(bitrate); - while (!tokenSource.IsCancellationRequested && transmittedBytes < packetInTransit.Size) + + try { - await Task.Delay(REFRESH_TIME_MS, tokenSource.Token); - transmittedBytes += REFRESH_TIME_MS * (bitrate / 1000); - log.Info($"Transmitted {transmittedBytes} of {packetInTransit.Size} bytes of packet {packetInTransit}."); - } + while (!tokenSource.IsCancellationRequested && transmittedBytes < packetInTransit.Size) + { + await Task.Delay(REFRESH_TIME_MS, tokenSource.Token); + transmittedBytes += REFRESH_TIME_MS * (bitrate / 1000); + log.Info($"Transmitted {transmittedBytes} of {packetInTransit.Size} bytes of packet {packetInTransit}."); + } - if (transmittedBytes >= packetInTransit.Size) + } catch (TaskCanceledException) { } + finally { await linkCallbacks[activeQueue].TransmissionCompleted(); log.Info($"{packetInTransit} of queue {activeQueue} has been sent successfully."); - } - // Reset the "Packet in transit" pointer. - packetInTransit = PriorityPacket.NoPacket; + // Reset the "Packet in transit" pointer. + packetInTransit = PriorityPacket.NoPacket; + } } }, tokenSource.Token); } - private bool CanSendInTime(int openedTime, PriorityPacket packet) + private bool CanSendInTime(ref int remainingBytes, PriorityPacket packet) { - // Bitrate * time = bits we can send in that time. - // if the packet is larger than that, we have to deny it due to pre-closing. - return packet.Size <= openedTime * (settingService.GetSettingValue<int>("bitrate") / 1000); + if (packet.Size <= remainingBytes) + { + log.Info($"Packet Size: {packet.Size}, remaining bytes until next GateCloseEvent: {remainingBytes}. {remainingBytes - packet.Size} bytes left."); + remainingBytes -= packet.Size; + return true; + } + + return false; } private void CloseInactiveGates(ISet<int> openedGates) diff --git a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs index 8bee7e8..ddccc65 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs @@ -12,6 +12,7 @@ namespace CBSVisualizer.Services.SchedulingService.Implementation public class RandomSchedulingService : ISchedulingService { private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private const int PROCESSING_DELAY_MS = 1500; private const string MIN_DELAY_SETTING_KEY = "random_scheduler_min_delay"; private const string MAX_DELAY_SETTING_KEY = "random_scheduler_max_delay"; private CancellationTokenSource tokenSource; @@ -40,7 +41,7 @@ namespace CBSVisualizer.Services.SchedulingService.Implementation log.Info("Published GateOpenedEvent [High Prio]"); // Wait for the specified time. - await Task.Delay(highPrioOpenedTime, tokenSource.Token); + await Task.Delay(highPrioOpenedTime + PROCESSING_DELAY_MS, tokenSource.Token); // Get the opening time for the low prio. int lowPrioOpenedTime = GetRandomWaitingTime(); @@ -50,7 +51,7 @@ namespace CBSVisualizer.Services.SchedulingService.Implementation log.Info("Published GateOpenedEvent [Lower Prio]"); // Wait for the specified time again. - await Task.Delay(lowPrioOpenedTime, tokenSource.Token); + await Task.Delay(lowPrioOpenedTime + PROCESSING_DELAY_MS, tokenSource.Token); } } -- GitLab From 4bff075cb5f72682979023c276776a5a3b6b7192 Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Sun, 6 Sep 2020 18:12:01 +0200 Subject: [PATCH 02/17] Add WPF Live Charts. Needs some love :-) --- .../ViewModels/LinkViewModel.cs | 1 - .../Views/QueueGroup.xaml | 1 + .../CBSVisualizer.Modules.Queue.csproj | 2 ++ .../ViewModels/QueueViewModel.cs | 28 ++++++++++++++++++- .../Views/Queue.xaml | 18 +++++++++--- 5 files changed, 44 insertions(+), 6 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs index 36a4752..1b96afe 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs @@ -200,7 +200,6 @@ namespace CBSVisualizer.Modules.Link.ViewModels transmittedBytes += REFRESH_TIME_MS * (bitrate / 1000); log.Info($"Transmitted {transmittedBytes} of {packetInTransit.Size} bytes of packet {packetInTransit}."); } - } catch (TaskCanceledException) { } finally { diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml index 4f47ea4..7dab185 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml @@ -25,6 +25,7 @@ <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> + <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TextBlock Text="Priority" Grid.Row="0" Grid.Column="0" TextAlignment="Center"/> <TextBlock Text="Packet Count" Grid.Row="0" Grid.Column="1" TextAlignment="Center"/> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj b/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj index 5fbb50f..98b739a 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj @@ -5,6 +5,8 @@ <AssemblyName>CBSVisualizer.Modules.Queue</AssemblyName> </PropertyGroup> <ItemGroup> + <PackageReference Include="LiveCharts" Version="0.9.7" /> + <PackageReference Include="LiveCharts.Wpf" Version="0.9.7" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> </ItemGroup> <ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs index 1b2a34e..2339590 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs @@ -1,6 +1,9 @@ using CBSVisualizer.Core.Mvvm; using CBSVisualizer.Messaging; using CBSVisualizer.Messaging.Events; +using LiveCharts; +using LiveCharts.Defaults; +using LiveCharts.Wpf; using Prism.Events; using Prism.Regions; using System; @@ -75,9 +78,13 @@ namespace CBSVisualizer.Modules.Queue.ViewModels /// </summary> public int IdleSlope { get; set; } = 100; + public SeriesCollection Series { get; set; } + public QueueViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, int prio) : base(regionManager) { + InitCharts(); + this.eventAggregator = eventAggregator; Priority = prio; @@ -86,10 +93,25 @@ namespace CBSVisualizer.Modules.Queue.ViewModels RegisterSimulationStartStopHandler(); PropertyChanged += HandleCreditBehaviourChanged; - eventAggregator.GetEvent<RegisterLinkCallbackEvent>().Publish(GetLinkCallback()); } + private void InitCharts() + { + Series = new SeriesCollection + { + new LineSeries { + Title = "Credit Values", + Values = new ChartValues<DateTimePoint>() { new DateTimePoint(DateTime.Now, 0) } + }, + + new LineSeries { + Title = "Packet Count", + Values = new ChartValues<DateTimePoint>() { new DateTimePoint(DateTime.Now, 0) } + } + }; + } + private void HandleCreditBehaviourChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName.Equals("SelectedCreditBehaviour")) @@ -191,7 +213,11 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { lock (queueLock) { + // Add packet. Queue.Add(packet); + + // Update chart value. + Series[1].Values.Add(new DateTimePoint(DateTime.Now, Queue.Count)); } } }); diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml index 4897b5c..5c77652 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml @@ -2,6 +2,7 @@ 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.Views" + xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" @@ -10,14 +11,23 @@ prism:ViewModelLocator.AutoWireViewModel="False" > <Grid> <Grid.ColumnDefinitions> - <ColumnDefinition Width="*"/> - <ColumnDefinition Width="*"/> - <ColumnDefinition Width="*"/> - <ColumnDefinition Width="*"/> + <ColumnDefinition Width="0.5*"/> + <ColumnDefinition Width="0.5*"/> + <ColumnDefinition Width="0.5*"/> + <ColumnDefinition Width="0.5*"/> + <ColumnDefinition Width="2*"/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding Priority}" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center"/> <TextBlock Text="{Binding Queue.Count}" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center"/> <TextBox x:Name="CreditRateTextBox" Text="{Binding IdleSlope}" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center"/> <ComboBox x:Name="CreditBehaviourBox" SelectedItem="{Binding SelectedCreditBehaviour}" Grid.Column="3" VerticalAlignment="Center" HorizontalAlignment="Center"/> + <lvc:CartesianChart Series="{Binding Series}" LegendLocation="Right" Grid.Column="4"> + <lvc:CartesianChart.AxisX> + <lvc:Axis Title="Time" LabelFormatter="{Binding XFormatter}" /> + </lvc:CartesianChart.AxisX> + <lvc:CartesianChart.AxisY> + <lvc:Axis Title="Credit"/> + </lvc:CartesianChart.AxisY> + </lvc:CartesianChart> </Grid> </UserControl> -- GitLab From cc268283c31e1f890fc1d2d342a9cddda5a82173 Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Mon, 7 Sep 2020 21:55:54 +0200 Subject: [PATCH 03/17] Switch to Material Design :-) --- .../CBSVisualizer.Common.csproj | 1 + .../CBSVisualizer.Core.csproj | 2 +- .../CBSVisualizer.Messaging.csproj | 1 + .../CBSVisualizer.Modules.Link.csproj | 3 ++ .../CBSVisualizer.Modules.MenuBar.csproj | 3 ++ .../CBSVisualizer.Modules.QueueGroup.csproj | 3 ++ .../Views/QueueGroup.xaml | 12 ------ .../Views/QueueGroup.xaml.cs | 7 ++-- .../CBSVisualizer.Modules.Queue.csproj | 3 ++ .../ViewModels/QueueViewModel.cs | 40 +++++++++++++++---- .../Views/Queue.xaml | 36 ++++++++++++----- ...BSVisualizer.Modules.SettingsDialog.csproj | 3 ++ ...sualizer.Services.SchedulingService.csproj | 2 +- ...SVisualizer.Services.SettingService.csproj | 1 + CBSVisualizer/CBSVisualizer/App.xaml | 7 ++++ .../CBSVisualizer/CBSVisualizer.csproj | 4 +- .../CBSVisualizer/Views/MainWindow.xaml | 9 ++++- 17 files changed, 100 insertions(+), 37 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.Common/CBSVisualizer.Common.csproj b/CBSVisualizer/CBSVisualizer.Common/CBSVisualizer.Common.csproj index 0a54f5c..6a7fe1b 100644 --- a/CBSVisualizer/CBSVisualizer.Common/CBSVisualizer.Common.csproj +++ b/CBSVisualizer/CBSVisualizer.Common/CBSVisualizer.Common.csproj @@ -5,6 +5,7 @@ </PropertyGroup> <ItemGroup> + <PackageReference Include="log4net" Version="2.0.9" /> <PackageReference Include="Prism.Core" Version="7.2.0.1422" /> </ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer.Core/CBSVisualizer.Core.csproj b/CBSVisualizer/CBSVisualizer.Core/CBSVisualizer.Core.csproj index 16f7d6c..f6367cc 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.8" /> + <PackageReference Include="log4net" Version="2.0.9" /> <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 a1193fe..73d623a 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/CBSVisualizer.Messaging.csproj +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/CBSVisualizer.Messaging.csproj @@ -5,6 +5,7 @@ </PropertyGroup> <ItemGroup> + <PackageReference Include="log4net" Version="2.0.9" /> <PackageReference Include="Prism.Core" Version="7.2.0.1422" /> </ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj b/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj index b2c95d5..58eb0a9 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj @@ -5,8 +5,11 @@ <AssemblyName>CBSVisualizer.Modules.Link</AssemblyName> </PropertyGroup> <ItemGroup> + <PackageReference Include="log4net" Version="2.0.9" /> + <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> <PackageReference Include="ParallelExtensionsExtras" Version="1.2.0" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> + <PackageReference Include="ShowMeTheXAML.MSBuild" Version="1.0.12" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Common\CBSVisualizer.Common.csproj" /> diff --git a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj index 39e0363..7ea0227 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj @@ -5,7 +5,10 @@ <AssemblyName>CBSVisualizer.Modules.MenuBar</AssemblyName> </PropertyGroup> <ItemGroup> + <PackageReference Include="log4net" Version="2.0.9" /> + <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> + <PackageReference Include="ShowMeTheXAML.MSBuild" Version="1.0.12" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj index 9a03652..45b7765 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj @@ -5,7 +5,10 @@ <AssemblyName>CBSVisualizer.Modules.Queue.QueueGroup</AssemblyName> </PropertyGroup> <ItemGroup> + <PackageReference Include="log4net" Version="2.0.9" /> + <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> + <PackageReference Include="ShowMeTheXAML.MSBuild" Version="1.0.12" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml index 7dab185..091e5a5 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml @@ -10,7 +10,6 @@ prism:ViewModelLocator.AutoWireViewModel="True" > <Grid x:Name="Grid"> <Grid.RowDefinitions> - <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> @@ -20,16 +19,5 @@ <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="*"/> - <ColumnDefinition Width="*"/> - <ColumnDefinition Width="*"/> - <ColumnDefinition Width="*"/> - <ColumnDefinition Width="*"/> - </Grid.ColumnDefinitions> - <TextBlock Text="Priority" Grid.Row="0" Grid.Column="0" TextAlignment="Center"/> - <TextBlock Text="Packet Count" Grid.Row="0" Grid.Column="1" TextAlignment="Center"/> - <TextBlock Text="Idle Slope [b/s]" Grid.Row="0" Grid.Column="2" TextAlignment="Center"/> - <TextBlock Text="Credit Behaviour" Grid.Row="0" Grid.Column="3" TextAlignment="Center"/> </Grid> </UserControl> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs index 3100399..c23cc56 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs @@ -27,11 +27,10 @@ namespace CBSVisualizer.Modules.Queue.QueueGroup.Views { InitializeComponent(); - for (int prio = 1; prio < 9; prio++) + for (int prio = 7; prio >= 0; prio--) { - Queue.Views.Queue newQueue = new Queue.Views.Queue(new QueueViewModel(regionManager, eventAggregator, prio - 1)); - Grid.SetRow(newQueue, 9 - prio); - Grid.SetColumnSpan(newQueue, 4); + Queue.Views.Queue newQueue = new Queue.Views.Queue(new QueueViewModel(regionManager, eventAggregator, prio)); + 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 98b739a..18306af 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj @@ -7,7 +7,10 @@ <ItemGroup> <PackageReference Include="LiveCharts" Version="0.9.7" /> <PackageReference Include="LiveCharts.Wpf" Version="0.9.7" /> + <PackageReference Include="log4net" Version="2.0.9" /> + <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> + <PackageReference Include="ShowMeTheXAML.MSBuild" Version="1.0.12" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs index 2339590..21f45d7 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs @@ -8,6 +8,7 @@ using Prism.Events; using Prism.Regions; using System; using System.Collections.ObjectModel; +using System.Collections.Specialized; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; @@ -24,10 +25,9 @@ namespace CBSVisualizer.Modules.Queue.ViewModels private const double CREDIT_REFRESH_RATE_S = 0.1; - private double currentCredit = 0; - private Task creditUpdateTask; + private double currentCredit = 0; public double CurrentCredit { get @@ -71,6 +71,12 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public int Priority { get; private set; } + public string PrioLabel { get; private set; } + + public string PacketLabel { get; private set; } + + + public ObservableCollection<PriorityPacket> Queue { get; private set; } = new ObservableCollection<PriorityPacket>(); /// <summary> @@ -83,17 +89,38 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public QueueViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, int prio) : base(regionManager) { - InitCharts(); - this.eventAggregator = eventAggregator; Priority = prio; + HandleLabels(); // Register handlers for the different events. RegisterPacketHandler(); RegisterSimulationStartStopHandler(); PropertyChanged += HandleCreditBehaviourChanged; + Queue.CollectionChanged += QueueChangedHandler; + eventAggregator.GetEvent<RegisterLinkCallbackEvent>().Publish(GetLinkCallback()); + + InitCharts(); + } + + private void HandleLabels() + { + if (Priority == 7) + { + PrioLabel = "Priority"; + PacketLabel = "Packet Count"; + } else + { + PrioLabel = ""; + PacketLabel = ""; + } + } + + private void QueueChangedHandler(object sender, NotifyCollectionChangedEventArgs e) + { + Series[1].Values.Add(new DateTimePoint(DateTime.Now, Queue.Count)); } private void InitCharts() @@ -203,6 +230,8 @@ namespace CBSVisualizer.Modules.Queue.ViewModels private void AtomicUpdateCredit(double increment, double limit) { Interlocked.Exchange(ref currentCredit, Math.Min(currentCredit + increment, limit)); + + Series[0].Values.Add(new DateTimePoint(DateTime.Now, currentCredit)); } private void RegisterPacketHandler() @@ -215,9 +244,6 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { // Add packet. Queue.Add(packet); - - // Update chart value. - Series[1].Values.Add(new DateTimePoint(DateTime.Now, Queue.Count)); } } }); diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml index 5c77652..1437a81 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml @@ -1,6 +1,7 @@ <UserControl x:Class="CBSVisualizer.Modules.Queue.Views.Queue" 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:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" @@ -10,18 +11,33 @@ xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="False" > <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="Auto"/> + <RowDefinition Height="*"/> + </Grid.RowDefinitions> <Grid.ColumnDefinitions> - <ColumnDefinition Width="0.5*"/> - <ColumnDefinition Width="0.5*"/> - <ColumnDefinition Width="0.5*"/> - <ColumnDefinition Width="0.5*"/> - <ColumnDefinition Width="2*"/> + <ColumnDefinition Width="*"/> + <ColumnDefinition Width="*"/> + <ColumnDefinition Width="*"/> + <ColumnDefinition Width="*"/> + <ColumnDefinition Width="3*"/> </Grid.ColumnDefinitions> - <TextBlock Text="{Binding Priority}" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center"/> - <TextBlock Text="{Binding Queue.Count}" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center"/> - <TextBox x:Name="CreditRateTextBox" Text="{Binding IdleSlope}" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center"/> - <ComboBox x:Name="CreditBehaviourBox" SelectedItem="{Binding SelectedCreditBehaviour}" Grid.Column="3" VerticalAlignment="Center" HorizontalAlignment="Center"/> - <lvc:CartesianChart Series="{Binding Series}" LegendLocation="Right" Grid.Column="4"> + <TextBlock Text="{Binding PrioLabel}" Grid.Column="0" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center"/> + <TextBlock Text="{Binding Priority}" Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center"/> + + <TextBlock Text="{Binding PacketLabel}" Grid.Column="1" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center"/> + <TextBlock Text="{Binding Queue.Count}" Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center"/> + + <TextBox materialDesign:HintAssist.Hint="Idle Slope [byte/s]" + Style="{StaticResource MaterialDesignFloatingHintTextBox}" + x:Name="CreditRateTextBox" Text="{Binding IdleSlope}" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center" TextAlignment="Center" Grid.RowSpan="2"/> + + <ComboBox Style="{StaticResource MaterialDesignFloatingHintComboBox}" + materialDesign:TextFieldAssist.UnderlineBrush="{DynamicResource SecondaryAccentBrush}" + materialDesign:HintAssist.Hint="Credit Behaviour" + x:Name="CreditBehaviourBox" SelectedItem="{Binding SelectedCreditBehaviour}" Grid.Column="3" Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center"/> + + <lvc:CartesianChart Series="{Binding Series}" LegendLocation="Right" Grid.Column="4" Grid.RowSpan="2"> <lvc:CartesianChart.AxisX> <lvc:Axis Title="Time" LabelFormatter="{Binding XFormatter}" /> </lvc:CartesianChart.AxisX> diff --git a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj index e681e4a..3cd4a74 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj @@ -5,7 +5,10 @@ <AssemblyName>CBSVisualizer.Modules.SettingsDialog</AssemblyName> </PropertyGroup> <ItemGroup> + <PackageReference Include="log4net" Version="2.0.9" /> + <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> + <PackageReference Include="ShowMeTheXAML.MSBuild" Version="1.0.12" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> diff --git a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/CBSVisualizer.Services.SchedulingService.csproj b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/CBSVisualizer.Services.SchedulingService.csproj index ae5e714..20f292c 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.8" /> + <PackageReference Include="log4net" Version="2.0.9" /> <PackageReference Include="Prism.Core" Version="7.2.0.1422" /> </ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/CBSVisualizer.Services.SettingService.csproj b/CBSVisualizer/CBSVisualizer.Services.SettingsService/CBSVisualizer.Services.SettingService.csproj index e90b892..6ba72c0 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/CBSVisualizer.Services.SettingService.csproj +++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/CBSVisualizer.Services.SettingService.csproj @@ -7,6 +7,7 @@ </PropertyGroup> <ItemGroup> + <PackageReference Include="log4net" Version="2.0.9" /> <PackageReference Include="Ookii.Dialogs.Wpf" Version="1.1.0" /> <PackageReference Include="Prism.Core" Version="7.2.0.1422" /> </ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer/App.xaml b/CBSVisualizer/CBSVisualizer/App.xaml index 80fe455..55a77f6 100644 --- a/CBSVisualizer/CBSVisualizer/App.xaml +++ b/CBSVisualizer/CBSVisualizer/App.xaml @@ -2,7 +2,14 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CBSVisualizer" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:prism="http://prismlibrary.com/" > <Application.Resources> + <ResourceDictionary> + <ResourceDictionary.MergedDictionaries> + <materialDesign:BundledTheme BaseTheme="Light" PrimaryColor="Cyan" SecondaryColor="LightBlue" /> + <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" /> + </ResourceDictionary.MergedDictionaries> + </ResourceDictionary> </Application.Resources> </prism:PrismApplication> diff --git a/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj b/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj index 5e2cc6e..2252ea0 100644 --- a/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj +++ b/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj @@ -7,8 +7,10 @@ <AssemblyName>CBSVisualizer</AssemblyName> </PropertyGroup> <ItemGroup> - <PackageReference Include="log4net" Version="2.0.8" /> + <PackageReference Include="log4net" Version="2.0.9" /> + <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> <PackageReference Include="Prism.DryIoc" Version="7.2.0.1422" /> + <PackageReference Include="ShowMeTheXAML.MSBuild" Version="1.0.12" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Modules.Link\CBSVisualizer.Modules.Link.csproj" /> diff --git a/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml b/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml index 4be8a18..dccc3d8 100644 --- a/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml +++ b/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml @@ -4,7 +4,14 @@ xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True" xmlns:core="clr-namespace:CBSVisualizer.Core;assembly=CBSVisualizer.Core" - Title="{Binding Title}" MinHeight="433" Height="433" MinWidth="867" Width="867" > + Title="{Binding Title}" MinHeight="433" Height="433" MinWidth="867" Width="867" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + TextElement.Foreground="{DynamicResource MaterialDesignBody}" + Background="{DynamicResource MaterialDesignPaper}" + TextElement.FontWeight="Medium" + TextElement.FontSize="14" + FontFamily="{materialDesign:MaterialDesignFont}" + > <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> -- GitLab From a85c65b3decafb71ed3d334f953ae473a0f0d087 Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Mon, 7 Sep 2020 23:14:28 +0200 Subject: [PATCH 04/17] Apply some visual changes. --- .../CBSVisualizer.Modules.Link.csproj | 1 - .../Views/Link.xaml | 122 ++++++++++++++---- .../CBSVisualizer.Modules.MenuBar.csproj | 1 - .../CBSVisualizer.Modules.QueueGroup.csproj | 1 - .../CBSVisualizer.Modules.Queue.csproj | 1 - ...BSVisualizer.Modules.SettingsDialog.csproj | 1 - .../Views/SettingsDialog.xaml | 8 +- CBSVisualizer/CBSVisualizer/App.xaml | 2 +- .../CBSVisualizer/CBSVisualizer.csproj | 1 - .../CBSVisualizer/Views/MainWindow.xaml | 6 +- 10 files changed, 110 insertions(+), 34 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj b/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj index 58eb0a9..0dc7e0a 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj @@ -9,7 +9,6 @@ <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> <PackageReference Include="ParallelExtensionsExtras" Version="1.2.0" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> - <PackageReference Include="ShowMeTheXAML.MSBuild" Version="1.0.12" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Common\CBSVisualizer.Common.csproj" /> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/Views/Link.xaml b/CBSVisualizer/CBSVisualizer.Modules.Link/Views/Link.xaml index 055371c..04d16ec 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/Views/Link.xaml +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/Views/Link.xaml @@ -2,36 +2,112 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CBSVisualizer.Modules.Link.Views" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:externals="clr-namespace:CBSVisualizer.Modules.Link.Externals" - xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - mc:Ignorable="d" + mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" xmlns:prism="http://prismlibrary.com/" - prism:ViewModelLocator.AutoWireViewModel="True" > + prism:ViewModelLocator.AutoWireViewModel="True"> <Grid> <Grid.Resources> - <externals:BoolToImageConverter x:Key="BoolToImageConv"/> + <externals:BoolToImageConverter x:Key="BoolToImageConv" /> </Grid.Resources> <Grid.RowDefinitions> - <RowDefinition Height="Auto"/> - <RowDefinition Height="*"/> - <RowDefinition Height="*"/> - <RowDefinition Height="*"/> - <RowDefinition Height="*"/> - <RowDefinition Height="*"/> - <RowDefinition Height="*"/> - <RowDefinition Height="*"/> - <RowDefinition Height="*"/> + <RowDefinition Height="Auto" /> + <RowDefinition Height="*" /> + <RowDefinition Height="*" /> + <RowDefinition Height="*" /> + <RowDefinition Height="*" /> + <RowDefinition Height="*" /> + <RowDefinition Height="*" /> + <RowDefinition Height="*" /> + <RowDefinition Height="*" /> </Grid.RowDefinitions> - <TextBlock Text="Gate Status" Grid.Row="0" TextAlignment="Center"/> - <Image Grid.Row="1" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[7].Value, Converter={StaticResource BoolToImageConv}}"/> - <Image Grid.Row="2" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[6].Value, Converter={StaticResource BoolToImageConv}}"/> - <Image Grid.Row="3" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[5].Value, Converter={StaticResource BoolToImageConv}}"/> - <Image Grid.Row="4" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[4].Value, Converter={StaticResource BoolToImageConv}}"/> - <Image Grid.Row="5" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[3].Value, Converter={StaticResource BoolToImageConv}}"/> - <Image Grid.Row="6" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[2].Value, Converter={StaticResource BoolToImageConv}}"/> - <Image Grid.Row="7" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[1].Value, Converter={StaticResource BoolToImageConv}}"/> - <Image Grid.Row="8" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[0].Value, Converter={StaticResource BoolToImageConv}}"/> + <TextBlock Text="Gate Status" Grid.Row="0" TextAlignment="Center" /> + <!-- + <Image Grid.Row="1" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[7].Value, Converter={StaticResource BoolToImageConv}}" /> + <Image Grid.Row="2" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[6].Value, Converter={StaticResource BoolToImageConv}}" /> + <Image Grid.Row="3" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[5].Value, Converter={StaticResource BoolToImageConv}}" /> + <Image Grid.Row="4" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[4].Value, Converter={StaticResource BoolToImageConv}}" /> + <Image Grid.Row="5" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[3].Value, Converter={StaticResource BoolToImageConv}}" /> + <Image Grid.Row="6" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[2].Value, Converter={StaticResource BoolToImageConv}}" /> + <Image Grid.Row="7" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[1].Value, Converter={StaticResource BoolToImageConv}}" /> + <Image Grid.Row="8" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[0].Value, Converter={StaticResource BoolToImageConv}}" /> + --> + + <ToggleButton Style="{StaticResource MaterialDesignActionToggleButton}" ToolTip="Gate Status" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" + IsChecked="{Binding GateStatusDictionary[7].Value, Mode=OneWay}"> + <ToggleButton.Content> + <materialDesign:PackIcon Kind="Gate" Foreground="Red"/> + </ToggleButton.Content> + <materialDesign:ToggleButtonAssist.OnContent> + <materialDesign:PackIcon Kind="GateOpen" Foreground="Green"/> + </materialDesign:ToggleButtonAssist.OnContent> + </ToggleButton> + <ToggleButton Style="{StaticResource MaterialDesignActionToggleButton}" ToolTip="MaterialDesignActionLightToggleButton" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" + IsChecked="{Binding GateStatusDictionary[6].Value, Mode=OneWay}"> + <ToggleButton.Content> + <materialDesign:PackIcon Kind="Gate" Foreground="Red"/> + </ToggleButton.Content> + <materialDesign:ToggleButtonAssist.OnContent> + <materialDesign:PackIcon Kind="GateOpen" Foreground="Green"/> + </materialDesign:ToggleButtonAssist.OnContent> + </ToggleButton> + <ToggleButton Style="{StaticResource MaterialDesignActionToggleButton}" ToolTip="MaterialDesignActionLightToggleButton" Grid.Row="3" HorizontalAlignment="Center" VerticalAlignment="Center" + IsChecked="{Binding GateStatusDictionary[5].Value, Mode=OneWay}"> + <ToggleButton.Content> + <materialDesign:PackIcon Kind="Gate" Foreground="Red"/> + </ToggleButton.Content> + <materialDesign:ToggleButtonAssist.OnContent> + <materialDesign:PackIcon Kind="GateOpen" Foreground="Green"/> + </materialDesign:ToggleButtonAssist.OnContent> + </ToggleButton> + <ToggleButton Style="{StaticResource MaterialDesignActionToggleButton}" ToolTip="MaterialDesignActionLightToggleButton" Grid.Row="4" HorizontalAlignment="Center" VerticalAlignment="Center" + IsChecked="{Binding GateStatusDictionary[4].Value, Mode=OneWay}"> + <ToggleButton.Content> + <materialDesign:PackIcon Kind="Gate" Foreground="Red"/> + </ToggleButton.Content> + <materialDesign:ToggleButtonAssist.OnContent> + <materialDesign:PackIcon Kind="GateOpen" Foreground="Green"/> + </materialDesign:ToggleButtonAssist.OnContent> + </ToggleButton> + <ToggleButton Style="{StaticResource MaterialDesignActionToggleButton}" ToolTip="MaterialDesignActionLightToggleButton" Grid.Row="5" HorizontalAlignment="Center" VerticalAlignment="Center" + IsChecked="{Binding GateStatusDictionary[3].Value, Mode=OneWay}"> + <ToggleButton.Content> + <materialDesign:PackIcon Kind="Gate" Foreground="Red"/> + </ToggleButton.Content> + <materialDesign:ToggleButtonAssist.OnContent> + <materialDesign:PackIcon Kind="GateOpen" Foreground="Green"/> + </materialDesign:ToggleButtonAssist.OnContent> + </ToggleButton> + <ToggleButton Style="{StaticResource MaterialDesignActionToggleButton}" ToolTip="MaterialDesignActionLightToggleButton" Grid.Row="6" HorizontalAlignment="Center" VerticalAlignment="Center" + IsChecked="{Binding GateStatusDictionary[2].Value, Mode=OneWay}"> + <ToggleButton.Content> + <materialDesign:PackIcon Kind="Gate" Foreground="Red"/> + </ToggleButton.Content> + <materialDesign:ToggleButtonAssist.OnContent> + <materialDesign:PackIcon Kind="GateOpen" Foreground="Green"/> + </materialDesign:ToggleButtonAssist.OnContent> + </ToggleButton> + <ToggleButton Style="{StaticResource MaterialDesignActionToggleButton}" ToolTip="MaterialDesignActionLightToggleButton" Grid.Row="7" HorizontalAlignment="Center" VerticalAlignment="Center" + IsChecked="{Binding GateStatusDictionary[1].Value, Mode=OneWay}"> + <ToggleButton.Content> + <materialDesign:PackIcon Kind="Gate" Foreground="Red"/> + </ToggleButton.Content> + <materialDesign:ToggleButtonAssist.OnContent> + <materialDesign:PackIcon Kind="GateOpen" Foreground="Green"/> + </materialDesign:ToggleButtonAssist.OnContent> + </ToggleButton> + <ToggleButton Style="{StaticResource MaterialDesignActionToggleButton}" ToolTip="MaterialDesignActionLightToggleButton" Grid.Row="8" HorizontalAlignment="Center" VerticalAlignment="Center" + IsChecked="{Binding GateStatusDictionary[0].Value, Mode=OneWay}"> + <ToggleButton.Content> + <materialDesign:PackIcon Kind="Gate" Foreground="Red"/> + </ToggleButton.Content> + <materialDesign:ToggleButtonAssist.OnContent> + <materialDesign:PackIcon Kind="GateOpen" Foreground="Green"/> + </materialDesign:ToggleButtonAssist.OnContent> + </ToggleButton> </Grid> -</UserControl> +</UserControl> \ 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 7ea0227..d71e29b 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj @@ -8,7 +8,6 @@ <PackageReference Include="log4net" Version="2.0.9" /> <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> - <PackageReference Include="ShowMeTheXAML.MSBuild" Version="1.0.12" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj index 45b7765..5dd618b 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj @@ -8,7 +8,6 @@ <PackageReference Include="log4net" Version="2.0.9" /> <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> - <PackageReference Include="ShowMeTheXAML.MSBuild" Version="1.0.12" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj b/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj index 18306af..754e306 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj @@ -10,7 +10,6 @@ <PackageReference Include="log4net" Version="2.0.9" /> <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> - <PackageReference Include="ShowMeTheXAML.MSBuild" Version="1.0.12" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> diff --git a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj index 3cd4a74..40a784e 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj @@ -8,7 +8,6 @@ <PackageReference Include="log4net" Version="2.0.9" /> <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> <PackageReference Include="Prism.Wpf" Version="7.2.0.1422" /> - <PackageReference Include="ShowMeTheXAML.MSBuild" Version="1.0.12" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> diff --git a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/Views/SettingsDialog.xaml b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/Views/SettingsDialog.xaml index 6a5d5cc..6488678 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/Views/SettingsDialog.xaml +++ b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/Views/SettingsDialog.xaml @@ -8,7 +8,13 @@ mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" xmlns:prism="http://prismlibrary.com/" - prism:ViewModelLocator.AutoWireViewModel="True" > + prism:ViewModelLocator.AutoWireViewModel="True" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + TextElement.Foreground="{DynamicResource MaterialDesignBody}" + Background="{DynamicResource MaterialDesignPaper}" + TextElement.FontWeight="Medium" + TextElement.FontSize="14" + FontFamily="{materialDesign:MaterialDesignFont}"> <prism:Dialog.WindowStyle> <Style TargetType="Window"> diff --git a/CBSVisualizer/CBSVisualizer/App.xaml b/CBSVisualizer/CBSVisualizer/App.xaml index 55a77f6..bc2cf44 100644 --- a/CBSVisualizer/CBSVisualizer/App.xaml +++ b/CBSVisualizer/CBSVisualizer/App.xaml @@ -7,7 +7,7 @@ <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> - <materialDesign:BundledTheme BaseTheme="Light" PrimaryColor="Cyan" SecondaryColor="LightBlue" /> + <materialDesign:BundledTheme BaseTheme="Light" PrimaryColor="Amber" SecondaryColor="LightBlue" /> <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> diff --git a/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj b/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj index 2252ea0..0ecc3d1 100644 --- a/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj +++ b/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj @@ -10,7 +10,6 @@ <PackageReference Include="log4net" Version="2.0.9" /> <PackageReference Include="MaterialDesignThemes" Version="3.1.3" /> <PackageReference Include="Prism.DryIoc" Version="7.2.0.1422" /> - <PackageReference Include="ShowMeTheXAML.MSBuild" Version="1.0.12" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Modules.Link\CBSVisualizer.Modules.Link.csproj" /> diff --git a/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml b/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml index dccc3d8..1d12452 100644 --- a/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml +++ b/CBSVisualizer/CBSVisualizer/Views/MainWindow.xaml @@ -18,11 +18,11 @@ <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> - <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> + <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.MenuBarRegion}" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2"/> - <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.QueueGroupRegion}" Grid.Column="0" Grid.Row="1"/> - <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.LinkRegion}" Grid.Column="1" Grid.Row="1" Margin="0, 0, 5, 0"/> + <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.QueueGroupRegion}" Grid.Column="1" Grid.Row="1"/> + <ContentControl prism:RegionManager.RegionName="{x:Static core:RegionNames.LinkRegion}" Grid.Column="0" Grid.Row="1" Margin="30, 0, 0, 0"/> </Grid> </Window> -- GitLab From e5c6a85cdc8e8726fe789d2b35ab66b256e9011c Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Thu, 10 Sep 2020 18:56:22 +0200 Subject: [PATCH 05/17] Remove some blank lines. --- .../CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs index 21f45d7..cd9ef0d 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs @@ -40,7 +40,6 @@ namespace CBSVisualizer.Modules.Queue.ViewModels SetProperty(ref currentCredit, value); } } - public enum CreditBehaviour { // This is selected when there should be no credit-based shaper for this queue. @@ -75,8 +74,6 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public string PacketLabel { get; private set; } - - public ObservableCollection<PriorityPacket> Queue { get; private set; } = new ObservableCollection<PriorityPacket>(); /// <summary> -- GitLab From 1b858813df7bbc348b46c073c490276e55c140fb Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Thu, 10 Sep 2020 19:21:14 +0200 Subject: [PATCH 06/17] Add UniqueId to the PriorityPacket. --- .../Models/PriorityPacket.cs | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Models/PriorityPacket.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Models/PriorityPacket.cs index 00be892..475ab8d 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Models/PriorityPacket.cs +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Models/PriorityPacket.cs @@ -13,25 +13,31 @@ namespace CBSVisualizer.Messaging private static readonly int PREEMPTION_TRAILER_SIZE_BYTES = 12; - public static PriorityPacket NoPacket { get; } = new PriorityPacket(0, 0); - /** - * The priority of the packet. - */ + public static PriorityPacket NoPacket { get; } = new PriorityPacket(0, 0) { UniqueId = -1 }; + + /// <summary> + /// The unique ID of the packet. + /// </summary> + public long UniqueId { get; private set; } + + /// <summary> + /// The priority of the packet. + /// </summary> public int Priority { get; private set; } - /** - * The header size of the packet. - */ + /// <summary> + /// The header size of the packet. + /// </summary> public int HeaderBytes { get; private set; } - /* - * The amount of payload bytes. - */ + /// <summary> + /// The amount of payload bytes. + /// </summary> public int PayloadBytes { get; private set; } - /** - * The amount of trailer bytes. - */ + /// <summary> + /// The amount of trailer bytes. + /// </summary> public int TrailerBytes { get; private set; } public int Size @@ -42,6 +48,8 @@ namespace CBSVisualizer.Messaging } } + private static long currentId = 0; + /// <summary> /// Constructs a new PriorityPacket. /// </summary> @@ -51,6 +59,7 @@ namespace CBSVisualizer.Messaging /// <param name="trailerBytes"></param> public PriorityPacket(int prio, int headerBytes, int payloadBytes, int trailerBytes) { + UniqueId = currentId++; Priority = prio; HeaderBytes = headerBytes; PayloadBytes = payloadBytes; @@ -63,16 +72,13 @@ namespace CBSVisualizer.Messaging /// <param name="prio"></param> /// <param name="payloadBytes"></param> public PriorityPacket(int prio, int payloadBytes) + : this(prio, payloadBytes, PREEMPTION_HEADER_SIZE_BYTES, PREEMPTION_TRAILER_SIZE_BYTES) { - Priority = prio; - PayloadBytes = payloadBytes; - HeaderBytes = PREEMPTION_HEADER_SIZE_BYTES; - TrailerBytes = PREEMPTION_TRAILER_SIZE_BYTES; } public override string ToString() { - return $"Priority: {Priority}, Header Size: {HeaderBytes}, Payload Bytes: {PayloadBytes}, Trailer Bytes: {TrailerBytes}"; + return $"ID: {UniqueId} Priority: {Priority}, Header Size: {HeaderBytes}, Payload Bytes: {PayloadBytes}, Trailer Bytes: {TrailerBytes}"; } } } -- GitLab From c94b97b0a82682b1e0f9fb64c9d92704c3fc7272 Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Thu, 10 Sep 2020 21:45:53 +0200 Subject: [PATCH 07/17] Refactor a bit, move some interfaces + introduce packetService. --- .../CBSVisualizer.Modules.Link.csproj | 13 -- .../Externals/BoolToImageConverter.cs | 30 ----- .../Properties/Resources.Designer.cs | 83 ------------ .../Properties/Resources.resx | 127 ------------------ .../Resources/greendot.png | Bin 896 -> 0 bytes .../Resources/reddot.png | Bin 1074 -> 0 bytes .../ViewModels/LinkViewModel.cs | 12 +- .../Views/Link.xaml | 14 -- .../CBSVisualizer.Modules.MenuBar.csproj | 1 + .../MenuBarViewModel.LoadGeneration.cs | 16 +-- .../ViewModels/MenuBarViewModel.cs | 15 +-- .../Views/QueueGroup.xaml.cs | 6 +- .../CBSVisualizer.Modules.Queue.csproj | 1 + .../QueueViewModel.LinkCallbacks.cs | 26 +++- .../ViewModels/QueueViewModel.cs | 71 +++++----- .../Views/Queue.xaml | 6 +- .../Views/Queue.xaml.cs | 14 +- .../ViewModels/SettingsDialogViewModel.cs | 8 +- ...BSVisualizer.Services.PacketService.csproj | 11 ++ .../Implementation/RandomPacketService.cs | 37 +++++ .../Interface/IPacketService.cs | 22 +++ .../Implementation/RandomSchedulingService.cs | 3 +- .../Interface/ISchedulingService.cs | 8 +- .../SettingService.cs | 2 +- CBSVisualizer/CBSVisualizer.sln | 7 + CBSVisualizer/CBSVisualizer/App.xaml.cs | 7 +- .../CBSVisualizer/CBSVisualizer.csproj | 1 + 27 files changed, 185 insertions(+), 356 deletions(-) delete mode 100644 CBSVisualizer/CBSVisualizer.Modules.Link/Externals/BoolToImageConverter.cs delete mode 100644 CBSVisualizer/CBSVisualizer.Modules.Link/Properties/Resources.Designer.cs delete mode 100644 CBSVisualizer/CBSVisualizer.Modules.Link/Properties/Resources.resx delete mode 100644 CBSVisualizer/CBSVisualizer.Modules.Link/Resources/greendot.png delete mode 100644 CBSVisualizer/CBSVisualizer.Modules.Link/Resources/reddot.png create mode 100644 CBSVisualizer/CBSVisualizer.Services.PacketService/CBSVisualizer.Services.PacketService.csproj create mode 100644 CBSVisualizer/CBSVisualizer.Services.PacketService/Implementation/RandomPacketService.cs create mode 100644 CBSVisualizer/CBSVisualizer.Services.PacketService/Interface/IPacketService.cs rename CBSVisualizer/CBSVisualizer.Services.SettingsService/{Service => Implementation}/SettingService.cs (96%) diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj b/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj index 0dc7e0a..88a26a2 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/CBSVisualizer.Modules.Link.csproj @@ -16,17 +16,4 @@ <ProjectReference Include="..\CBSVisualizer.MessagingCore\CBSVisualizer.Messaging.csproj" /> <ProjectReference Include="..\CBSVisualizer.Services.SchedulingService\CBSVisualizer.Services.SchedulingService.csproj" /> </ItemGroup> - <ItemGroup> - <Compile Update="Properties\Resources.Designer.cs"> - <DesignTime>True</DesignTime> - <AutoGen>True</AutoGen> - <DependentUpon>Resources.resx</DependentUpon> - </Compile> - </ItemGroup> - <ItemGroup> - <EmbeddedResource Update="Properties\Resources.resx"> - <Generator>ResXFileCodeGenerator</Generator> - <LastGenOutput>Resources.Designer.cs</LastGenOutput> - </EmbeddedResource> - </ItemGroup> </Project> \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/Externals/BoolToImageConverter.cs b/CBSVisualizer/CBSVisualizer.Modules.Link/Externals/BoolToImageConverter.cs deleted file mode 100644 index 0e34bdd..0000000 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/Externals/BoolToImageConverter.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Resources; -using System.Text; -using System.Windows.Data; -using System.Windows.Media.Imaging; - -namespace CBSVisualizer.Modules.Link.Externals -{ - public class BoolToImageConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - bool val = (bool)value; - if (val) - { - return Properties.Resources.GreenDot; - } else - { - return Properties.Resources.RedDot; - } - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/Properties/Resources.Designer.cs b/CBSVisualizer/CBSVisualizer.Modules.Link/Properties/Resources.Designer.cs deleted file mode 100644 index 7ca5c05..0000000 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/Properties/Resources.Designer.cs +++ /dev/null @@ -1,83 +0,0 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// </auto-generated> -//------------------------------------------------------------------------------ - -namespace CBSVisualizer.Modules.Link.Properties { - using System; - - - /// <summary> - /// A strongly-typed resource class, for looking up localized strings, etc. - /// </summary> - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// <summary> - /// Returns the cached ResourceManager instance used by this class. - /// </summary> - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CBSVisualizer.Modules.Link.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// <summary> - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// </summary> - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// <summary> - /// Looks up a localized resource of type System.Byte[]. - /// </summary> - internal static byte[] GreenDot { - get { - object obj = ResourceManager.GetObject("GreenDot", resourceCulture); - return ((byte[])(obj)); - } - } - - /// <summary> - /// Looks up a localized resource of type System.Byte[]. - /// </summary> - internal static byte[] RedDot { - get { - object obj = ResourceManager.GetObject("RedDot", resourceCulture); - return ((byte[])(obj)); - } - } - } -} diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/Properties/Resources.resx b/CBSVisualizer/CBSVisualizer.Modules.Link/Properties/Resources.resx deleted file mode 100644 index 49e1ad3..0000000 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/Properties/Resources.resx +++ /dev/null @@ -1,127 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<root> - <!-- - Microsoft ResX Schema - - Version 2.0 - - The primary goals of this format is to allow a simple XML format - that is mostly human readable. The generation and parsing of the - various data types are done through the TypeConverter classes - associated with the data types. - - Example: - - ... ado.net/XML headers & schema ... - <resheader name="resmimetype">text/microsoft-resx</resheader> - <resheader name="version">2.0</resheader> - <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> - <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> - <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> - <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> - <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> - <value>[base64 mime encoded serialized .NET Framework object]</value> - </data> - <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> - <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> - <comment>This is a comment</comment> - </data> - - There are any number of "resheader" rows that contain simple - name/value pairs. - - Each data row contains a name, and value. The row also contains a - type or mimetype. Type corresponds to a .NET class that support - text/value conversion through the TypeConverter architecture. - Classes that don't support this are serialized and stored with the - mimetype set. - - The mimetype is used for serialized objects, and tells the - ResXResourceReader how to depersist the object. This is currently not - extensible. For a given mimetype the value must be set accordingly: - - Note - application/x-microsoft.net.object.binary.base64 is the format - that the ResXResourceWriter will generate, however the reader can - read any of the formats listed below. - - mimetype: application/x-microsoft.net.object.binary.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.soap.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Soap.SoapFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.bytearray.base64 - value : The object must be serialized into a byte array - : using a System.ComponentModel.TypeConverter - : and then encoded with base64 encoding. - --> - <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> - <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> - <xsd:element name="root" msdata:IsDataSet="true"> - <xsd:complexType> - <xsd:choice maxOccurs="unbounded"> - <xsd:element name="metadata"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" /> - </xsd:sequence> - <xsd:attribute name="name" use="required" type="xsd:string" /> - <xsd:attribute name="type" type="xsd:string" /> - <xsd:attribute name="mimetype" type="xsd:string" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="assembly"> - <xsd:complexType> - <xsd:attribute name="alias" type="xsd:string" /> - <xsd:attribute name="name" type="xsd:string" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="data"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> - <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> - <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="resheader"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" /> - </xsd:complexType> - </xsd:element> - </xsd:choice> - </xsd:complexType> - </xsd:element> - </xsd:schema> - <resheader name="resmimetype"> - <value>text/microsoft-resx</value> - </resheader> - <resheader name="version"> - <value>2.0</value> - </resheader> - <resheader name="reader"> - <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <resheader name="writer"> - <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> - <data name="GreenDot" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\greendot.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </data> - <data name="RedDot" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\reddot.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </data> -</root> \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/Resources/greendot.png b/CBSVisualizer/CBSVisualizer.Modules.Link/Resources/greendot.png deleted file mode 100644 index 507dccf03172b0f3c7615fcd5cc7f5a69237bb53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 896 zcmeAS@N?(olHy`uVBq!ia0y~yVCZLHV3@|i#K6Fial>ai0|NtNage(c!@6@aFBupZ zSkfJR9T^xl_H+M9WMyDr;4JWnEM{QfI}E~%$MaXDFfcHSdb&7<RK&f#6PS0~frsJZ zlJJ+6w+?T6{xULzF<YXkmt~tvk>#Z`{(n~9RbR)V{Nec~9eK8w$KS3O4C<Z|wd9J@ zQZdb~9xGkFbc3=c5)j(>-}&wH`SIKR?|*y${r+wB3YE3uxpADYuE%Nzyjbl}RJ)aH z&Njs}w=zYQZLiN<JMmh{@?6`qQ5jo{Ze2T@vneckd2a2QWtoa|wv`&p{v6BJm$mk= zss9C~px$Nim0vwiEWKs+I%LgdtM<!#H4|LbAD&!sZP}U?POoc17XK<;nmu=FR>+=R zF>8y1d$q35SW(KlD)6S)<}K@-O;<(ccU`->!i{xx-}PN;S2e2N9*hcKCbjgP!=vc7 zR`Hcj6M8>=Q}pp(mFv0tp{IwI+v$T<dddEC)*d-@kZFs|noV=o-bu=Tx;Tn2EcIMi zRipVAMP2sQ7U|tr>U7y(e_izL)J>(OVk_rH$u++h+mw6`9Au%_KOQdVpT@s7(lQzr zj(gWW)jl?n@7=u3cmnjw?WntT5;LwIyj#2t7V@_iKkYuYX3pAOefOV&;^B&)u6!)q zuD91e8Px1uvA1ZOhwP=IJzd4yE^+T!epRV7<n-YWzmvWnzo{g;;Aur|=#O(p&P+=< zpZca#U2&y>?(yvCOL;EmrX?)iQ~N<hMRd*6ily%y{^Z0;>QukgRDWoCkSlEN*E_qU zBF<I`-#1#v9JcL}%i680eIv@|pWbxGZdvK0`E6SJWQ)_YORjOQjt_6WcI)SXWouS= zWWV)E*nBPM<DDvwzY?>n&tE-z&Gy{{-~FFBqq1E#@LjigsB)*xLiG2Y=*e5%a?kFX z%c#4>ZS9$=c~^V4xLrPLWgmPyvv=8y(lRO2tGmJvT$6tpSH3p4u}EQIuFBf>dxx4o t*|1#Ol~BCz^oCmE5+_{M<>SZe3m!2tt#Z7<&cMLH;OXk;vd$@?2>?0uups~d diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/Resources/reddot.png b/CBSVisualizer/CBSVisualizer.Modules.Link/Resources/reddot.png deleted file mode 100644 index 885ff703a6a15f21a203b56b3969027e813427a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1074 zcmeAS@N?(olHy`uVBq!ia0y~yVCZLHV3@|i#K6Fial>ai0|NtNage(c!@6@aFBupZ zSkfJR9T^xl_H+M9WMyDr;4JWnEM{QfI}E~%$MaXDFfcG5_jGX#sfc?!(J@cPk%#&7 z1ewqO=Rf83V|Hd?6V|_$<*9paLx6kr@}s{#CYBWFs>XP8UJp97bqeXsw^94+|5dsF z*=pytb;ZHHAFig$t}mLZePp`GjOcE&wPNve&+dpaN!nj=+=K1vqO0e+%z2YtbfdER zD(*}0U0+n1*0r7QL4<Bp%D#&4f#<F)QVcor`h4L6G2aEMc@{3^x>j)^GMD}0b*&;| zW3GA!>so!4d$i5XD(m9Jav|}uz_{*nyXWuN+<Ggj<VNh#tzSj1Et>pJH&1WbDlys5 zEQOV-s#{<5Jn#5@`owxyb{pR{0nSCbRlkgnim~np+jnD8!<ncrFVwqTH+imhJ-_va zs_6AqLc5nt3htK6(%<MOw=Pth%}Z&a*xvJXV$!M)qn;)$<0;F&c>2x$q?J4|tDSqc zo(<Ejn*7)6&DP%R(vH2`I<GHczj-}rt8L6`&o$fHvrRj%e&e{dX!(uuBW2P%!sg$| zW4``M_;&7tsI^J^G$uxUVfwu<!k{aAYZvR{9bv0cn5VX9Uwr<y{AizI%<AYj5{I_# zBA>Z0HrsLj_V?YGwm|H5$<lox_|4ZaUIgmA+N9mQF{}M^wmWXP)-*3EzWeI8g0*TJ zZ^^B@suFfvIWF6ge^Y$t-fe|z`8HlRi{2{sMdx?C;We{$p?cF!9oTy6XprQaYf%>- zze(R1D6}qA+ssR8;kBlD8K6+L+$#1ZpgT6GaIMxxZ>`L&VqflnqTuA3tqa`kgL48K zvY&SAa(S%Vx?s6ID8}m6vdVstDXf=N-6~dcO!&ytsUcURE*O3nGZznz$aYk}8yXYs zpSzY-w#>UQ%l7G3v69<!kF>^?T#33c@w>ow(@P=Qj>}hdudaHzdh3Gb(xbL-w_Mw` z;PlobyzLeN*^a_1I<C)u?6a1Y*D!w1Z;j(wu@{t#k4Cc>?6}6d*4TYdK96!%?1iB8 zqqEx#S6pLVdrkkI;iST?dKm}hKE6H3v-YdF)E1{2&&HQq?VPpWcf^M{uM~4+jO+d{ n=)U6`b0N8zOV-ZrAH#yZV$*}>{5NJ`U|{fc^>bP0l+XkKzBuiw diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs index 1b96afe..52ff6b8 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs @@ -2,8 +2,8 @@ using CBSVisualizer.Core.Mvvm; using CBSVisualizer.Messaging; using CBSVisualizer.Messaging.Events; -using CBSVisualizer.Services.SchedulingService; -using CBSVisualizer.Services.SettingsService.Service; +using CBSVisualizer.Services.SchedulingService.Interface; +using CBSVisualizer.Services.SettingsService.Implementation; using log4net; using Prism.Events; using Prism.Regions; @@ -72,6 +72,14 @@ namespace CBSVisualizer.Modules.Link.ViewModels return; } + // Call Initialize() on each ILinkCallback. + log.Info("Initializing all links"); + foreach (var callback in linkCallbacks.Values) + { + callback.Initialize(); + } + + // Start scheduling. scheduler.StartScheduling(); log.Info("Simulation started."); diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/Views/Link.xaml b/CBSVisualizer/CBSVisualizer.Modules.Link/Views/Link.xaml index 04d16ec..1c59871 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/Views/Link.xaml +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/Views/Link.xaml @@ -3,7 +3,6 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CBSVisualizer.Modules.Link.Views" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" - xmlns:externals="clr-namespace:CBSVisualizer.Modules.Link.Externals" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" @@ -11,9 +10,6 @@ xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True"> <Grid> - <Grid.Resources> - <externals:BoolToImageConverter x:Key="BoolToImageConv" /> - </Grid.Resources> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> @@ -26,16 +22,6 @@ <RowDefinition Height="*" /> </Grid.RowDefinitions> <TextBlock Text="Gate Status" Grid.Row="0" TextAlignment="Center" /> - <!-- - <Image Grid.Row="1" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[7].Value, Converter={StaticResource BoolToImageConv}}" /> - <Image Grid.Row="2" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[6].Value, Converter={StaticResource BoolToImageConv}}" /> - <Image Grid.Row="3" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[5].Value, Converter={StaticResource BoolToImageConv}}" /> - <Image Grid.Row="4" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[4].Value, Converter={StaticResource BoolToImageConv}}" /> - <Image Grid.Row="5" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[3].Value, Converter={StaticResource BoolToImageConv}}" /> - <Image Grid.Row="6" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[2].Value, Converter={StaticResource BoolToImageConv}}" /> - <Image Grid.Row="7" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[1].Value, Converter={StaticResource BoolToImageConv}}" /> - <Image Grid.Row="8" HorizontalAlignment="Center" Source="{Binding GateStatusDictionary[0].Value, Converter={StaticResource BoolToImageConv}}" /> - --> <ToggleButton Style="{StaticResource MaterialDesignActionToggleButton}" ToolTip="Gate Status" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" IsChecked="{Binding GateStatusDictionary[7].Value, Mode=OneWay}"> diff --git a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj index d71e29b..bd70497 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj @@ -12,6 +12,7 @@ <ItemGroup> <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" /> <ProjectReference Include="..\CBSVisualizer\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> </ItemGroup> diff --git a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs index 8e09473..4fb601d 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs @@ -2,10 +2,6 @@ using CBSVisualizer.Messaging.Events; using log4net; using Prism.Commands; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; @@ -33,14 +29,8 @@ namespace CBSVisualizer.Modules.MenuBar.ViewModels } } - private const int HEADER_BYTES = 100; - - private const int TRAILER_BYTES = 100; - private CancellationTokenSource tokenSource = new CancellationTokenSource(); - private readonly Random random = new Random(); - private bool CanStartLoadGeneration() { return !LoadGenerationInProgress; @@ -75,11 +65,7 @@ namespace CBSVisualizer.Modules.MenuBar.ViewModels private PriorityPacket GenerateRandomPacket() { - PriorityPacket ret = new PriorityPacket( - random.Next(0, 8), // Priority between 0 and 7 - HEADER_BYTES, - random.Next(2000), // Random value between 0 and 1999. - TRAILER_BYTES); + 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 eb68171..0187f30 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs @@ -1,16 +1,12 @@ using CBSVisualizer.Core.Mvvm; using CBSVisualizer.Messaging.Events; -using CBSVisualizer.Services.SettingsService.Service; +using CBSVisualizer.Services.PacketService.Interface; +using CBSVisualizer.Services.SettingsService.Implementation; using Prism.Commands; using Prism.Events; -using Prism.Mvvm; using Prism.Regions; using Prism.Services.Dialogs; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; + namespace CBSVisualizer.Modules.MenuBar.ViewModels { @@ -40,12 +36,15 @@ namespace CBSVisualizer.Modules.MenuBar.ViewModels private readonly SettingService settings; + private readonly IPacketService packetService; + - public MenuBarViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, IDialogService dialogService, SettingService settingService) + public MenuBarViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, IDialogService dialogService, SettingService settingService, IPacketService packetServ) : base(regionManager) { this.eventAggregator = eventAggregator; settings = settingService; + packetService = packetServ; StartSimulationCommand = new DelegateCommand(SignalSimulationStart, () => !SimulationRunning).ObservesProperty(() => SimulationRunning); StopSimulationCommand = new DelegateCommand(SignalSimulationStop).ObservesCanExecute(() => SimulationRunning); diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs index c23cc56..f917451 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/Views/QueueGroup.xaml.cs @@ -1,5 +1,7 @@ using CBSVisualizer.Modules.Queue.ViewModels; +using CBSVisualizer.Services.PacketService.Interface; using Prism.Events; +using Prism.Ioc; using Prism.Regions; using System; using System.Collections.Generic; @@ -23,13 +25,13 @@ namespace CBSVisualizer.Modules.Queue.QueueGroup.Views /// </summary> public partial class QueueGroup : UserControl { - public QueueGroup(IRegionManager regionManager, IEventAggregator eventAggregator) + public QueueGroup(IRegionManager regionManager, IEventAggregator eventAggregator, IPacketService packetService) { InitializeComponent(); for (int prio = 7; prio >= 0; prio--) { - Queue.Views.Queue newQueue = new Queue.Views.Queue(new QueueViewModel(regionManager, eventAggregator, prio)); + Queue.Views.Queue newQueue = new Queue.Views.Queue(new QueueViewModel(regionManager, eventAggregator, prio, packetService)); 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 754e306..2398fc6 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj @@ -14,6 +14,7 @@ <ItemGroup> <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\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> </ItemGroup> </Project> \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs index 5658c4b..37c7375 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs @@ -198,17 +198,35 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override async Task Initialize() { - await parent.StartCreditThread(parent.IdleSlope); + log.Info("Initialize"); + var shouldStartThread = false; + + lock (parent.queueLock) + { + shouldStartThread = parent.CurrentCredit < 0 || parent.Queue.Count > 0; + } + + if (shouldStartThread) + { + await parent.StartCreditThread(parent.IdleSlope); + } + } public override async Task GateClosed() { + log.Info("GateClosed"); + // Stop the credit growth thread. await parent.StopCreditThread(); + } public override Task GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) { + log.Info("GateOpened"); + + // Start the credit lock (parent.queueLock) { @@ -231,6 +249,9 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override Task PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) { + + log.Info("PacketPreempted"); + lock (parent.queueLock) { parent.Queue.Insert(0, new PriorityPacket(parent.Priority, leftoverBytes)); @@ -241,12 +262,15 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override async Task TransmissionCompleted() { + log.Info("TransmissionCompleted"); + await parent.StopCreditThread(); await parent.StartCreditThread(parent.IdleSlope); } public override async Task TransmissionStarted(double bytesPerSecondRate) { + log.Info("TransmissionStarted"); await parent.StopCreditThread(); await parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); } diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs index cd9ef0d..932e9d9 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs @@ -1,9 +1,12 @@ using CBSVisualizer.Core.Mvvm; using CBSVisualizer.Messaging; using CBSVisualizer.Messaging.Events; +using CBSVisualizer.Services.PacketService.Interface; using LiveCharts; using LiveCharts.Defaults; using LiveCharts.Wpf; +using log4net; +using Prism.Commands; using Prism.Events; using Prism.Regions; using System; @@ -17,8 +20,12 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { public partial class QueueViewModel : RegionViewModelBase { + private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private readonly IEventAggregator eventAggregator; + private readonly IPacketService packetService; + private readonly object queueLock = new object(); private CancellationTokenSource creditGrowthCancellationSource; @@ -83,10 +90,13 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public SeriesCollection Series { get; set; } - public QueueViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, int prio) : + public DelegateCommand GeneratePacketOnClick { get; private set; } + + public QueueViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, int prio, IPacketService packetProvider) : base(regionManager) { this.eventAggregator = eventAggregator; + packetService = packetProvider; Priority = prio; HandleLabels(); @@ -166,15 +176,6 @@ namespace CBSVisualizer.Modules.Queue.ViewModels private void RegisterSimulationStartStopHandler() { - eventAggregator.GetEvent<SimulationStartedEvent>().Subscribe(() => - { - if (SelectedCreditBehaviour != CreditBehaviour.NoCBS && Queue.Count >= 1) - { - creditUpdateTask = StartCreditThread(IdleSlope); - } - } - ); - eventAggregator.GetEvent<SimulationStoppedEvent>().Subscribe(async () => { if (SelectedCreditBehaviour != CreditBehaviour.NoCBS) @@ -187,6 +188,25 @@ namespace CBSVisualizer.Modules.Queue.ViewModels }); } + private async Task StartCreditThread(double bytesPerSecondSlope, double limit = double.PositiveInfinity) + { + log.Info($"Queue {Priority}: Credit Thread was started with {bytesPerSecondSlope} bytes/s slope."); + creditGrowthCancellationSource = new CancellationTokenSource(); + await Task.Run(async () => + { + // Refresh the credit. + while (!creditGrowthCancellationSource.Token.IsCancellationRequested && CurrentCredit < limit && Queue.Count > 0) + { + // Wait for the specified amount of time. + await Task.Delay(TimeSpan.FromSeconds(CREDIT_REFRESH_RATE_S), creditGrowthCancellationSource.Token); + + AtomicUpdateCredit(CREDIT_REFRESH_RATE_S * bytesPerSecondSlope, limit); + + Debug.WriteLine($"Queue {Priority}: Credit {CurrentCredit}"); + } + }, creditGrowthCancellationSource.Token); + } + private async Task StopCreditThread() { creditGrowthCancellationSource?.Cancel(); @@ -199,31 +219,14 @@ namespace CBSVisualizer.Modules.Queue.ViewModels } catch (TaskCanceledException) { - // Do nothing. + log.Info($"Queue {Priority}: Credit Thread was cancelled."); } + + log.Info($"Queue {Priority}: Credit Thread was stopped successfully."); creditUpdateTask = null; creditGrowthCancellationSource = null; } - private async Task StartCreditThread(double bytesPerSecondSlope, double limit = double.PositiveInfinity) - { - creditGrowthCancellationSource = new CancellationTokenSource(); - await Task.Run(async () => - { - // Refresh the credit. - while (!creditGrowthCancellationSource.Token.IsCancellationRequested && CurrentCredit < limit && Queue.Count > 0) - { - // Wait for the specified amount of time. - await Task.Delay(TimeSpan.FromSeconds(CREDIT_REFRESH_RATE_S), creditGrowthCancellationSource.Token); - - AtomicUpdateCredit(CREDIT_REFRESH_RATE_S * bytesPerSecondSlope, limit); - - Debug.WriteLine($"Queue {Priority}: Credit {CurrentCredit}"); - } - } - , creditGrowthCancellationSource.Token); - } - private void AtomicUpdateCredit(double increment, double limit) { Interlocked.Exchange(ref currentCredit, Math.Min(currentCredit + increment, limit)); @@ -244,6 +247,14 @@ namespace CBSVisualizer.Modules.Queue.ViewModels } } }); + + GeneratePacketOnClick = new DelegateCommand(() => + { + lock (queueLock) + { + Queue.Add(packetService.GeneratePacket(Priority)); + } + }); } } } \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml index 1437a81..13428af 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml @@ -26,7 +26,11 @@ <TextBlock Text="{Binding Priority}" Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center"/> <TextBlock Text="{Binding PacketLabel}" Grid.Column="1" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center"/> - <TextBlock Text="{Binding Queue.Count}" Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center"/> + <TextBlock Text="{Binding Queue.Count}" Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center"> + <TextBlock.InputBindings> + <MouseBinding MouseAction="RightClick" Command="{Binding GeneratePacketOnClick}"/> + </TextBlock.InputBindings> + </TextBlock> <TextBox materialDesign:HintAssist.Hint="Idle Slope [byte/s]" Style="{StaticResource MaterialDesignFloatingHintTextBox}" diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs index 7b92184..cbf853e 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs @@ -1,19 +1,7 @@ using CBSVisualizer.Modules.Queue.ViewModels; -using System; -using System.Collections.Generic; using System.Collections.ObjectModel; -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; + using static CBSVisualizer.Modules.Queue.ViewModels.QueueViewModel; namespace CBSVisualizer.Modules.Queue.Views diff --git a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/ViewModels/SettingsDialogViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/ViewModels/SettingsDialogViewModel.cs index 48b3dc5..ad966f2 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/ViewModels/SettingsDialogViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/ViewModels/SettingsDialogViewModel.cs @@ -1,14 +1,8 @@ using CBSVisualizer.Core.Mvvm; -using CBSVisualizer.Services.SettingsService.Service; -using Prism.Commands; -using Prism.Mvvm; +using CBSVisualizer.Services.SettingsService.Implementation; using Prism.Regions; using Prism.Services.Dialogs; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace CBSVisualizer.Modules.SettingsDialog.ViewModels { diff --git a/CBSVisualizer/CBSVisualizer.Services.PacketService/CBSVisualizer.Services.PacketService.csproj b/CBSVisualizer/CBSVisualizer.Services.PacketService/CBSVisualizer.Services.PacketService.csproj new file mode 100644 index 0000000..2d123f6 --- /dev/null +++ b/CBSVisualizer/CBSVisualizer.Services.PacketService/CBSVisualizer.Services.PacketService.csproj @@ -0,0 +1,11 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>net5.0</TargetFramework> + </PropertyGroup> + + <ItemGroup> + <ProjectReference Include="..\CBSVisualizer.MessagingCore\CBSVisualizer.Messaging.csproj" /> + </ItemGroup> + +</Project> diff --git a/CBSVisualizer/CBSVisualizer.Services.PacketService/Implementation/RandomPacketService.cs b/CBSVisualizer/CBSVisualizer.Services.PacketService/Implementation/RandomPacketService.cs new file mode 100644 index 0000000..be5b66a --- /dev/null +++ b/CBSVisualizer/CBSVisualizer.Services.PacketService/Implementation/RandomPacketService.cs @@ -0,0 +1,37 @@ +using CBSVisualizer.Messaging; +using CBSVisualizer.Services.PacketService.Interface; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CBSVisualizer.Services.PacketService.Implementation +{ + public class RandomPacketService : IPacketService + { + private const int HEADER_BYTES = 100; + + private const int TRAILER_BYTES = 100; + + private readonly Random random = new Random(); + + public PriorityPacket GeneratePacket(int priority) + { + return new PriorityPacket( + priority, // Priority between 0 and 7 + HEADER_BYTES, + random.Next(2000), // Random value between 0 and 1999. + TRAILER_BYTES); + } + + public PriorityPacket GeneratePacket() + { + return new PriorityPacket( + random.Next(0, 8), // Priority between 0 and 7 + HEADER_BYTES, + random.Next(2000), // Random value between 0 and 1999. + TRAILER_BYTES); + } + } +} diff --git a/CBSVisualizer/CBSVisualizer.Services.PacketService/Interface/IPacketService.cs b/CBSVisualizer/CBSVisualizer.Services.PacketService/Interface/IPacketService.cs new file mode 100644 index 0000000..0b7ca4c --- /dev/null +++ b/CBSVisualizer/CBSVisualizer.Services.PacketService/Interface/IPacketService.cs @@ -0,0 +1,22 @@ +using CBSVisualizer.Messaging; +using System; +using System.Net.Mail; + +namespace CBSVisualizer.Services.PacketService.Interface +{ + public interface IPacketService + { + /// <summary> + /// Generates a packet with the specified priority. + /// </summary> + /// <param name="priority"></param> + /// <returns></returns> + PriorityPacket GeneratePacket(int priority); + + /// <summary> + /// Generates a packet with a random priority. + /// </summary> + /// <returns></returns> + PriorityPacket GeneratePacket(); + } +} diff --git a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs index ddccc65..0f89150 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs @@ -1,5 +1,6 @@ using CBSVisualizer.Messaging.Events; -using CBSVisualizer.Services.SettingsService.Service; +using CBSVisualizer.Services.SchedulingService.Interface; +using CBSVisualizer.Services.SettingsService.Implementation; using log4net; using Prism.Events; using System; diff --git a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Interface/ISchedulingService.cs b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Interface/ISchedulingService.cs index 2fd639a..4896d20 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Interface/ISchedulingService.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Interface/ISchedulingService.cs @@ -1,10 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Threading.Tasks; -namespace CBSVisualizer.Services.SchedulingService +namespace CBSVisualizer.Services.SchedulingService.Interface { public interface ISchedulingService { diff --git a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Service/SettingService.cs b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs similarity index 96% rename from CBSVisualizer/CBSVisualizer.Services.SettingsService/Service/SettingService.cs rename to CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs index 72e9458..3be0dff 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SettingsService/Service/SettingService.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SettingsService/Implementation/SettingService.cs @@ -6,7 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace CBSVisualizer.Services.SettingsService.Service +namespace CBSVisualizer.Services.SettingsService.Implementation { public class SettingService { diff --git a/CBSVisualizer/CBSVisualizer.sln b/CBSVisualizer/CBSVisualizer.sln index bc17186..ccf16e1 100644 --- a/CBSVisualizer/CBSVisualizer.sln +++ b/CBSVisualizer/CBSVisualizer.sln @@ -36,6 +36,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CBSVisualizer.Core", "CBSVi EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CBSVisualizer.Common", "CBSVisualizer.Common\CBSVisualizer.Common.csproj", "{9B1B603C-601C-4F31-ADD9-D0962C0011AF}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CBSVisualizer.Services.PacketService", "CBSVisualizer.Services.PacketService\CBSVisualizer.Services.PacketService.csproj", "{274C0DC3-C59C-4C91-8130-6DEF2BDBD0A1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -86,6 +88,10 @@ Global {9B1B603C-601C-4F31-ADD9-D0962C0011AF}.Debug|Any CPU.Build.0 = Debug|Any CPU {9B1B603C-601C-4F31-ADD9-D0962C0011AF}.Release|Any CPU.ActiveCfg = Release|Any CPU {9B1B603C-601C-4F31-ADD9-D0962C0011AF}.Release|Any CPU.Build.0 = Release|Any CPU + {274C0DC3-C59C-4C91-8130-6DEF2BDBD0A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {274C0DC3-C59C-4C91-8130-6DEF2BDBD0A1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {274C0DC3-C59C-4C91-8130-6DEF2BDBD0A1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {274C0DC3-C59C-4C91-8130-6DEF2BDBD0A1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -99,6 +105,7 @@ Global {B2059A32-91EC-4CFF-AB5C-87FBC3B6686C} = {6D2194E0-E17B-44D6-AD8C-F3699549D259} {AB9EA79C-F11F-4B93-A08E-8C52A9716666} = {BFDCC6CE-CAA6-45AA-832F-0CBAB9A3C8BA} {61B7FF00-1B9D-4ABF-B3BF-667A1505415F} = {BFDCC6CE-CAA6-45AA-832F-0CBAB9A3C8BA} + {274C0DC3-C59C-4C91-8130-6DEF2BDBD0A1} = {BFDCC6CE-CAA6-45AA-832F-0CBAB9A3C8BA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {EE8EFE44-67AF-451F-9DFD-7B458AA3B3B3} diff --git a/CBSVisualizer/CBSVisualizer/App.xaml.cs b/CBSVisualizer/CBSVisualizer/App.xaml.cs index 8fd0e59..dfe06d6 100644 --- a/CBSVisualizer/CBSVisualizer/App.xaml.cs +++ b/CBSVisualizer/CBSVisualizer/App.xaml.cs @@ -2,7 +2,7 @@ using CBSVisualizer.Views; using System.Windows; using Prism.Modularity; -using CBSVisualizer.Services.SettingsService.Service; +using CBSVisualizer.Services.SettingsService.Implementation; using CBSVisualizer.Services.SchedulingService.Implementation; using CBSVisualizer.Modules.Queue.QueueGroup; using CBSVisualizer.Services.SchedulingService; @@ -10,7 +10,9 @@ using CBSVisualizer.Modules.Link; using CBSVisualizer.Modules.SettingsDialog; using CBSVisualizer.Modules.MenuBar; using System.IO; -using System.Configuration; +using CBSVisualizer.Services.PacketService.Implementation; +using CBSVisualizer.Services.PacketService.Interface; +using CBSVisualizer.Services.SchedulingService.Interface; namespace CBSVisualizer { @@ -29,6 +31,7 @@ namespace CBSVisualizer // containerRegistry.RegisterSingleton<IMessageService, MessageService>(); containerRegistry.RegisterSingleton<SettingService>(); containerRegistry.RegisterSingleton<ISchedulingService, RandomSchedulingService>(); + containerRegistry.RegisterSingleton<IPacketService, RandomPacketService>(); } protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) diff --git a/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj b/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj index 0ecc3d1..3a731bf 100644 --- a/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj +++ b/CBSVisualizer/CBSVisualizer/CBSVisualizer.csproj @@ -16,6 +16,7 @@ <ProjectReference Include="..\CBSVisualizer.Modules.MenuBar\CBSVisualizer.Modules.MenuBar.csproj" /> <ProjectReference Include="..\CBSVisualizer.Modules.Queue.QueueGroup\CBSVisualizer.Modules.QueueGroup.csproj" /> <ProjectReference Include="..\CBSVisualizer.Modules.SettingsDialog\CBSVisualizer.Modules.SettingsDialog.csproj" /> + <ProjectReference Include="..\CBSVisualizer.Services.PacketService\CBSVisualizer.Services.PacketService.csproj" /> <ProjectReference Include="..\CBSVisualizer.Services.SchedulingService\CBSVisualizer.Services.SchedulingService.csproj" /> <ProjectReference Include="..\CBSVisualizer.Services.SettingsService\CBSVisualizer.Services.SettingService.csproj" /> </ItemGroup> -- GitLab From 1cf18089e46724dac97d8f81d3d6623183241b54 Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Thu, 10 Sep 2020 21:57:09 +0200 Subject: [PATCH 08/17] Remove some of the logs. --- .../ViewModels/QueueViewModel.LinkCallbacks.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs index 37c7375..e48021e 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs @@ -215,8 +215,6 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override async Task GateClosed() { - log.Info("GateClosed"); - // Stop the credit growth thread. await parent.StopCreditThread(); @@ -224,9 +222,6 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override Task GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) { - log.Info("GateOpened"); - - // Start the credit lock (parent.queueLock) { @@ -249,9 +244,6 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override Task PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) { - - log.Info("PacketPreempted"); - lock (parent.queueLock) { parent.Queue.Insert(0, new PriorityPacket(parent.Priority, leftoverBytes)); @@ -263,7 +255,6 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override async Task TransmissionCompleted() { log.Info("TransmissionCompleted"); - await parent.StopCreditThread(); await parent.StartCreditThread(parent.IdleSlope); } -- GitLab From 317910365f3aaad48b8ce2dd16fabda1f5171731 Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Sat, 12 Sep 2020 15:50:24 +0200 Subject: [PATCH 09/17] Remove wrapping Task.Run(...) from StartCreditThread. --- .../ViewModels/QueueViewModel.cs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs index 932e9d9..03b2add 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs @@ -192,19 +192,15 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { log.Info($"Queue {Priority}: Credit Thread was started with {bytesPerSecondSlope} bytes/s slope."); creditGrowthCancellationSource = new CancellationTokenSource(); - await Task.Run(async () => + while (!creditGrowthCancellationSource.Token.IsCancellationRequested && CurrentCredit < limit && Queue.Count > 0) { - // Refresh the credit. - while (!creditGrowthCancellationSource.Token.IsCancellationRequested && CurrentCredit < limit && Queue.Count > 0) - { - // Wait for the specified amount of time. - await Task.Delay(TimeSpan.FromSeconds(CREDIT_REFRESH_RATE_S), creditGrowthCancellationSource.Token); + // Wait for the specified amount of time. + await Task.Delay(TimeSpan.FromSeconds(CREDIT_REFRESH_RATE_S), creditGrowthCancellationSource.Token); - AtomicUpdateCredit(CREDIT_REFRESH_RATE_S * bytesPerSecondSlope, limit); + AtomicUpdateCredit(CREDIT_REFRESH_RATE_S * bytesPerSecondSlope, limit); - Debug.WriteLine($"Queue {Priority}: Credit {CurrentCredit}"); - } - }, creditGrowthCancellationSource.Token); + log.Info($"Queue {Priority}: Credit {CurrentCredit}"); + } } private async Task StopCreditThread() -- GitLab From 54737ca784fc93e0d27a8643349df8a75b16c418 Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Sat, 12 Sep 2020 15:57:24 +0200 Subject: [PATCH 10/17] Remove some wrong references. --- .../CBSVisualizer.Modules.MenuBar.csproj | 1 - .../CBSVisualizer.Modules.QueueGroup.csproj | 1 - .../CBSVisualizer.Modules.Queue.csproj | 1 - .../CBSVisualizer.Modules.SettingsDialog.csproj | 1 - 4 files changed, 4 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj index bd70497..390006b 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/CBSVisualizer.Modules.MenuBar.csproj @@ -14,6 +14,5 @@ <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" /> - <ProjectReference Include="..\CBSVisualizer\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> </ItemGroup> </Project> \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj index 5dd618b..4028604 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue.QueueGroup/CBSVisualizer.Modules.QueueGroup.csproj @@ -12,6 +12,5 @@ <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> <ProjectReference Include="..\CBSVisualizer.Modules.Queue\CBSVisualizer.Modules.Queue.csproj" /> - <ProjectReference Include="..\CBSVisualizer\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> </ItemGroup> </Project> \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj b/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj index 2398fc6..7a155ee 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/CBSVisualizer.Modules.Queue.csproj @@ -15,6 +15,5 @@ <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\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> </ItemGroup> </Project> \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj index 40a784e..f9da61e 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj +++ b/CBSVisualizer/CBSVisualizer.Modules.SettingsDialog/CBSVisualizer.Modules.SettingsDialog.csproj @@ -12,6 +12,5 @@ <ItemGroup> <ProjectReference Include="..\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> <ProjectReference Include="..\CBSVisualizer.Services.SettingsService\CBSVisualizer.Services.SettingService.csproj" /> - <ProjectReference Include="..\CBSVisualizer\CBSVisualizer.Core\CBSVisualizer.Core.csproj" /> </ItemGroup> </Project> \ No newline at end of file -- GitLab From d1f6e26e19fc61577808ebda44c33cf6295060e6 Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Sat, 12 Sep 2020 16:06:56 +0200 Subject: [PATCH 11/17] Remove wrapping await Task.Run(...) in MenuBarViewModel.LoadGeneration.cs. Remove one CanExecute method, because it can be expressed by inverting the other one. --- .../MenuBarViewModel.LoadGeneration.cs | 33 +++++++------------ .../ViewModels/MenuBarViewModel.cs | 2 +- 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs index 4fb601d..c94c3c8 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.LoadGeneration.cs @@ -36,9 +36,11 @@ namespace CBSVisualizer.Modules.MenuBar.ViewModels return !LoadGenerationInProgress; } - private bool CanStopLoadGeneration() + private async Task StartLoadThread() { - return LoadGenerationInProgress; + tokenSource = new CancellationTokenSource(); + LoadGenerationInProgress = true; + await GenerateLoad(); } private void StopLoadThread() @@ -49,18 +51,14 @@ namespace CBSVisualizer.Modules.MenuBar.ViewModels private async Task GenerateLoad() { - await Task.Run(async () => - { - int packetCount = 0; + 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"); - } - - }, tokenSource.Token); + 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() @@ -69,14 +67,5 @@ namespace CBSVisualizer.Modules.MenuBar.ViewModels log.Info(ret); return ret; } - - - private async Task StartLoadThread() - { - tokenSource = new CancellationTokenSource(); - LoadGenerationInProgress = true; - - await GenerateLoad(); - } } } diff --git a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs index 0187f30..ee49c0f 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.MenuBar/ViewModels/MenuBarViewModel.cs @@ -51,7 +51,7 @@ namespace CBSVisualizer.Modules.MenuBar.ViewModels OpenSettingsCommand = new DelegateCommand(() => dialogService.Show("SettingsDialog", new DialogParameters(), result => { })); StartLoadGeneration = new DelegateCommand(async () => await StartLoadThread(), CanStartLoadGeneration).ObservesProperty(() => LoadGenerationInProgress); - StopLoadGeneration = new DelegateCommand(StopLoadThread, CanStopLoadGeneration).ObservesProperty(() => LoadGenerationInProgress); + StopLoadGeneration = new DelegateCommand(StopLoadThread, () => !CanStartLoadGeneration()).ObservesProperty(() => LoadGenerationInProgress); } private void SignalSimulationStart() { -- GitLab From bb356efbd459ef7021435a86d616735bf057d7aa Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Sat, 12 Sep 2020 16:25:08 +0200 Subject: [PATCH 12/17] Remove some more stuff. --- .../ViewModels/LinkViewModel.cs | 21 +---------- .../QueueViewModel.LinkCallbacks.cs | 35 +++++++++++-------- .../ViewModels/QueueViewModel.cs | 26 +++----------- 3 files changed, 26 insertions(+), 56 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs index 52ff6b8..e558a51 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs @@ -31,8 +31,6 @@ namespace CBSVisualizer.Modules.Link.ViewModels private CancellationTokenSource tokenSource; - private Task packetTransmissionTask; - /// <summary> /// The queue that is currently sending. /// </summary> @@ -92,14 +90,6 @@ namespace CBSVisualizer.Modules.Link.ViewModels // Stop packet sending. tokenSource?.Cancel(); - if (packetTransmissionTask != null) - { - try - { - await packetTransmissionTask; - } catch (TaskCanceledException) { } - - } // Reset all gate status lamps. SetStatusLamps(new HashSet<int>()); @@ -126,15 +116,6 @@ namespace CBSVisualizer.Modules.Link.ViewModels { // Cancel old sending task. tokenSource?.Cancel(); - if (packetTransmissionTask != null) - { - try - { - await packetTransmissionTask; - } - catch (TaskCanceledException) { } - - } packetInTransit = PriorityPacket.NoPacket; @@ -146,7 +127,7 @@ namespace CBSVisualizer.Modules.Link.ViewModels // Handle transmission. tokenSource = new CancellationTokenSource(); - packetTransmissionTask = TransmitPackets(infoTuple); + await TransmitPackets(infoTuple); } /// <summary> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs index e48021e..7a5da57 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs @@ -154,7 +154,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels // If my packet was denied due to pre-closing, freeze my credit. } else if (submitResult == PacketSubmitResult.DeniedPreClosing) { - _ = parent.StopCreditThread(); + parent.StopCreditThread(); } } @@ -176,14 +176,14 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override async Task TransmissionCompleted() { // Stop and restart the credit thread. - await parent.StopCreditThread(); + parent.StopCreditThread(); await parent.StartCreditThread(parent.IdleSlope); } public override async Task TransmissionStarted(double bytesPerSecondRate) { // Decrease the credit by the idle slope. - await parent.StopCreditThread(); + parent.StopCreditThread(); await parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); } } @@ -213,11 +213,11 @@ namespace CBSVisualizer.Modules.Queue.ViewModels } - public override async Task GateClosed() + public override Task GateClosed() { // Stop the credit growth thread. - await parent.StopCreditThread(); - + parent.StopCreditThread(); + return Task.CompletedTask; } public override Task GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) @@ -255,14 +255,14 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override async Task TransmissionCompleted() { log.Info("TransmissionCompleted"); - await parent.StopCreditThread(); + parent.StopCreditThread(); await parent.StartCreditThread(parent.IdleSlope); } public override async Task TransmissionStarted(double bytesPerSecondRate) { log.Info("TransmissionStarted"); - await parent.StopCreditThread(); + parent.StopCreditThread(); await parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); } } @@ -285,14 +285,15 @@ namespace CBSVisualizer.Modules.Queue.ViewModels return Task.CompletedTask; } - public override Task GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) + public override async Task GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) { + var sentSuccessfully = false; lock (parent.queueLock) { // Again, check if we can submit anything. if (!CanSend()) { - return Task.CompletedTask; + return; } var firstPacket = parent.Queue.First(); @@ -301,14 +302,18 @@ namespace CBSVisualizer.Modules.Queue.ViewModels if (submitResult == PacketSubmitResult.Accepted) { parent.Queue.Remove(firstPacket); + sentSuccessfully = true; } else if (submitResult == PacketSubmitResult.DeniedPreClosing) // In the pre-closing case, we signal the thread to increase our credit to zero. { - _ = parent.StopCreditThread(); - _ = parent.StartCreditThread(parent.IdleSlope, 0); + parent.StopCreditThread(); + sentSuccessfully = false; } } - return Task.CompletedTask; + if (sentSuccessfully) + { + await parent.StartCreditThread(parent.IdleSlope, 0); + } } public override Task PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) @@ -323,13 +328,13 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override async Task TransmissionCompleted() { - await parent.StopCreditThread(); + parent.StopCreditThread(); await parent.StartCreditThread(parent.IdleSlope); } public override async Task TransmissionStarted(double bytesPerSecondRate) { - await parent.StopCreditThread(); + parent.StopCreditThread(); await parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); } } diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs index 03b2add..37cb0ae 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs @@ -20,6 +20,8 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { public partial class QueueViewModel : RegionViewModelBase { + private const double CREDIT_REFRESH_RATE_S = 0.1; + private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private readonly IEventAggregator eventAggregator; @@ -30,10 +32,6 @@ namespace CBSVisualizer.Modules.Queue.ViewModels private CancellationTokenSource creditGrowthCancellationSource; - private const double CREDIT_REFRESH_RATE_S = 0.1; - - private Task creditUpdateTask; - private double currentCredit = 0; public double CurrentCredit { @@ -176,11 +174,11 @@ namespace CBSVisualizer.Modules.Queue.ViewModels private void RegisterSimulationStartStopHandler() { - eventAggregator.GetEvent<SimulationStoppedEvent>().Subscribe(async () => + eventAggregator.GetEvent<SimulationStoppedEvent>().Subscribe(() => { if (SelectedCreditBehaviour != CreditBehaviour.NoCBS) { - await StopCreditThread(); + StopCreditThread(); // Reset credit. currentCredit = 0; @@ -203,24 +201,10 @@ namespace CBSVisualizer.Modules.Queue.ViewModels } } - private async Task StopCreditThread() + private void StopCreditThread() { creditGrowthCancellationSource?.Cancel(); - try - { - if (creditUpdateTask != null) - { - await creditUpdateTask; - } - - } catch (TaskCanceledException) - { - log.Info($"Queue {Priority}: Credit Thread was cancelled."); - } - log.Info($"Queue {Priority}: Credit Thread was stopped successfully."); - creditUpdateTask = null; - creditGrowthCancellationSource = null; } private void AtomicUpdateCredit(double increment, double limit) -- GitLab From e7cc913f28e235c190cbb69c1c1cb6b21030c9fd Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Sat, 12 Sep 2020 16:59:50 +0200 Subject: [PATCH 13/17] Correct the RandomSchedulingService to have an async start and a void stop method. I've come to the conclusion that async/await is not applicable for the Credit Update Scenario. I'll switch to a traditional thread there. --- .../ViewModels/LinkViewModel.cs | 17 ++++++++++---- .../ViewModels/QueueViewModel.cs | 19 +++++++++------ .../Implementation/RandomSchedulingService.cs | 23 +++++-------------- .../Interface/ISchedulingService.cs | 4 ++-- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs index e558a51..1f4a2ff 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs @@ -7,6 +7,7 @@ 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.Linq; @@ -62,7 +63,7 @@ namespace CBSVisualizer.Modules.Link.ViewModels linkCallbacks[callback.GetPriority()] = callback; }); - eventAggregator.GetEvent<SimulationStartedEvent>().Subscribe(() => + eventAggregator.GetEvent<SimulationStartedEvent>().Subscribe(async () => { if (linkCallbacks.Count != 8) { @@ -72,21 +73,27 @@ namespace CBSVisualizer.Modules.Link.ViewModels // Call Initialize() on each ILinkCallback. log.Info("Initializing all links"); + var initTasks = new List<Task>(); foreach (var callback in linkCallbacks.Values) { - callback.Initialize(); + initTasks.Add(callback.Initialize()); } // Start scheduling. - scheduler.StartScheduling(); + try + { + await Task.WhenAll(initTasks); + await scheduler.StartScheduling(); + } catch (TaskCanceledException) { + } log.Info("Simulation started."); }); - eventAggregator.GetEvent<SimulationStoppedEvent>().Subscribe(async () => + eventAggregator.GetEvent<SimulationStoppedEvent>().Subscribe(() => { // Stop the scheduler - await scheduler.StopScheduling(); + scheduler.StopScheduling(); // Stop packet sending. tokenSource?.Cancel(); diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs index 37cb0ae..2247c06 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs @@ -188,17 +188,22 @@ namespace CBSVisualizer.Modules.Queue.ViewModels private async Task StartCreditThread(double bytesPerSecondSlope, double limit = double.PositiveInfinity) { - log.Info($"Queue {Priority}: Credit Thread was started with {bytesPerSecondSlope} bytes/s slope."); + // Init new cancellation token. creditGrowthCancellationSource = new CancellationTokenSource(); - while (!creditGrowthCancellationSource.Token.IsCancellationRequested && CurrentCredit < limit && Queue.Count > 0) + + await Task.Run(async () => { - // Wait for the specified amount of time. - await Task.Delay(TimeSpan.FromSeconds(CREDIT_REFRESH_RATE_S), creditGrowthCancellationSource.Token); + log.Info($"Queue {Priority}: Credit Thread was started with {bytesPerSecondSlope} bytes/s slope."); + while (!creditGrowthCancellationSource.Token.IsCancellationRequested && CurrentCredit < limit && Queue.Count > 0) + { + // Wait for the specified amount of time. + await Task.Delay(TimeSpan.FromSeconds(CREDIT_REFRESH_RATE_S), creditGrowthCancellationSource.Token); - AtomicUpdateCredit(CREDIT_REFRESH_RATE_S * bytesPerSecondSlope, limit); + AtomicUpdateCredit(CREDIT_REFRESH_RATE_S * bytesPerSecondSlope, limit); - log.Info($"Queue {Priority}: Credit {CurrentCredit}"); - } + log.Info($"Queue {Priority}: Credit {CurrentCredit}"); + } + }, creditGrowthCancellationSource.Token); } private void StopCreditThread() diff --git a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs index 0f89150..9eb15cd 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Implementation/RandomSchedulingService.cs @@ -38,8 +38,8 @@ namespace CBSVisualizer.Services.SchedulingService.Implementation int highPrioOpenedTime = GetRandomWaitingTime(); // Publish GateOpenedEvent for the high prio queue. + log.Info("Publishing GateOpenedEvent [High Prio]"); eventAggregator.GetEvent<GateOpenedEvent>().Publish((OpenedTime: highPrioOpenedTime, OpenedGates: new HashSet<int> { 7 })); - log.Info("Published GateOpenedEvent [High Prio]"); // Wait for the specified time. await Task.Delay(highPrioOpenedTime + PROCESSING_DELAY_MS, tokenSource.Token); @@ -48,8 +48,8 @@ namespace CBSVisualizer.Services.SchedulingService.Implementation int 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 })); - log.Info("Published GateOpenedEvent [Lower Prio]"); // Wait for the specified time again. await Task.Delay(lowPrioOpenedTime + PROCESSING_DELAY_MS, tokenSource.Token); @@ -61,26 +61,15 @@ namespace CBSVisualizer.Services.SchedulingService.Implementation return random.Next(settings.GetSettingValue<int>(MIN_DELAY_SETTING_KEY), settings.GetSettingValue<int>(MAX_DELAY_SETTING_KEY)); } - public void StartScheduling() + public async Task StartScheduling() { tokenSource = new CancellationTokenSource(); - schedulerTask = StartScheduler(); + await StartScheduler(); } - public async Task StopScheduling() + public void StopScheduling() { - try - { - tokenSource?.Cancel(); - if (schedulerTask != null) - { - await schedulerTask; - } - } catch (TaskCanceledException) - { - // Don't do anything. - } - + tokenSource?.Cancel(); } } } \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Interface/ISchedulingService.cs b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Interface/ISchedulingService.cs index 4896d20..e5bb1a1 100644 --- a/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Interface/ISchedulingService.cs +++ b/CBSVisualizer/CBSVisualizer.Services.SchedulingService/Interface/ISchedulingService.cs @@ -4,8 +4,8 @@ namespace CBSVisualizer.Services.SchedulingService.Interface { public interface ISchedulingService { - public void StartScheduling(); + public Task StartScheduling(); - public Task StopScheduling(); + public void StopScheduling(); } } -- GitLab From d944c95b6aca17604007c66ea32af4ba01711cbc Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Sat, 12 Sep 2020 17:56:52 +0200 Subject: [PATCH 14/17] Change link callback interface a bit and introduce "normal" thread for credit update. --- .../Events/RegisterLinkCallbackEvent.cs | 12 +- .../ViewModels/LinkViewModel.cs | 13 +- .../QueueViewModel.LinkCallbacks.cs | 146 ++++++++---------- .../ViewModels/QueueViewModel.cs | 124 +++++++-------- .../Views/Queue.xaml.cs | 4 +- 5 files changed, 135 insertions(+), 164 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/RegisterLinkCallbackEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/RegisterLinkCallbackEvent.cs index d564aef..8503b93 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/RegisterLinkCallbackEvent.cs +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/RegisterLinkCallbackEvent.cs @@ -35,36 +35,36 @@ namespace CBSVisualizer.Messaging.Events /// Allows to perform necessary initialization operations. /// </summary> /// <returns></returns> - Task Initialize(); + 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> - Task GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket); + void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket); /// <summary> /// Called by the link if the gate of the queue has been closed. /// </summary> - Task GateClosed(); + 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> - Task PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes); + 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> - Task TransmissionStarted(double bytesPerSecondRate); + void TransmissionStarted(double bytesPerSecondRate); /// <summary> /// Called when the transmission of the last packet has been completed. /// </summary> - Task TransmissionCompleted(); + void TransmissionCompleted(); } /// <summary> diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs index 1f4a2ff..db692ca 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs @@ -73,18 +73,17 @@ namespace CBSVisualizer.Modules.Link.ViewModels // Call Initialize() on each ILinkCallback. log.Info("Initializing all links"); - var initTasks = new List<Task>(); foreach (var callback in linkCallbacks.Values) { - initTasks.Add(callback.Initialize()); + callback.Initialize(); } // Start scheduling. try { - await Task.WhenAll(initTasks); await scheduler.StartScheduling(); - } catch (TaskCanceledException) { + } catch (TaskCanceledException) { + log.Info("Scheduling was cancelled by button press."); } log.Info("Simulation started."); @@ -154,7 +153,7 @@ namespace CBSVisualizer.Modules.Link.ViewModels // Scan the callbacks for the highest-prio queue that wants to send a packet. foreach (var queue in infoTuple.OpenedGates.OrderByDescending(gate => gate)) { - await linkCallbacks[queue].GateOpened(packet => + linkCallbacks[queue].GateOpened(packet => { if (packetInTransit == PriorityPacket.NoPacket) { @@ -186,7 +185,7 @@ namespace CBSVisualizer.Modules.Link.ViewModels // Once a packet was selected for transmission, we send it. transmittedBytes = 0; - await linkCallbacks[activeQueue].TransmissionStarted(bitrate); + linkCallbacks[activeQueue].TransmissionStarted(bitrate); try { @@ -199,7 +198,7 @@ namespace CBSVisualizer.Modules.Link.ViewModels } catch (TaskCanceledException) { } finally { - await linkCallbacks[activeQueue].TransmissionCompleted(); + linkCallbacks[activeQueue].TransmissionCompleted(); log.Info($"{packetInTransit} of queue {activeQueue} has been sent successfully."); // Reset the "Packet in transit" pointer. diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs index 7a5da57..ddc31d8 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs @@ -9,11 +9,26 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { public partial class QueueViewModel { + public enum CreditBehaviour + { + // This is selected when there should be no credit-based shaper for this queue. + NoCbs, + + // Frozen credit behaviour + Frozen, + + // The standard credit behaviour + Standard, + + // Return to zero. + ReturnToZero + } private abstract class LinkCallbackBase : ILinkCallback { protected readonly QueueViewModel parent; - public LinkCallbackBase(QueueViewModel parentViewModel) + + protected LinkCallbackBase(QueueViewModel parentViewModel) { parent = parentViewModel; } @@ -28,10 +43,9 @@ namespace CBSVisualizer.Modules.Queue.ViewModels return parent.Priority; } - public virtual Task Initialize() + public virtual void Initialize() { // Do nothing by default. - return Task.CompletedTask; } protected bool CanSend() @@ -42,31 +56,30 @@ namespace CBSVisualizer.Modules.Queue.ViewModels } } - public abstract Task GateClosed(); + public abstract void GateClosed(); - public abstract Task GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket); + public abstract void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket); - public abstract Task PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes); + public abstract void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes); - public abstract Task TransmissionCompleted(); + public abstract void TransmissionCompleted(); - public abstract Task TransmissionStarted(double bytesPerSecondRate); + public abstract void TransmissionStarted(double bytesPerSecondRate); } - private class NoCBSLinkCallback : LinkCallbackBase + private class NoCbsLinkCallback : LinkCallbackBase { - public NoCBSLinkCallback(QueueViewModel parent) + public NoCbsLinkCallback(QueueViewModel parent) : base(parent) { } - public override Task GateClosed() + public override void GateClosed() { // Nothing to be done. - return Task.CompletedTask; } - public override Task GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) + public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) { // Try to submit the "oldest" packet. lock (parent.queueLock) @@ -74,7 +87,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels // If the queue is empty, return. if (!CanSend()) { - return Task.CompletedTask; + return; } // If the packet was accepted, remove it from the queue. @@ -87,29 +100,25 @@ namespace CBSVisualizer.Modules.Queue.ViewModels // Otherwise, just don't do anything :-) } - return Task.CompletedTask; } - public override Task PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) + public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) { // Build a new packet that just contains the leftover bytes and put it into the queue. lock (parent.queueLock) { parent.Queue.Insert(0, new PriorityPacket(parent.Priority, leftoverBytes)); - return Task.CompletedTask; } } - public override Task TransmissionCompleted() + public override void TransmissionCompleted() { - return Task.CompletedTask; } - public override Task TransmissionStarted(double bytesPerSecondRate) + public override void TransmissionStarted(double bytesPerSecondRate) { // Just write some log. Debug.WriteLine($"Packet of Queue {parent.Priority} has started transmission with {bytesPerSecondRate} bytes/s."); - return Task.CompletedTask; } } @@ -121,18 +130,17 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { } - public override async Task Initialize() + public override void Initialize() { - await parent.StartCreditThread(parent.IdleSlope); + parent.StartCreditThread(parent.IdleSlope); } - public override Task GateClosed() + public override void GateClosed() { // Nothing special happens here. The credit handling is done in the GateOpened method. - return Task.CompletedTask; } - public override Task GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) + public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) { // Try to submit first packet. lock (parent.queueLock) @@ -140,7 +148,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels if (!CanSend()) { - return Task.CompletedTask; + return; } var firstPacket = parent.Queue.First(); @@ -159,32 +167,29 @@ namespace CBSVisualizer.Modules.Queue.ViewModels } // Otherwise, just let the credit grow for now. - return Task.CompletedTask; } - public override Task PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) + public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) { // Put the leftovers of the packet back into the queue. lock (parent.queueLock) { parent.Queue.Insert(0, new PriorityPacket(parent.Priority, leftoverBytes)); } - - return Task.CompletedTask; } - public override async Task TransmissionCompleted() + public override void TransmissionCompleted() { // Stop and restart the credit thread. parent.StopCreditThread(); - await parent.StartCreditThread(parent.IdleSlope); + parent.StartCreditThread(parent.IdleSlope); } - public override async Task TransmissionStarted(double bytesPerSecondRate) + public override void TransmissionStarted(double bytesPerSecondRate) { // Decrease the credit by the idle slope. parent.StopCreditThread(); - await parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); + parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); } } @@ -196,31 +201,18 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { } - public override async Task Initialize() + public override void Initialize() { - log.Info("Initialize"); - var shouldStartThread = false; - - lock (parent.queueLock) - { - shouldStartThread = parent.CurrentCredit < 0 || parent.Queue.Count > 0; - } - - if (shouldStartThread) - { - await parent.StartCreditThread(parent.IdleSlope); - } - + parent.StartCreditThread(parent.IdleSlope); } - public override Task GateClosed() + public override void GateClosed() { // Stop the credit growth thread. parent.StopCreditThread(); - return Task.CompletedTask; } - public override Task GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) + public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) { // Start the credit lock (parent.queueLock) @@ -228,7 +220,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels // Don't do anything when there are no packets. if (!CanSend()) { - return Task.CompletedTask; + return; } // Otherwise, once again try to send the first packet. @@ -238,32 +230,28 @@ namespace CBSVisualizer.Modules.Queue.ViewModels parent.Queue.Remove(firstPacket); } } - - return Task.CompletedTask; } - public override Task PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) + public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) { lock (parent.queueLock) { parent.Queue.Insert(0, new PriorityPacket(parent.Priority, leftoverBytes)); } - - return Task.CompletedTask; } - public override async Task TransmissionCompleted() + public override void TransmissionCompleted() { - log.Info("TransmissionCompleted"); + Log.Info("TransmissionCompleted"); parent.StopCreditThread(); - await parent.StartCreditThread(parent.IdleSlope); + parent.StartCreditThread(parent.IdleSlope); } - public override async Task TransmissionStarted(double bytesPerSecondRate) + public override void TransmissionStarted(double bytesPerSecondRate) { - log.Info("TransmissionStarted"); + Log.Info("TransmissionStarted"); parent.StopCreditThread(); - await parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); + parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); } } @@ -274,20 +262,18 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { } - public override async Task Initialize() + public override void Initialize() { - await parent.StartCreditThread(parent.IdleSlope); + parent.StartCreditThread(parent.IdleSlope); } - public override Task GateClosed() + public override void GateClosed() { // Nothing special to be done here. - return Task.CompletedTask; } - public override async Task GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) + public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) { - var sentSuccessfully = false; lock (parent.queueLock) { // Again, check if we can submit anything. @@ -302,40 +288,32 @@ namespace CBSVisualizer.Modules.Queue.ViewModels if (submitResult == PacketSubmitResult.Accepted) { parent.Queue.Remove(firstPacket); - sentSuccessfully = true; } else if (submitResult == PacketSubmitResult.DeniedPreClosing) // In the pre-closing case, we signal the thread to increase our credit to zero. { parent.StopCreditThread(); - sentSuccessfully = false; + parent.StartCreditThread(parent.IdleSlope, 0); } } - - if (sentSuccessfully) - { - await parent.StartCreditThread(parent.IdleSlope, 0); - } } - public override Task PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) + public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) { lock (parent.queueLock) { parent.Queue.Insert(0, new PriorityPacket(GetPriority(), leftoverBytes)); } - - return Task.CompletedTask; } - public override async Task TransmissionCompleted() + public override void TransmissionCompleted() { parent.StopCreditThread(); - await parent.StartCreditThread(parent.IdleSlope); + parent.StartCreditThread(parent.IdleSlope, 0); } - public override async Task TransmissionStarted(double bytesPerSecondRate) + public override void TransmissionStarted(double bytesPerSecondRate) { parent.StopCreditThread(); - await parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); + parent.StartCreditThread(GetSendSlope(bytesPerSecondRate), 0); } } } diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs index 2247c06..ddb6843 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs @@ -12,7 +12,6 @@ using Prism.Regions; using System; using System.Collections.ObjectModel; using System.Collections.Specialized; -using System.Diagnostics; using System.Threading; using System.Threading.Tasks; @@ -20,9 +19,11 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { public partial class QueueViewModel : RegionViewModelBase { - private const double CREDIT_REFRESH_RATE_S = 0.1; + private const int ThreadJoinTimeoutS = 1; - private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private const double CreditRefreshRateS = 0.1; + + private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod()?.DeclaringType); private readonly IEventAggregator eventAggregator; @@ -32,54 +33,33 @@ namespace CBSVisualizer.Modules.Queue.ViewModels private CancellationTokenSource creditGrowthCancellationSource; - private double currentCredit = 0; - public double CurrentCredit + private CreditBehaviour selectedCreditBehaviour; + + public CreditBehaviour SelectedCreditBehaviour { - get - { - return currentCredit; - } + get => selectedCreditBehaviour; - private set - { - SetProperty(ref currentCredit, value); - } + set => SetProperty(ref selectedCreditBehaviour, value); } - public enum CreditBehaviour - { - // This is selected when there should be no credit-based shaper for this queue. - NoCBS, - // Frozen credit behaviour - Frozen, + private double currentCredit = 0; - // The standard credit behaviour - Standard, + public double CurrentCredit + { + get => currentCredit; - // Return to zero. - ReturnToZero + private set => SetProperty(ref currentCredit, value); } - private CreditBehaviour selectedCreditBehaviour; - public CreditBehaviour SelectedCreditBehaviour { - get - { - return selectedCreditBehaviour; - } - - set - { - SetProperty(ref selectedCreditBehaviour, value); - } - } + private Thread creditUpdateThread; - public int Priority { get; private set; } + public int Priority { get; } public string PrioLabel { get; private set; } public string PacketLabel { get; private set; } - public ObservableCollection<PriorityPacket> Queue { get; private set; } = new ObservableCollection<PriorityPacket>(); + public ObservableCollection<PriorityPacket> Queue { get; } = new ObservableCollection<PriorityPacket>(); /// <summary> /// Idle Slope ( given in byte / s). @@ -116,7 +96,8 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { PrioLabel = "Priority"; PacketLabel = "Packet Count"; - } else + } + else { PrioLabel = ""; PacketLabel = ""; @@ -146,7 +127,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels private void HandleCreditBehaviourChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { - if (e.PropertyName.Equals("SelectedCreditBehaviour")) + if (e.PropertyName != null && e.PropertyName.Equals("SelectedCreditBehaviour")) { eventAggregator.GetEvent<RegisterLinkCallbackEvent>().Publish(GetLinkCallback()); } @@ -166,9 +147,9 @@ namespace CBSVisualizer.Modules.Queue.ViewModels case CreditBehaviour.Standard: return new StandardLinkCallback(this); - case CreditBehaviour.NoCBS: + case CreditBehaviour.NoCbs: default: - return new NoCBSLinkCallback(this); + return new NoCbsLinkCallback(this); } } @@ -176,40 +157,48 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { eventAggregator.GetEvent<SimulationStoppedEvent>().Subscribe(() => { - if (SelectedCreditBehaviour != CreditBehaviour.NoCBS) + if (SelectedCreditBehaviour == CreditBehaviour.NoCbs) { - StopCreditThread(); - - // Reset credit. - currentCredit = 0; + return; } + + StopCreditThread(); + + // Reset credit. + currentCredit = 0; }); } - private async Task StartCreditThread(double bytesPerSecondSlope, double limit = double.PositiveInfinity) + private void StartCreditThread(double bytesPerSecondSlope, double limit = double.PositiveInfinity) { // Init new cancellation token. creditGrowthCancellationSource = new CancellationTokenSource(); - await Task.Run(async () => + creditUpdateThread = new Thread(() => { - log.Info($"Queue {Priority}: Credit Thread was started with {bytesPerSecondSlope} bytes/s slope."); - while (!creditGrowthCancellationSource.Token.IsCancellationRequested && CurrentCredit < limit && Queue.Count > 0) + Log.Info($"Queue {Priority}: Credit Thread was started with {bytesPerSecondSlope} bytes/s slope."); + while (!creditGrowthCancellationSource.Token.IsCancellationRequested && CurrentCredit < limit && + Queue.Count > 0) { // Wait for the specified amount of time. - await Task.Delay(TimeSpan.FromSeconds(CREDIT_REFRESH_RATE_S), creditGrowthCancellationSource.Token); + Thread.Sleep(TimeSpan.FromSeconds(CreditRefreshRateS)); - AtomicUpdateCredit(CREDIT_REFRESH_RATE_S * bytesPerSecondSlope, limit); + AtomicUpdateCredit(CreditRefreshRateS * bytesPerSecondSlope, limit); - log.Info($"Queue {Priority}: Credit {CurrentCredit}"); + Log.Info($"Queue {Priority}: Credit {CurrentCredit}"); } - }, creditGrowthCancellationSource.Token); + }); + + creditUpdateThread.Start(); } private void StopCreditThread() { creditGrowthCancellationSource?.Cancel(); - log.Info($"Queue {Priority}: Credit Thread was stopped successfully."); + + Log.Info(creditUpdateThread.Join(TimeSpan.FromSeconds(ThreadJoinTimeoutS)) + ? $"Queue {Priority}: Unable to stop credit thread." + : $"Queue {Priority}: Credit Thread was stopped successfully."); } private void AtomicUpdateCredit(double increment, double limit) @@ -223,23 +212,28 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { eventAggregator.GetEvent<PacketArrivedEvent>().Subscribe(packet => { - if (packet.Priority == Priority) + if (packet.Priority != Priority) { - lock (queueLock) - { - // Add packet. - Queue.Add(packet); - } + return; } - }); - GeneratePacketOnClick = new DelegateCommand(() => - { lock (queueLock) { - Queue.Add(packetService.GeneratePacket(Priority)); + // Add packet. + Queue.Add(packet); } }); + + GeneratePacketOnClick = new DelegateCommand(async () => + { + await Task.Run(() => + { + lock (queueLock) + { + Queue.Add(packetService.GeneratePacket(Priority)); + } + }); + }); } } } \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs index cbf853e..e20fa11 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/Views/Queue.xaml.cs @@ -27,7 +27,7 @@ namespace CBSVisualizer.Modules.Queue.Views private void CreditBehaviourBoxSelectionChanged(object sender, SelectionChangedEventArgs e) { - if (CreditBehaviourBox.SelectedItem.Equals(CreditBehaviour.NoCBS)) + if (CreditBehaviourBox.SelectedItem.Equals(CreditBehaviour.NoCbs)) { CreditRateTextBox.IsEnabled = false; } else @@ -39,7 +39,7 @@ namespace CBSVisualizer.Modules.Queue.Views private static ObservableCollection<CreditBehaviour> InitList() { ObservableCollection<CreditBehaviour> ret = new ObservableCollection<CreditBehaviour>(); - ret.Add(CreditBehaviour.NoCBS); + ret.Add(CreditBehaviour.NoCbs); ret.Add(CreditBehaviour.Frozen); ret.Add(CreditBehaviour.Standard); ret.Add(CreditBehaviour.ReturnToZero); -- GitLab From c60cc618c4198bf28c235cae3652e9e0dee6fe3e Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Sat, 12 Sep 2020 18:40:07 +0200 Subject: [PATCH 15/17] Change some stuff. Maybe works better now. --- .../CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs | 4 ++-- CBSVisualizer/CBSVisualizer/App.xaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs index ddb6843..2e2dc0f 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs @@ -19,9 +19,9 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { public partial class QueueViewModel : RegionViewModelBase { - private const int ThreadJoinTimeoutS = 1; + private const int ThreadJoinTimeoutS = 5; - private const double CreditRefreshRateS = 0.1; + private const double CreditRefreshRateS = 1; private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod()?.DeclaringType); diff --git a/CBSVisualizer/CBSVisualizer/App.xaml b/CBSVisualizer/CBSVisualizer/App.xaml index bc2cf44..220ab7b 100644 --- a/CBSVisualizer/CBSVisualizer/App.xaml +++ b/CBSVisualizer/CBSVisualizer/App.xaml @@ -7,7 +7,7 @@ <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> - <materialDesign:BundledTheme BaseTheme="Light" PrimaryColor="Amber" SecondaryColor="LightBlue" /> + <materialDesign:BundledTheme BaseTheme="Dark" PrimaryColor="Amber" SecondaryColor="LightBlue" /> <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> -- GitLab From 3ff173ec666df97d1d08bfac5c398488161674a0 Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Mon, 14 Sep 2020 20:04:38 +0200 Subject: [PATCH 16/17] Replace a lot of double variables by long for performance reasons + introduce second lock for credit. --- .../Events/RegisterLinkCallbackEvent.cs | 2 +- .../ViewModels/LinkViewModel.cs | 24 ++-- .../QueueViewModel.LinkCallbacks.cs | 104 +++++++++--------- .../ViewModels/QueueViewModel.cs | 52 ++++++--- 4 files changed, 101 insertions(+), 81 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/RegisterLinkCallbackEvent.cs b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/RegisterLinkCallbackEvent.cs index 8503b93..21304fe 100644 --- a/CBSVisualizer/CBSVisualizer.MessagingCore/Events/RegisterLinkCallbackEvent.cs +++ b/CBSVisualizer/CBSVisualizer.MessagingCore/Events/RegisterLinkCallbackEvent.cs @@ -59,7 +59,7 @@ namespace CBSVisualizer.Messaging.Events /// Called by the link when the transmission has started. /// </summary> /// <param name="bytesPerSecondRate"> the rate in bytes per second. </param> - void TransmissionStarted(double bytesPerSecondRate); + void TransmissionStarted(long bytesPerSecondRate); /// <summary> /// Called when the transmission of the last packet has been completed. diff --git a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs index db692ca..995c0f5 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Link/ViewModels/LinkViewModel.cs @@ -210,17 +210,18 @@ namespace CBSVisualizer.Modules.Link.ViewModels private bool CanSendInTime(ref int remainingBytes, PriorityPacket packet) { - if (packet.Size <= remainingBytes) + if (packet.Size > remainingBytes) { - log.Info($"Packet Size: {packet.Size}, remaining bytes until next GateCloseEvent: {remainingBytes}. {remainingBytes - packet.Size} bytes left."); - remainingBytes -= packet.Size; - return true; + return false; } - return false; + log.Info($"Packet Size: {packet.Size}, remaining bytes until next GateCloseEvent: {remainingBytes}. {remainingBytes - packet.Size} bytes left."); + remainingBytes -= packet.Size; + return true; + } - private void CloseInactiveGates(ISet<int> openedGates) + private void CloseInactiveGates(IEnumerable<int> openedGates) { ISet<int> gatesToClose = new HashSet<int>(linkCallbacks.Keys); gatesToClose.ExceptWith(openedGates); @@ -236,18 +237,11 @@ namespace CBSVisualizer.Modules.Link.ViewModels /// Sets the status lamps according to the set. /// </summary> /// <param name="openedGates">the set containing the opened gates</param> - private void SetStatusLamps(ISet<int> openedGates) + private void SetStatusLamps(ICollection<int> openedGates) { foreach (var key in GateStatusDictionary.Keys) { - if (openedGates.Contains(key)) - { - GateStatusDictionary[key].Value = true; - } - else - { - GateStatusDictionary[key].Value = false; - } + GateStatusDictionary[key].Value = openedGates.Contains(key); } } diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs index ddc31d8..611f353 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs @@ -26,21 +26,21 @@ namespace CBSVisualizer.Modules.Queue.ViewModels private abstract class LinkCallbackBase : ILinkCallback { - protected readonly QueueViewModel parent; + protected readonly QueueViewModel Parent; protected LinkCallbackBase(QueueViewModel parentViewModel) { - parent = parentViewModel; + Parent = parentViewModel; } - protected double GetSendSlope(double rate) + protected long GetSendSlope(long rate) { - return parent.IdleSlope - rate; + return Parent.IdleSlope - rate; } public int GetPriority() { - return parent.Priority; + return Parent.Priority; } public virtual void Initialize() @@ -50,9 +50,9 @@ namespace CBSVisualizer.Modules.Queue.ViewModels protected bool CanSend() { - lock (parent.queueLock) + lock (Parent.queueLock) { - return parent.Queue.Count > 0 && parent.CurrentCredit >= 0; + return Parent.Queue.Count > 0 && Parent.CurrentCredit >= 0; } } @@ -64,7 +64,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public abstract void TransmissionCompleted(); - public abstract void TransmissionStarted(double bytesPerSecondRate); + public abstract void TransmissionStarted(long bytesPerSecondRate); } private class NoCbsLinkCallback : LinkCallbackBase @@ -82,7 +82,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) { // Try to submit the "oldest" packet. - lock (parent.queueLock) + lock (Parent.queueLock) { // If the queue is empty, return. if (!CanSend()) @@ -91,11 +91,11 @@ namespace CBSVisualizer.Modules.Queue.ViewModels } // If the packet was accepted, remove it from the queue. - var firstPacket = parent.Queue.First(); + var firstPacket = Parent.Queue.First(); if (trySubmitFirstPacket.Invoke(firstPacket) == PacketSubmitResult.Accepted) { - parent.Queue.Remove(firstPacket); + Parent.Queue.Remove(firstPacket); } // Otherwise, just don't do anything :-) @@ -105,9 +105,9 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) { // Build a new packet that just contains the leftover bytes and put it into the queue. - lock (parent.queueLock) + lock (Parent.queueLock) { - parent.Queue.Insert(0, new PriorityPacket(parent.Priority, leftoverBytes)); + Parent.Queue.Insert(0, new PriorityPacket(Parent.Priority, leftoverBytes)); } } @@ -115,10 +115,10 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { } - public override void TransmissionStarted(double bytesPerSecondRate) + public override void TransmissionStarted(long bytesPerSecondRate) { // Just write some log. - Debug.WriteLine($"Packet of Queue {parent.Priority} has started transmission with {bytesPerSecondRate} bytes/s."); + Debug.WriteLine($"Packet of Queue {Parent.Priority} has started transmission with {bytesPerSecondRate} bytes/s."); } } @@ -132,7 +132,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override void Initialize() { - parent.StartCreditThread(parent.IdleSlope); + Parent.StartCreditThread(Parent.IdleSlope); } public override void GateClosed() @@ -143,7 +143,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) { // Try to submit first packet. - lock (parent.queueLock) + lock (Parent.queueLock) { if (!CanSend()) @@ -151,18 +151,18 @@ namespace CBSVisualizer.Modules.Queue.ViewModels return; } - var firstPacket = parent.Queue.First(); + var firstPacket = Parent.Queue.First(); var submitResult = trySubmitFirstPacket.Invoke(firstPacket); // If the packet was accepted, remove it from the queue. if (submitResult == PacketSubmitResult.Accepted) { - parent.Queue.Remove(firstPacket); + Parent.Queue.Remove(firstPacket); // If my packet was denied due to pre-closing, freeze my credit. } else if (submitResult == PacketSubmitResult.DeniedPreClosing) { - parent.StopCreditThread(); + Parent.StopCreditThread(); } } @@ -172,24 +172,24 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) { // Put the leftovers of the packet back into the queue. - lock (parent.queueLock) + lock (Parent.queueLock) { - parent.Queue.Insert(0, new PriorityPacket(parent.Priority, leftoverBytes)); + Parent.Queue.Insert(0, new PriorityPacket(Parent.Priority, leftoverBytes)); } } public override void TransmissionCompleted() { // Stop and restart the credit thread. - parent.StopCreditThread(); - parent.StartCreditThread(parent.IdleSlope); + Parent.StopCreditThread(); + Parent.StartCreditThread(Parent.IdleSlope); } - public override void TransmissionStarted(double bytesPerSecondRate) + public override void TransmissionStarted(long bytesPerSecondRate) { // Decrease the credit by the idle slope. - parent.StopCreditThread(); - parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); + Parent.StopCreditThread(); + Parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); } } @@ -203,19 +203,19 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override void Initialize() { - parent.StartCreditThread(parent.IdleSlope); + Parent.StartCreditThread(Parent.IdleSlope); } public override void GateClosed() { // Stop the credit growth thread. - parent.StopCreditThread(); + Parent.StopCreditThread(); } public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) { // Start the credit - lock (parent.queueLock) + lock (Parent.queueLock) { // Don't do anything when there are no packets. if (!CanSend()) @@ -224,34 +224,34 @@ namespace CBSVisualizer.Modules.Queue.ViewModels } // Otherwise, once again try to send the first packet. - var firstPacket = parent.Queue.First(); + var firstPacket = Parent.Queue.First(); if (trySubmitFirstPacket.Invoke(firstPacket) == PacketSubmitResult.Accepted) { - parent.Queue.Remove(firstPacket); + Parent.Queue.Remove(firstPacket); } } } public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) { - lock (parent.queueLock) + lock (Parent.queueLock) { - parent.Queue.Insert(0, new PriorityPacket(parent.Priority, leftoverBytes)); + Parent.Queue.Insert(0, new PriorityPacket(Parent.Priority, leftoverBytes)); } } public override void TransmissionCompleted() { Log.Info("TransmissionCompleted"); - parent.StopCreditThread(); - parent.StartCreditThread(parent.IdleSlope); + Parent.StopCreditThread(); + Parent.StartCreditThread(Parent.IdleSlope); } - public override void TransmissionStarted(double bytesPerSecondRate) + public override void TransmissionStarted(long bytesPerSecondRate) { Log.Info("TransmissionStarted"); - parent.StopCreditThread(); - parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); + Parent.StopCreditThread(); + Parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); } } @@ -264,7 +264,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override void Initialize() { - parent.StartCreditThread(parent.IdleSlope); + Parent.StartCreditThread(Parent.IdleSlope); } public override void GateClosed() @@ -274,7 +274,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) { - lock (parent.queueLock) + lock (Parent.queueLock) { // Again, check if we can submit anything. if (!CanSend()) @@ -282,38 +282,38 @@ namespace CBSVisualizer.Modules.Queue.ViewModels return; } - var firstPacket = parent.Queue.First(); + var firstPacket = Parent.Queue.First(); var submitResult = trySubmitFirstPacket.Invoke(firstPacket); if (submitResult == PacketSubmitResult.Accepted) { - parent.Queue.Remove(firstPacket); + Parent.Queue.Remove(firstPacket); } else if (submitResult == PacketSubmitResult.DeniedPreClosing) // In the pre-closing case, we signal the thread to increase our credit to zero. { - parent.StopCreditThread(); - parent.StartCreditThread(parent.IdleSlope, 0); + Parent.StopCreditThread(); + Parent.StartCreditThread(Parent.IdleSlope, 0); } } } public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) { - lock (parent.queueLock) + lock (Parent.queueLock) { - parent.Queue.Insert(0, new PriorityPacket(GetPriority(), leftoverBytes)); + Parent.Queue.Insert(0, new PriorityPacket(GetPriority(), leftoverBytes)); } } public override void TransmissionCompleted() { - parent.StopCreditThread(); - parent.StartCreditThread(parent.IdleSlope, 0); + Parent.StopCreditThread(); + Parent.StartCreditThread(Parent.IdleSlope, 0); } - public override void TransmissionStarted(double bytesPerSecondRate) + public override void TransmissionStarted(long bytesPerSecondRate) { - parent.StopCreditThread(); - parent.StartCreditThread(GetSendSlope(bytesPerSecondRate), 0); + Parent.StopCreditThread(); + Parent.StartCreditThread(GetSendSlope(bytesPerSecondRate), 0); } } } diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs index 2e2dc0f..b33fa8a 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs @@ -21,7 +21,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { private const int ThreadJoinTimeoutS = 5; - private const double CreditRefreshRateS = 1; + private const long CreditRefreshRateS = 1; private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod()?.DeclaringType); @@ -31,6 +31,8 @@ namespace CBSVisualizer.Modules.Queue.ViewModels private readonly object queueLock = new object(); + private readonly object creditLock = new object(); + private CancellationTokenSource creditGrowthCancellationSource; private CreditBehaviour selectedCreditBehaviour; @@ -42,13 +44,25 @@ namespace CBSVisualizer.Modules.Queue.ViewModels set => SetProperty(ref selectedCreditBehaviour, value); } - private double currentCredit = 0; + private long currentCredit; - public double CurrentCredit + public long CurrentCredit { - get => currentCredit; + get + { + lock (creditLock) + { + return currentCredit; + } + } - private set => SetProperty(ref currentCredit, value); + private set + { + lock (creditLock) + { + SetProperty(ref currentCredit, value); + } + } } private Thread creditUpdateThread; @@ -146,7 +160,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels case CreditBehaviour.Standard: return new StandardLinkCallback(this); - + // Default is no CBS. case CreditBehaviour.NoCbs: default: return new NoCbsLinkCallback(this); @@ -165,11 +179,11 @@ namespace CBSVisualizer.Modules.Queue.ViewModels StopCreditThread(); // Reset credit. - currentCredit = 0; + CurrentCredit = 0; }); } - private void StartCreditThread(double bytesPerSecondSlope, double limit = double.PositiveInfinity) + private void StartCreditThread(long bytesPerSecondSlope, long limit = long.MaxValue) { // Init new cancellation token. creditGrowthCancellationSource = new CancellationTokenSource(); @@ -177,9 +191,19 @@ namespace CBSVisualizer.Modules.Queue.ViewModels creditUpdateThread = new Thread(() => { Log.Info($"Queue {Priority}: Credit Thread was started with {bytesPerSecondSlope} bytes/s slope."); - while (!creditGrowthCancellationSource.Token.IsCancellationRequested && CurrentCredit < limit && - Queue.Count > 0) + while (!creditGrowthCancellationSource.Token.IsCancellationRequested) { + lock (queueLock) + { + lock (creditLock) + { + if (CurrentCredit > limit || Queue.Count <= 0) + { + return; + } + } + } + // Wait for the specified amount of time. Thread.Sleep(TimeSpan.FromSeconds(CreditRefreshRateS)); @@ -201,11 +225,13 @@ namespace CBSVisualizer.Modules.Queue.ViewModels : $"Queue {Priority}: Credit Thread was stopped successfully."); } - private void AtomicUpdateCredit(double increment, double limit) + private void AtomicUpdateCredit(long increment, long limit) { - Interlocked.Exchange(ref currentCredit, Math.Min(currentCredit + increment, limit)); + // Update the credit. + CurrentCredit = Math.Min(CurrentCredit + increment, limit); - Series[0].Values.Add(new DateTimePoint(DateTime.Now, currentCredit)); + // Add the new value to the series. + Series[0].Values.Add(new DateTimePoint(DateTime.Now, CurrentCredit)); } private void RegisterPacketHandler() -- GitLab From d0ba462ab3671041e842bf9e6af015e7aaa739ab Mon Sep 17 00:00:00 2001 From: Dmitrii Cetvericov <d.cetvericov@live.de> Date: Mon, 14 Sep 2020 21:13:47 +0200 Subject: [PATCH 17/17] Standard Credit Behaviour seems to do something nice :-) I guess this is a good moment to merge to master. --- .../QueueViewModel.LinkCallbacks.cs | 136 +++++++++++------- .../ViewModels/QueueViewModel.cs | 21 +-- 2 files changed, 96 insertions(+), 61 deletions(-) diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs index 611f353..5053171 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.LinkCallbacks.cs @@ -3,7 +3,6 @@ using CBSVisualizer.Messaging.Events; using System; using System.Diagnostics; using System.Linq; -using System.Threading.Tasks; namespace CBSVisualizer.Modules.Queue.ViewModels { @@ -56,6 +55,40 @@ namespace CBSVisualizer.Modules.Queue.ViewModels } } + + protected void TrySendPacket(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket, Action<PriorityPacket> additionalAcceptedAction, + Action<PriorityPacket> deniedPreClosingAction, Action<PriorityPacket> deniedHigherPrioAction) + { + lock (Parent.queueLock) + { + lock (Parent.creditLock) + { + if (Parent.Queue.Count <= 0 || Parent.CurrentCredit < 0) + { + return; + } + + var firstPacket = Parent.Queue.First(); + + switch (trySubmitFirstPacket.Invoke(firstPacket)) + { + case PacketSubmitResult.Accepted: + Parent.Queue.Remove(firstPacket); + additionalAcceptedAction?.Invoke(firstPacket); + break; + + case PacketSubmitResult.DeniedHigherPrio: + deniedHigherPrioAction?.Invoke(firstPacket); + break; + + case PacketSubmitResult.DeniedPreClosing: + deniedPreClosingAction?.Invoke(firstPacket); + break; + } + } + } + } + public abstract void GateClosed(); public abstract void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket); @@ -67,6 +100,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public abstract void TransmissionStarted(long bytesPerSecondRate); } + #region NoCbsLinkCallback private class NoCbsLinkCallback : LinkCallbackBase { public NoCbsLinkCallback(QueueViewModel parent) @@ -85,7 +119,7 @@ namespace CBSVisualizer.Modules.Queue.ViewModels lock (Parent.queueLock) { // If the queue is empty, return. - if (!CanSend()) + if (Parent.Queue.Count <= 0) { return; } @@ -111,22 +145,24 @@ namespace CBSVisualizer.Modules.Queue.ViewModels } } - public override void TransmissionCompleted() - { - } - public override void TransmissionStarted(long bytesPerSecondRate) { // Just write some log. Debug.WriteLine($"Packet of Queue {Parent.Priority} has started transmission with {bytesPerSecondRate} bytes/s."); } + + public override void TransmissionCompleted() + { + // Nothing to be done. + } } + #endregion - private class FrozenLinkCallback : LinkCallbackBase + #region StandardLinkCallback + private class StandardLinkCallback : LinkCallbackBase { - - public FrozenLinkCallback(QueueViewModel parent) - : base(parent) + public StandardLinkCallback(QueueViewModel parentViewModel) + : base(parentViewModel) { } @@ -137,41 +173,21 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override void GateClosed() { - // Nothing special happens here. The credit handling is done in the GateOpened method. + // Stop the credit thread. + Parent.StopCreditThread(); } public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) { - // Try to submit first packet. - lock (Parent.queueLock) - { - - if (!CanSend()) - { - return; - } - - var firstPacket = Parent.Queue.First(); - var submitResult = trySubmitFirstPacket.Invoke(firstPacket); - - // If the packet was accepted, remove it from the queue. - if (submitResult == PacketSubmitResult.Accepted) - { - Parent.Queue.Remove(firstPacket); - - // If my packet was denied due to pre-closing, freeze my credit. - } else if (submitResult == PacketSubmitResult.DeniedPreClosing) - { - Parent.StopCreditThread(); - } - } + // Start the credit thread + Parent.StartCreditThread(Parent.IdleSlope); - // Otherwise, just let the credit grow for now. + // Try to send the packet if we can. + TrySendPacket(trySubmitFirstPacket, null, null, null); } public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) { - // Put the leftovers of the packet back into the queue. lock (Parent.queueLock) { Parent.Queue.Insert(0, new PriorityPacket(Parent.Priority, leftoverBytes)); @@ -180,24 +196,25 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override void TransmissionCompleted() { - // Stop and restart the credit thread. + Log.Info("Transmission Completed"); Parent.StopCreditThread(); Parent.StartCreditThread(Parent.IdleSlope); } public override void TransmissionStarted(long bytesPerSecondRate) { - // Decrease the credit by the idle slope. + Log.Info("TransmissionStarted"); Parent.StopCreditThread(); Parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); } } + #endregion - private class StandardLinkCallback : LinkCallbackBase + #region FrozenLinkCallback + private class FrozenLinkCallback : LinkCallbackBase { - - public StandardLinkCallback(QueueViewModel parentViewModel) - : base(parentViewModel) + public FrozenLinkCallback(QueueViewModel parent) + : base(parent) { } @@ -208,32 +225,41 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override void GateClosed() { - // Stop the credit growth thread. - Parent.StopCreditThread(); + // Nothing special happens here. The credit handling is done in the GateOpened method. } public override void GateOpened(Func<PriorityPacket, PacketSubmitResult> trySubmitFirstPacket) { - // Start the credit + // Try to submit first packet. lock (Parent.queueLock) { - // Don't do anything when there are no packets. if (!CanSend()) { return; } - // Otherwise, once again try to send the first packet. var firstPacket = Parent.Queue.First(); - if (trySubmitFirstPacket.Invoke(firstPacket) == PacketSubmitResult.Accepted) + var submitResult = trySubmitFirstPacket.Invoke(firstPacket); + + // If the packet was accepted, remove it from the queue. + if (submitResult == PacketSubmitResult.Accepted) { Parent.Queue.Remove(firstPacket); + + // If my packet was denied due to pre-closing, freeze my credit. + } + else if (submitResult == PacketSubmitResult.DeniedPreClosing) + { + Parent.StopCreditThread(); } } + + // Otherwise, just let the credit grow for now. } public override void PacketPreempted(PriorityPacket preemptedPacket, int leftoverBytes) { + // Put the leftovers of the packet back into the queue. lock (Parent.queueLock) { Parent.Queue.Insert(0, new PriorityPacket(Parent.Priority, leftoverBytes)); @@ -242,23 +268,25 @@ namespace CBSVisualizer.Modules.Queue.ViewModels public override void TransmissionCompleted() { - Log.Info("TransmissionCompleted"); + // Stop and restart the credit thread. Parent.StopCreditThread(); Parent.StartCreditThread(Parent.IdleSlope); } public override void TransmissionStarted(long bytesPerSecondRate) { - Log.Info("TransmissionStarted"); + // Decrease the credit by the idle slope. Parent.StopCreditThread(); Parent.StartCreditThread(GetSendSlope(bytesPerSecondRate)); } } + #endregion + #region ReturnToZeroLinkCallback private class ReturnToZeroLinkCallback : LinkCallbackBase { public ReturnToZeroLinkCallback(QueueViewModel parentViewModel) - :base(parentViewModel) + : base(parentViewModel) { } @@ -288,7 +316,8 @@ namespace CBSVisualizer.Modules.Queue.ViewModels if (submitResult == PacketSubmitResult.Accepted) { Parent.Queue.Remove(firstPacket); - } else if (submitResult == PacketSubmitResult.DeniedPreClosing) // In the pre-closing case, we signal the thread to increase our credit to zero. + } + else if (submitResult == PacketSubmitResult.DeniedPreClosing) // In the pre-closing case, we signal the thread to increase our credit to zero. { Parent.StopCreditThread(); Parent.StartCreditThread(Parent.IdleSlope, 0); @@ -316,5 +345,6 @@ namespace CBSVisualizer.Modules.Queue.ViewModels Parent.StartCreditThread(GetSendSlope(bytesPerSecondRate), 0); } } + #endregion } -} +} \ No newline at end of file diff --git a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs index b33fa8a..e3b9186 100644 --- a/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs +++ b/CBSVisualizer/CBSVisualizer.Modules.Queue/ViewModels/QueueViewModel.cs @@ -19,9 +19,9 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { public partial class QueueViewModel : RegionViewModelBase { - private const int ThreadJoinTimeoutS = 5; + private const int ThreadJoinTimeoutS = 1; - private const long CreditRefreshRateS = 1; + private const long CreditRefreshRateS = 5; private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod()?.DeclaringType); @@ -120,6 +120,11 @@ namespace CBSVisualizer.Modules.Queue.ViewModels private void QueueChangedHandler(object sender, NotifyCollectionChangedEventArgs e) { + // Add the new value to the series. + if (selectedCreditBehaviour != CreditBehaviour.NoCbs) + { + Series[0].Values.Add(new DateTimePoint(DateTime.Now, CurrentCredit)); + } Series[1].Values.Add(new DateTimePoint(DateTime.Now, Queue.Count)); } @@ -220,18 +225,18 @@ namespace CBSVisualizer.Modules.Queue.ViewModels { creditGrowthCancellationSource?.Cancel(); - Log.Info(creditUpdateThread.Join(TimeSpan.FromSeconds(ThreadJoinTimeoutS)) - ? $"Queue {Priority}: Unable to stop credit thread." - : $"Queue {Priority}: Credit Thread was stopped successfully."); + if (creditUpdateThread != null) + { + Log.Info(creditUpdateThread.Join(TimeSpan.FromSeconds(ThreadJoinTimeoutS)) + ? $"Queue {Priority}: Unable to stop credit thread." + : $"Queue {Priority}: Credit Thread was stopped successfully."); + } } private void AtomicUpdateCredit(long increment, long limit) { // Update the credit. CurrentCredit = Math.Min(CurrentCredit + increment, limit); - - // Add the new value to the series. - Series[0].Values.Add(new DateTimePoint(DateTime.Now, CurrentCredit)); } private void RegisterPacketHandler() -- GitLab