aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2018-02-06 19:46:56 +0200
committerRoy Ben-Shabat <Roy@Twine-s.com>2018-02-06 19:46:56 +0200
commita37d0e9c9203d680bf63698cf9d47447a57b5684 (patch)
tree0547105ad8973076ddc558f6e5afdd192b86f7b3 /Software/Visual_Studio
parent198a620cf30e86158c60cb632df740ca94b73b57 (diff)
downloadTango-a37d0e9c9203d680bf63698cf9d47447a57b5684.tar.gz
Tango-a37d0e9c9203d680bf63698cf9d47447a57b5684.zip
Diagnostics Data Playing Works!
Diffstat (limited to 'Software/Visual_Studio')
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs163
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml29
-rw-r--r--Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFilePlayer.cs224
-rw-r--r--Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileRecorder.cs8
-rw-r--r--Software/Visual_Studio/Tango.Integration/Diagnostics/TimeCodeChannelFrame.cs7
-rw-r--r--Software/Visual_Studio/Tango.Integration/Printing/BrushStop.cs14
-rw-r--r--Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj1
-rw-r--r--Software/Visual_Studio/Tango.Serialization/BinaryDataSerializer.cs17
8 files changed, 417 insertions, 46 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs
index edc6274c3..2ca3d215e 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs
@@ -55,6 +55,16 @@ namespace Tango.MachineStudio.Developer.ViewModels
set { _recorder = value; RaisePropertyChangedAuto(); }
}
+ private DiagnosticsFilePlayer _player;
+ /// <summary>
+ /// Gets or sets the diagnostics file player.
+ /// </summary>
+ public DiagnosticsFilePlayer Player
+ {
+ get { return _player; }
+ set { _player = value; RaisePropertyChangedAuto(); }
+ }
+
/// <summary>
/// Gets or sets the application manager.
/// </summary>
@@ -443,6 +453,16 @@ namespace Tango.MachineStudio.Developer.ViewModels
/// </summary>
public RelayCommand MediaLoadFileCommand { get; set; }
+ /// <summary>
+ /// Gets or sets the media play pause command.
+ /// </summary>
+ public RelayCommand MediaPlayPauseCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the media load command.
+ /// </summary>
+ public RelayCommand MediaLoadCommand { get; set; }
+
#endregion
#region Constructors
@@ -461,6 +481,7 @@ namespace Tango.MachineStudio.Developer.ViewModels
Graphs = new ObservableCollection<IRealTimeGraph>();
_controllers = new Dictionary<String, GraphControllerBase>();
Recorder = new DiagnosticsFileRecorder();
+ Player = new DiagnosticsFilePlayer();
}
/// <summary>
@@ -491,8 +512,10 @@ namespace Tango.MachineStudio.Developer.ViewModels
StopJobCommand = new RelayCommand(StopJob, () => IsJobRunning);
CloseJobCompletionStatusCommand = new RelayCommand(CloseJobCompletionStatusBar);
ExitFullScreenCommand = new RelayCommand(ExitFullScreen);
- MediaRecordingCommand = new RelayCommand(StartDiagnosticsRecording, () => !Recorder.IsRecording && MachineOperator != null);
- MediaStopCommand = new RelayCommand(StopRecorderOrPlayer, () => Recorder.IsRecording);
+ MediaRecordingCommand = new RelayCommand(StartDiagnosticsRecording, () => !Recorder.IsRecording && MachineOperator != null && !Player.IsPlaying);
+ MediaStopCommand = new RelayCommand(StopRecorderOrPlayer, () => Recorder.IsRecording || Player.IsPlaying);
+ MediaLoadCommand = new RelayCommand(LoadDiagnosticsRecordingFile,() => !Recorder.IsRecording && !Player.IsPlaying);
+ MediaPlayPauseCommand = new RelayCommand(DiagnosticsTogglePlayPause,() => !Recorder.IsRecording && Player.IsLoaded);
CaptureDevices = new ObservableCollection<CaptureDevice>();
var availableDevices = CaptureDevice.GetAvailableCaptureDevices();
@@ -518,6 +541,11 @@ namespace Tango.MachineStudio.Developer.ViewModels
#region Event Handlers
+ private void Player_FrameReceived(object sender, DataFileFrame frame)
+ {
+ PopulateDiagnosticsData(frame.PushDiagnosticsResponse);
+ }
+
private void ApplicationManager_ConnectedMachineChanged(object sender, Integration.Services.IExternalBridgeClient machine)
{
MachineOperator = machine;
@@ -536,27 +564,12 @@ namespace Tango.MachineStudio.Developer.ViewModels
Recorder.PushData(response);
}
- foreach (var prop in response.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
+ if (!Player.IsPlaying)
{
- GraphControllerBase controller = null;
-
- if (_controllers.TryGetValue(prop.Name, out controller))
- {
- if (controller is GraphController)
- {
- double[] arr = Enumerable.ToArray(prop.GetValue(response) as IEnumerable<double>);
- (controller as GraphController).PushData(arr);
- }
- else
- {
- DoubleArray[] arrayOfDoubles = Enumerable.ToArray(prop.GetValue(response) as IEnumerable<DoubleArray>);
- (controller as GraphMultiController).PushData(arrayOfDoubles.Select(x => x.Data.ToList()).ToList());
- }
- }
+ PopulateDiagnosticsData(response);
}
}
-
/// <summary>
/// Handles the Saved event of the SelectedMachine.
/// </summary>
@@ -665,6 +678,74 @@ namespace Tango.MachineStudio.Developer.ViewModels
#region Private Methods
+ private void ClearGraphs()
+ {
+ _controllers.ToList().ForEach(x => x.Value.Clear());
+ }
+
+ private void PopulateDiagnosticsData(PushDiagnosticsResponse data)
+ {
+ foreach (var prop in data.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
+ {
+ GraphControllerBase controller = null;
+
+ if (_controllers.TryGetValue(prop.Name, out controller))
+ {
+ if (controller is GraphController)
+ {
+ double[] arr = Enumerable.ToArray(prop.GetValue(data) as IEnumerable<double>);
+ (controller as GraphController).PushData(arr);
+ }
+ else
+ {
+ DoubleArray[] arrayOfDoubles = Enumerable.ToArray(prop.GetValue(data) as IEnumerable<DoubleArray>);
+ (controller as GraphMultiController).PushData(arrayOfDoubles.Select(x => x.Data.ToList()).ToList());
+ }
+ }
+ }
+ }
+
+ private void DiagnosticsTogglePlayPause()
+ {
+ if (!Player.IsPlaying || Player.IsPaused)
+ {
+ if (!Player.IsPlaying)
+ {
+ ClearGraphs();
+ }
+ Player.Play();
+ }
+ else
+ {
+ Player.Pause();
+ }
+
+ InvalidateRelayCommands();
+ }
+
+ private async void LoadDiagnosticsRecordingFile()
+ {
+ OpenFileDialog dlg = new OpenFileDialog();
+ dlg.Title = "Select Tango Diagnostics Recording File";
+ dlg.Filter = "Tango Diagnostics Recording|*.tdr";
+ if (dlg.ShowDialog().Value)
+ {
+ using (_notification.PushTaskItem("Loading Recording..."))
+ {
+ if (Player != null)
+ {
+ Player.Dispose();
+ }
+
+ Player = new DiagnosticsFilePlayer();
+ Player.FrameReceived += Player_FrameReceived;
+ await Player.Load(dlg.FileName);
+ }
+ }
+
+ InvalidateRelayCommands();
+ }
+
private void StartDiagnosticsRecording()
{
using (_notification.PushTaskItem("Starting Recording..."))
@@ -677,24 +758,34 @@ namespace Tango.MachineStudio.Developer.ViewModels
private async void StopRecorderOrPlayer()
{
- using (_notification.PushTaskItem("Stopping Recording..."))
+ if (Recorder.IsRecording)
{
- await Recorder.Stop();
- }
+ using (_notification.PushTaskItem("Stopping Recording..."))
+ {
+ await Recorder.Stop();
+ }
- SaveFileDialog dlg = new SaveFileDialog();
- dlg.Title = "Select diagnostics file location";
- dlg.Filter = "Tango Diagnostics Recording|*.tdr";
- if (dlg.ShowDialog().Value)
- {
- using (_notification.PushTaskItem("Saving Recording..."))
+ SaveFileDialog dlg = new SaveFileDialog();
+ dlg.Title = "Select diagnostics file location";
+ dlg.Filter = "Tango Diagnostics Recording|*.tdr";
+ if (dlg.ShowDialog().Value)
{
- await Recorder.Save(dlg.FileName);
+ using (_notification.PushTaskItem("Saving Recording..."))
+ {
+ await Recorder.Save(dlg.FileName);
+ }
}
+
+ Recorder.Dispose();
+ Recorder = new DiagnosticsFileRecorder();
+ }
+ else if (Player.IsPlaying)
+ {
+ await Player.Stop();
+ ClearGraphs();
}
- Recorder.Dispose();
- Recorder = new DiagnosticsFileRecorder();
+ InvalidateRelayCommands();
}
private void ExitFullScreen()
@@ -986,6 +1077,13 @@ namespace Tango.MachineStudio.Developer.ViewModels
if (SelectedBrushStop != null && SelectedSegment != null)
{
SelectedSegment.BrushStops.Remove(SelectedBrushStop);
+
+ if (SelectedSegment.BrushStops.Count > 1)
+ {
+ SelectedSegment.BrushStops.Last().OffsetPercent = 100;
+ }
+
+ SelectedSegment.BrushStops.ToList().ForEach(x => x.RaiseOffsetChanged());
}
}
@@ -997,10 +1095,13 @@ namespace Tango.MachineStudio.Developer.ViewModels
if (SelectedSegment != null)
{
var stop = new BrushStop();
+ stop.OffsetPercent = 100;
+ stop.Segment = SelectedSegment;
stop.ColorSpace = Adapter.ColorSpaces.FirstOrDefault();
stop.Color = Colors.Black;
stop.SetLiquidVolumes(SelectedMachine.Configuration, SelectedRML, SelectedProcessParametersTable);
SelectedSegment.BrushStops.Add(stop);
+ SelectedSegment.BrushStops.ToList().ForEach(x => x.RaiseOffsetChanged());
}
}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml
index 33652f119..820c5bb18 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MainView.xaml
@@ -1608,22 +1608,36 @@
<DockPanel>
<DockPanel DockPanel.Dock="Top">
<StackPanel Orientation="Horizontal" DockPanel.Dock="Left" Height="50" VerticalAlignment="Bottom" Margin="0 0 0 5">
- <Button Style="{StaticResource MaterialDesignFloatingActionButton}" Padding="0" Width="28" Height="28" Background="Transparent" ToolTip="Load Data File">
+ <Button Command="{Binding MediaLoadCommand}" Style="{StaticResource MaterialDesignFloatingActionButton}" Padding="0" Width="28" Height="28" Background="Transparent" ToolTip="Load Data File">
<materialDesign:PackIcon Width="20" Height="20" Kind="Eject" Foreground="{StaticResource AccentColorBrush}" />
</Button>
- <Button Margin="5 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Padding="0" Width="35" Height="35" Background="Transparent">
- <materialDesign:PackIcon Width="20" Height="20" Kind="Play" Foreground="{StaticResource AccentColorBrush}" />
+ <Button Command="{Binding MediaPlayPauseCommand}" Margin="5 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Padding="0" Width="35" Height="35" Background="Transparent">
+ <materialDesign:PackIcon Width="20" Height="20" Foreground="{StaticResource AccentColorBrush}">
+ <materialDesign:PackIcon.Style>
+ <Style TargetType="materialDesign:PackIcon">
+ <Setter Property="Kind" Value="Play"></Setter>
+ <Style.Triggers>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding Player.IsPlaying}" Value="True" />
+ <Condition Binding="{Binding Player.IsPaused}" Value="False" />
+ </MultiDataTrigger.Conditions>
+ <Setter Property="Kind" Value="Pause"></Setter>
+ </MultiDataTrigger>
+ </Style.Triggers>
+ </Style>
+ </materialDesign:PackIcon.Style>
+ </materialDesign:PackIcon>
</Button>
<Button Command="{Binding MediaStopCommand}" Margin="5 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Padding="0" Width="28" Height="28" Background="Transparent">
<materialDesign:PackIcon Width="20" Height="20" Kind="Stop" Foreground="{StaticResource AccentColorBrush}" />
</Button>
<Button Command="{Binding MediaRecordingCommand}" Margin="5 0 0 0" Style="{StaticResource MaterialDesignFloatingActionButton}" Foreground="#FF7A7A" BorderBrush="#FF8585" Padding="0" Width="20" Height="20" Background="Transparent" ToolTip="Start Recording">
-
<materialDesign:PackIcon Width="10" Height="10" Kind="Record" />
</Button>
</StackPanel>
<Grid>
- <TextBlock Text="00:00:00 / 00:00:00" Margin="0 -5 0 0" VerticalAlignment="Center" HorizontalAlignment="Right" Foreground="#FF8585" FontSize="20" FontFamily="{StaticResource digital-7}">
+ <TextBlock Margin="0 -5 0 0" VerticalAlignment="Center" HorizontalAlignment="Right" Foreground="#FF8585" FontSize="20" FontFamily="{StaticResource digital-7}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Opacity" Value="1"></Setter>
@@ -1652,11 +1666,14 @@
</Style.Triggers>
</Style>
</TextBlock.Style>
+ <Run Text="{Binding Player.CurrentTime,Mode=OneWay,StringFormat=hh\\:mm\\:ss,FallbackValue='00:00:00'}"/>
+ <Run>/</Run>
+ <Run Text="{Binding Player.TotalTime,Mode=OneWay,StringFormat=hh\\:mm\\:ss,FallbackValue='00:00:00'}"/>
</TextBlock>
</Grid>
</DockPanel>
<Grid>
- <Slider Visibility="{Binding Recorder.IsRecording,Converter={StaticResource BooleanToVisibilityInverseConverter}}"></Slider>
+ <Slider Visibility="{Binding Recorder.IsRecording,Converter={StaticResource BooleanToVisibilityInverseConverter}}" Maximum="{Binding Player.TotalFrames}" Value="{Binding Player.CurrentFrame}"></Slider>
<DockPanel Visibility="{Binding Recorder.IsRecording,Converter={StaticResource BooleanToVisibilityConverter}}">
<TextBlock DockPanel.Dock="Left">
<Run FontWeight="SemiBold" FontStyle="Italic">Total Frames:</Run>
diff --git a/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFilePlayer.cs b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFilePlayer.cs
new file mode 100644
index 000000000..463aecc06
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFilePlayer.cs
@@ -0,0 +1,224 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.PMR.Diagnostics;
+using Tango.Serialization;
+
+namespace Tango.Integration.Diagnostics
+{
+ public class DiagnosticsFilePlayer : ExtendedObject, IDisposable
+ {
+ private FileStream _dataFileStream;
+ private TimeCodeChannel _timeCodeChannel;
+ private long _diagnosticsDataOffset;
+ private Thread _playThread;
+ private TaskCompletionSource<object> _stopTaskSource;
+
+ public event EventHandler<DataFileFrame> FrameReceived;
+
+ private bool _isLoaded;
+ public bool IsLoaded
+ {
+ get { return _isLoaded; }
+ private set { _isLoaded = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isPlaying;
+ public bool IsPlaying
+ {
+ get { return _isPlaying; }
+ private set { _isPlaying = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isPaused;
+ public bool IsPaused
+ {
+ get { return _isPaused; }
+ set { _isPaused = value; RaisePropertyChangedAuto(); }
+ }
+
+ private TimeSpan _currentTime;
+ public TimeSpan CurrentTime
+ {
+ get { return _currentTime; }
+ private set { _currentTime = value; RaisePropertyChanged(nameof(CurrentTime)); }
+ }
+
+ private TimeSpan _totalTime;
+ public TimeSpan TotalTime
+ {
+ get { return _totalTime; }
+ set { _totalTime = value; RaisePropertyChangedAuto(); }
+ }
+
+ private int _currentFrame;
+ public int CurrentFrame
+ {
+ get { return _currentFrame; }
+ set
+ {
+ _currentFrame = value;
+
+ OnCurrentFrameChanged();
+
+ RaisePropertyChanged(nameof(CurrentFrame));
+ }
+ }
+
+ private long _totalFrames;
+ public long TotalFrames
+ {
+ get { return _totalFrames; }
+ private set { _totalFrames = value; RaisePropertyChangedAuto(); }
+ }
+
+ public Task Load(String fileName)
+ {
+ return Task.Factory.StartNew(() =>
+ {
+ if (_dataFileStream != null)
+ {
+ _dataFileStream.Dispose();
+ }
+
+ _dataFileStream = new FileStream(fileName, FileMode.Open);
+
+ BinaryReader binaryReader = new BinaryReader(_dataFileStream);
+
+ int timeCodeDataSize = binaryReader.ReadInt32();
+ byte[] timeCodeData = binaryReader.ReadBytes(timeCodeDataSize);
+
+ BinaryDataSerializer serializer = new BinaryDataSerializer();
+ _timeCodeChannel = serializer.DeserializeFromBytes<TimeCodeChannel>(timeCodeData);
+
+ _diagnosticsDataOffset = _dataFileStream.Position;
+
+ CurrentFrame = 0;
+ TotalFrames = _timeCodeChannel.Frames.Count;
+ TotalTime = _timeCodeChannel.Frames.Last().TimeStamp;
+
+ IsLoaded = true;
+ });
+ }
+
+ public void Seek(int frameIndex)
+ {
+ if (frameIndex < 0)
+ {
+ frameIndex = 0;
+ }
+ else if (frameIndex > TotalFrames - 1)
+ {
+ frameIndex = (int)(TotalFrames - 1);
+ }
+
+ CurrentFrame = frameIndex;
+ }
+
+ public void Play()
+ {
+ IsPaused = false;
+
+ if (!IsPlaying)
+ {
+ IsPlaying = true;
+ _playThread = new Thread(PlayThreadMethod);
+ _playThread.IsBackground = true;
+ _playThread.Start();
+ }
+ }
+
+ private void OnCurrentFrameChanged()
+ {
+ if (IsPlaying)
+ {
+ if (_currentFrame > _timeCodeChannel.Frames.Count - 1)
+ {
+ _currentFrame = _timeCodeChannel.Frames.Count - 1;
+ }
+
+ if (_dataFileStream != null && _dataFileStream.CanSeek)
+ {
+ _dataFileStream.Position = _diagnosticsDataOffset + _timeCodeChannel.Frames[_currentFrame].Position;
+ }
+
+ byte[] data = new byte[_timeCodeChannel.Frames[_currentFrame].FrameLength];
+ _dataFileStream.Read(data, 0, data.Length);
+ DataFileFrame frame = DataFileFrame.Parser.ParseFrom(data);
+ OnFrameReceived(frame);
+ data = null;
+ }
+
+ if (_timeCodeChannel != null)
+ {
+ CurrentTime = _timeCodeChannel.Frames[_currentFrame].TimeStamp;
+ }
+ }
+
+ private void PlayThreadMethod()
+ {
+ while (IsPlaying)
+ {
+ if (!IsPaused)
+ {
+ CurrentFrame++;
+
+ if (CurrentFrame >= TotalFrames - 1)
+ {
+ CurrentFrame = 0;
+ }
+ }
+
+ if (CurrentFrame > 0)
+ {
+ Thread.Sleep(_timeCodeChannel.Frames[CurrentFrame].TimeStamp - _timeCodeChannel.Frames[CurrentFrame - 1].TimeStamp);
+ }
+ else
+ {
+ Thread.Sleep(10);
+ }
+ }
+
+ CurrentFrame = 0;
+ CurrentTime = TimeSpan.Zero;
+
+ _stopTaskSource.SetResult(new object());
+ }
+
+ public Task Stop()
+ {
+ _stopTaskSource = new TaskCompletionSource<object>();
+ IsPlaying = false;
+ IsPaused = false;
+ return _stopTaskSource.Task;
+ }
+
+ public void Pause()
+ {
+ if (IsPlaying)
+ {
+ IsPaused = true;
+ }
+ }
+
+ protected virtual void OnFrameReceived(DataFileFrame frame)
+ {
+ FrameReceived?.Invoke(this, frame);
+ }
+
+ public void Dispose()
+ {
+ Stop();
+
+ if (_dataFileStream != null)
+ {
+ _dataFileStream.Dispose();
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileRecorder.cs b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileRecorder.cs
index e52f39944..81f3217e7 100644
--- a/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileRecorder.cs
+++ b/Software/Visual_Studio/Tango.Integration/Diagnostics/DiagnosticsFileRecorder.cs
@@ -95,6 +95,9 @@ namespace Tango.Integration.Diagnostics
DataFileFrame frame = null;
if (_frames.TryDequeue(out frame))
{
+ TimeCodeChannelFrame timeCodeFrame = new TimeCodeChannelFrame();
+ timeCodeFrame.Position = TotalBytesRecorded;
+
byte[] data = frame.ToBytes();
_dataFileStream.Write(data, 0, data.Length);
@@ -102,7 +105,10 @@ namespace Tango.Integration.Diagnostics
TotalFramesRecorded++;
TotalBytesRecorded += data.Length;
- _timeCodeChannel.Frames.Add(new TimeCodeChannelFrame(data.Length, _stopWatch.Elapsed));
+ timeCodeFrame.TimeStamp = _stopWatch.Elapsed;
+ timeCodeFrame.FrameLength = data.Length;
+
+ _timeCodeChannel.Frames.Add(timeCodeFrame);
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/Diagnostics/TimeCodeChannelFrame.cs b/Software/Visual_Studio/Tango.Integration/Diagnostics/TimeCodeChannelFrame.cs
index c1f0f0582..22c2e0477 100644
--- a/Software/Visual_Studio/Tango.Integration/Diagnostics/TimeCodeChannelFrame.cs
+++ b/Software/Visual_Studio/Tango.Integration/Diagnostics/TimeCodeChannelFrame.cs
@@ -9,13 +9,8 @@ namespace Tango.Integration.Diagnostics
[Serializable]
public class TimeCodeChannelFrame
{
+ public long Position { get; set; }
public long FrameLength { get; set; }
public TimeSpan TimeStamp { get; set; }
-
- public TimeCodeChannelFrame(long frameLength, TimeSpan timeStamp)
- {
- FrameLength = frameLength;
- TimeStamp = timeStamp;
- }
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/Printing/BrushStop.cs b/Software/Visual_Studio/Tango.Integration/Printing/BrushStop.cs
index 947ff9013..b11ef9f15 100644
--- a/Software/Visual_Studio/Tango.Integration/Printing/BrushStop.cs
+++ b/Software/Visual_Studio/Tango.Integration/Printing/BrushStop.cs
@@ -65,13 +65,25 @@ namespace Tango.Integration.Observables
[NotMapped]
public double OffsetMeters
{
- get { return Segment.Length * (OffsetPercent / 100d); }
+ get
+ {
+ if (Segment != null)
+ {
+ return Segment.Length * (OffsetPercent / 100d);
+ }
+ else
+ {
+ return 0;
+ }
+ }
}
public void RaiseOffsetChanged()
{
RaisePropertyChanged(nameof(OffsetPercent));
RaisePropertyChanged(nameof(OffsetMeters));
+ RaisePropertyChanged(nameof(IsFirst));
+ RaisePropertyChanged(nameof(IsLast));
}
public void SetLiquidVolumes(Configuration configuration, Rml rml, ProcessParametersTable processParametersTable)
diff --git a/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj b/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj
index 6924c3abe..5417e7c0f 100644
--- a/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj
+++ b/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj
@@ -73,6 +73,7 @@
<Compile Include="..\Versioning\GlobalVersionInfo.cs">
<Link>GlobalVersionInfo.cs</Link>
</Compile>
+ <Compile Include="Diagnostics\DiagnosticsFilePlayer.cs" />
<Compile Include="Diagnostics\DiagnosticsFileRecorder.cs" />
<Compile Include="Diagnostics\TimeCodeChannel.cs" />
<Compile Include="Diagnostics\TimeCodeChannelFrame.cs" />
diff --git a/Software/Visual_Studio/Tango.Serialization/BinaryDataSerializer.cs b/Software/Visual_Studio/Tango.Serialization/BinaryDataSerializer.cs
index 26dcdad83..71efe9318 100644
--- a/Software/Visual_Studio/Tango.Serialization/BinaryDataSerializer.cs
+++ b/Software/Visual_Studio/Tango.Serialization/BinaryDataSerializer.cs
@@ -42,6 +42,21 @@ namespace Tango.Serialization
}
/// <summary>
+ /// Deserialize object from bytes.
+ /// </summary>
+ /// <typeparam name="T">Type of object to deserialize.</typeparam>
+ /// <param name="filePath">The full path of the data file.</param>
+ /// <returns>The resulting object.</returns>
+ public T DeserializeFromBytes<T>(byte[] bytes)
+ {
+ using (MemoryStream ms = new MemoryStream(bytes))
+ {
+ ms.Position = 0;
+ return DeserializeFromStream<T>(ms);
+ }
+ }
+
+ /// <summary>
/// Serialize object to stream.
/// </summary>
/// <typeparam name="T">Type of specified object.</typeparam>
@@ -54,7 +69,7 @@ namespace Tango.Serialization
}
/// <summary>
- /// Serialize object to stream.
+ /// Serialize object to byte array.
/// </summary>
/// <typeparam name="T">Type of specified object.</typeparam>
/// <param name="obj">The specified object.</param>