diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2017-11-09 20:26:27 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2017-11-09 20:26:27 +0200 |
| commit | 070aa53b6763fd2b5f7b482bf0f5070711f91ef6 (patch) | |
| tree | fcd654e68ba229d093d07c0c261044ff80d5beaf /Software | |
| parent | 6626d0227c28c0a9f990e08c431e8b80739ea58d (diff) | |
| download | Tango-070aa53b6763fd2b5f7b482bf0f5070711f91ef6.tar.gz Tango-070aa53b6763fd2b5f7b482bf0f5070711f91ef6.zip | |
Working on Tango integration & emulation on C# side.
Diffstat (limited to 'Software')
49 files changed, 2171 insertions, 26 deletions
diff --git a/Software/PMR/Messages/Common/MessageType.proto b/Software/PMR/Messages/Common/MessageType.proto index f1a284679..857e6874c 100644 --- a/Software/PMR/Messages/Common/MessageType.proto +++ b/Software/PMR/Messages/Common/MessageType.proto @@ -8,4 +8,6 @@ enum MessageType RGB = 0; Job = 1; Segment = 2; + Stub1Request = 3; + Stub1Response = 4; } diff --git a/Software/PMR/Messages/Stubs/Stub1.proto b/Software/PMR/Messages/Stubs/Stub1.proto new file mode 100644 index 000000000..e202613ff --- /dev/null +++ b/Software/PMR/Messages/Stubs/Stub1.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package Tango.PMR.Stubs; +option java_package = "com.twine.tango.pmr.stubs"; + +message Stub1Request +{ + int32 A = 1; + int32 B = 2; +} + +message Stub1Response +{ + int32 Sum = 1; +}
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.Core/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.Core/Properties/AssemblyInfo.cs index f76af4bb8..577126b91 100644 --- a/Software/Visual Studio/Tango.Core/Properties/AssemblyInfo.cs +++ b/Software/Visual Studio/Tango.Core/Properties/AssemblyInfo.cs @@ -2,5 +2,5 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -[assembly: AssemblyTitle("Twine - Core Components")] +[assembly: AssemblyTitle("Tango - Core Components")] [assembly: ComVisible(false)]
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.Emulator/App.config b/Software/Visual Studio/Tango.Emulator/App.config new file mode 100644 index 000000000..8e1564635 --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/App.config @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" ?> +<configuration> + <startup> + <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> + </startup> +</configuration>
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.Emulator/App.xaml b/Software/Visual Studio/Tango.Emulator/App.xaml new file mode 100644 index 000000000..a5bc9bfe1 --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/App.xaml @@ -0,0 +1,20 @@ +<Application x:Class="Tango.Emulator.App" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="clr-namespace:Tango.Emulator" + StartupUri="MainWindow.xaml"> + <Application.Resources> + <ResourceDictionary> + <ResourceDictionary.MergedDictionaries> + <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! --> + <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" /> + <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" /> + <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" /> + <!-- Accent and AppTheme setting --> + <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Red.xaml" /> + <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" /> + <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/FlatButton.xaml" /> + </ResourceDictionary.MergedDictionaries> + </ResourceDictionary> + </Application.Resources> +</Application> diff --git a/Software/Visual Studio/Tango.Emulator/App.xaml.cs b/Software/Visual Studio/Tango.Emulator/App.xaml.cs new file mode 100644 index 000000000..ca571bda0 --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace Tango.Emulator +{ + /// <summary> + /// Interaction logic for App.xaml + /// </summary> + public partial class App : Application + { + } +} diff --git a/Software/Visual Studio/Tango.Emulator/Images/machine-trans.png b/Software/Visual Studio/Tango.Emulator/Images/machine-trans.png Binary files differnew file mode 100644 index 000000000..a7cf65852 --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/Images/machine-trans.png diff --git a/Software/Visual Studio/Tango.Emulator/Images/phone.png b/Software/Visual Studio/Tango.Emulator/Images/phone.png Binary files differnew file mode 100644 index 000000000..d93503adc --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/Images/phone.png diff --git a/Software/Visual Studio/Tango.Emulator/MainWindow.xaml b/Software/Visual Studio/Tango.Emulator/MainWindow.xaml new file mode 100644 index 000000000..f5e4ee98e --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/MainWindow.xaml @@ -0,0 +1,95 @@ +<mahapps:MetroWindow x:Class="Tango.Emulator.MainWindow" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + xmlns:fa="http://schemas.fontawesome.io/icons/" + xmlns:local="clr-namespace:Tango.Emulator" + mc:Ignorable="d" + Title="Tango Machine Emulator" Height="720" Width="1200" TitleCaps="False" BorderBrush="Gray" BorderThickness="1" WindowStartupLocation="CenterScreen" Background="#202020" Foreground="Gainsboro" DataContext="{Binding RelativeSource={RelativeSource Self}}"> + <Grid> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="100"/> + <RowDefinition Height="1*"/> + </Grid.RowDefinitions> + + <Grid> + <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="20 15"> + <Image Source="Images/machine-trans.png" RenderOptions.BitmapScalingMode="Fant"></Image> + <TextBlock Text="Tango Machine Emulator" VerticalAlignment="Center" Margin="20 0 0 0" FontSize="36" Foreground="Yellow"> + <TextBlock.Effect> + <DropShadowEffect/> + </TextBlock.Effect> + </TextBlock> + </StackPanel> + + <Rectangle VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Margin="20 0 50 0" Stroke="DimGray" StrokeThickness="1" StrokeDashArray="5"></Rectangle> + </Grid> + + <Grid Grid.Row="1" Margin="20"> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="1*"/> + <RowDefinition Height="70"/> + </Grid.RowDefinitions> + + <Grid x:Name="gridContent" Background="#151515" Margin="5"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="300"/> + <ColumnDefinition Width="1*"/> + </Grid.ColumnDefinitions> + + <Image Source="Images/phone.png" RenderOptions.BitmapScalingMode="Fant" Stretch="Fill"></Image> + + <Grid Margin="45 70 45 55"> + <Grid.RowDefinitions> + <RowDefinition Height="302*"/> + <RowDefinition Height="35"/> + </Grid.RowDefinitions> + + <Grid> + <Button Width="100" Height="40" Click="Button_Click">SEND</Button> + </Grid> + + <UniformGrid Grid.Row="1" Columns="2" Background="#151515"> + <Button Margin="5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding DisconnectCommand}"> + <StackPanel Orientation="Horizontal"> + <fa:ImageAwesome Icon="Unlink" Width="16"></fa:ImageAwesome> + <TextBlock VerticalAlignment="Center" Margin="5 0 10 0">Disconnect</TextBlock> + </StackPanel> + </Button> + <Button Margin="5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding ConnectCommand}"> + <StackPanel Orientation="Horizontal"> + <fa:ImageAwesome Icon="Link" Width="16"></fa:ImageAwesome> + <TextBlock VerticalAlignment="Center" Margin="5 0 10 0">Connect</TextBlock> + </StackPanel> + </Button> + </UniformGrid> + </Grid> + </Grid> + </Grid> + <Grid x:Name="gridActions" Grid.Row="1" Background="#151515" Margin="5"> + <StackPanel HorizontalAlignment="Right" Orientation="Horizontal" Margin="5"> + <Button Margin="5" MinWidth="100" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding StopCommand}"> + <StackPanel Orientation="Horizontal"> + <fa:ImageAwesome Icon="Stop" Width="16"></fa:ImageAwesome> + <TextBlock VerticalAlignment="Center" Margin="10 0 10 0">STOP</TextBlock> + </StackPanel> + </Button> + <Button Margin="5" MinWidth="100" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding StartCommand}"> + <StackPanel Orientation="Horizontal"> + <fa:ImageAwesome Icon="Play" Width="16"></fa:ImageAwesome> + <TextBlock VerticalAlignment="Center" Margin="10 0 10 0">START</TextBlock> + </StackPanel> + </Button> + </StackPanel> + </Grid> + </Grid> + </Grid> + </Grid> + </Grid> +</mahapps:MetroWindow> diff --git a/Software/Visual Studio/Tango.Emulator/MainWindow.xaml.cs b/Software/Visual Studio/Tango.Emulator/MainWindow.xaml.cs new file mode 100644 index 000000000..43e3563bf --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/MainWindow.xaml.cs @@ -0,0 +1,177 @@ +using MahApps.Metro.Controls; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Tango.Integration.Adapters; +using Tango.Integration.Emulators; +using Tango.Integration.TCP; +using Tango.Integration.Transport; +using Tango.Logging; +using Tango.PMR; +using Tango.PMR.Stubs; +using Tango.SharedUI.Commands; + +namespace Tango.Emulator +{ + /// <summary> + /// Interaction logic for MainWindow.xaml + /// </summary> + public partial class MainWindow : MetroWindow + { + private ProtoTransporter mobileTransporter; + + #region Properties + + /// <summary> + /// Gets or sets a value indicating whether the emulator is started. + /// </summary> + public bool IsStarted + { + get { return (bool)GetValue(IsStartedProperty); } + set { SetValue(IsStartedProperty, value); } + } + public static readonly DependencyProperty IsStartedProperty = + DependencyProperty.Register("IsStarted", typeof(bool), typeof(MainWindow), new PropertyMetadata(false)); + + /// <summary> + /// Gets or sets the emulator. + /// </summary> + public MachineEmulator Emulator + { + get { return (MachineEmulator)GetValue(EmulatorProperty); } + set { SetValue(EmulatorProperty, value); } + } + public static readonly DependencyProperty EmulatorProperty = + DependencyProperty.Register("Emulator", typeof(MachineEmulator), typeof(MainWindow), new PropertyMetadata(null)); + + + /// <summary> + /// Gets or sets the TCP server. + /// </summary> + public TcpServer TcpServer + { + get { return (TcpServer)GetValue(TcpServerProperty); } + set { SetValue(TcpServerProperty, value); } + } + public static readonly DependencyProperty TcpServerProperty = + DependencyProperty.Register("TcpServer", typeof(TcpServer), typeof(MainWindow), new PropertyMetadata(null)); + + #endregion + + #region Commands + + /// <summary> + /// Gets or sets the start command. + /// </summary> + public RelayCommand StartCommand { get; set; } + + /// <summary> + /// Gets or sets the stop command. + /// </summary> + public RelayCommand StopCommand { get; set; } + + /// <summary> + /// Gets or sets the connect command. + /// </summary> + public RelayCommand ConnectCommand { get; set; } + + /// <summary> + /// Gets or sets the disconnect command. + /// </summary> + public RelayCommand DisconnectCommand { get; set; } + + #endregion + + #region Constructors + + /// <summary> + /// Initializes a new instance of the <see cref="MainWindow"/> class. + /// </summary> + public MainWindow() + { + LogManager.RegisterLogger(new VSOutputLogger()); + + TcpServer = new TcpServer(9999); + TcpServer.ClientConnected += TcpServer_ClientConnected; + + mobileTransporter = new ProtoTransporter(); + + StartCommand = new RelayCommand(() => + { + TcpServer.Start(); + StopCommand.RaiseCanExecuteChanged(); + StartCommand.RaiseCanExecuteChanged(); + }, x => !TcpServer.IsStarted); + + StopCommand = new RelayCommand(() => + { + TcpServer.Stop(); + + if (Emulator != null) + { + Emulator.Stop(); + } + StartCommand.RaiseCanExecuteChanged(); + StopCommand.RaiseCanExecuteChanged(); + }, (x) => + { + return TcpServer.IsStarted; + }); + + ConnectCommand = new RelayCommand(() => + { + mobileTransporter.Adapter = new TcpSerialAdapter("127.0.0.1", 9999); + mobileTransporter.Connect().Subscribe(); + + ConnectCommand.RaiseCanExecuteChanged(); + DisconnectCommand.RaiseCanExecuteChanged(); + + }, (x) => !mobileTransporter.IsConnected); + + DisconnectCommand = new RelayCommand(() => + { + mobileTransporter.Disconnect().Subscribe(); + + ConnectCommand.RaiseCanExecuteChanged(); + DisconnectCommand.RaiseCanExecuteChanged(); + + }, (x) => mobileTransporter.IsConnected); + + InitializeComponent(); + } + + private void TcpServer_ClientConnected(object sender, ClientConnectedEventArgs e) + { + Emulator = new MachineEmulator(new ProtoTransporter(new TcpSerialAdapter(e.Socket))); + Emulator.Start(); + } + + #endregion + + private void Button_Click(object sender, RoutedEventArgs e) + { + var request = MessageFactory.CreateContainer<Stub1Request>(); + request.Message.A = 5; + request.Message.B = 10; + + mobileTransporter.SendRequest<Stub1Request, Stub1Response>(request).Subscribe((response) => + { + + }, (error) => + { + + }); + } + } +} diff --git a/Software/Visual Studio/Tango.Emulator/Models/StubVM.cs b/Software/Visual Studio/Tango.Emulator/Models/StubVM.cs new file mode 100644 index 000000000..abda393b8 --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/Models/StubVM.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PMR; +using Tango.PMR.Common; +using Tango.SharedUI; + +namespace Tango.Emulator.Models +{ + public class StubVM : ExtendedObject + { + public MessageContainer Message { get; set; } + } +} diff --git a/Software/Visual Studio/Tango.Emulator/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.Emulator/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..7d440978a --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Tango - Machine Emulator Utility")] +[assembly: ComVisible(false)]
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.Emulator/Properties/Resources.Designer.cs b/Software/Visual Studio/Tango.Emulator/Properties/Resources.Designer.cs new file mode 100644 index 000000000..3958e81c9 --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// <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 Tango.Emulator.Properties +{ + + + /// <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", "4.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 ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Tango.Emulator.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; + } + } + } +} diff --git a/Software/Visual Studio/Tango.Emulator/Properties/Resources.resx b/Software/Visual Studio/Tango.Emulator/Properties/Resources.resx new file mode 100644 index 000000000..af7dbebba --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/Properties/Resources.resx @@ -0,0 +1,117 @@ +<?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.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: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" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + </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" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + </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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root>
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.Emulator/Properties/Settings.Designer.cs b/Software/Visual Studio/Tango.Emulator/Properties/Settings.Designer.cs new file mode 100644 index 000000000..a9e286568 --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// <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 Tango.Emulator.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/Software/Visual Studio/Tango.Emulator/Properties/Settings.settings b/Software/Visual Studio/Tango.Emulator/Properties/Settings.settings new file mode 100644 index 000000000..033d7a5e9 --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/Properties/Settings.settings @@ -0,0 +1,7 @@ +<?xml version='1.0' encoding='utf-8'?> +<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> + <Profiles> + <Profile Name="(Default)" /> + </Profiles> + <Settings /> +</SettingsFile>
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.Emulator/Tango.Emulator.csproj b/Software/Visual Studio/Tango.Emulator/Tango.Emulator.csproj new file mode 100644 index 000000000..0b3cfabb1 --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/Tango.Emulator.csproj @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{FA15BBFC-AEAF-4364-9F90-CE4EFCE661FE}</ProjectGuid> + <OutputType>WinExe</OutputType> + <RootNamespace>Tango.Emulator</RootNamespace> + <AssemblyName>Tango.Emulator</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>..\Build\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="FontAwesome.WPF, Version=4.7.0.37774, Culture=neutral, PublicKeyToken=0758b07a11a4f466, processorArchitecture=MSIL"> + <HintPath>..\packages\FontAwesome.WPF.4.7.0.9\lib\net40\FontAwesome.WPF.dll</HintPath> + </Reference> + <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL"> + <HintPath>..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath> + </Reference> + <Reference Include="MahApps.Metro, Version=1.5.0.23, Culture=neutral, PublicKeyToken=f4fb5a3c4d1e5b4f, processorArchitecture=MSIL"> + <HintPath>..\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Reactive.Core, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Reactive.Core.3.1.1\lib\net45\System.Reactive.Core.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.Interfaces, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Reactive.Interfaces.3.1.1\lib\net45\System.Reactive.Interfaces.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.Linq, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Reactive.Linq.3.1.1\lib\net45\System.Reactive.Linq.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.PlatformServices, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Reactive.PlatformServices.3.1.1\lib\net45\System.Reactive.PlatformServices.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.Windows.Threading, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Reactive.Windows.Threading.3.1.1\lib\net45\System.Reactive.Windows.Threading.dll</HintPath> + </Reference> + <Reference Include="System.Windows" /> + <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\packages\MahApps.Metro.1.5.0\lib\net45\System.Windows.Interactivity.dll</HintPath> + </Reference> + <Reference Include="System.Xml" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Core" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xaml"> + <RequiredTargetFramework>4.0</RequiredTargetFramework> + </Reference> + <Reference Include="WindowsBase" /> + <Reference Include="PresentationCore" /> + <Reference Include="PresentationFramework" /> + </ItemGroup> + <ItemGroup> + <ApplicationDefinition Include="App.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </ApplicationDefinition> + <Page Include="MainWindow.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> + <Compile Include="..\Versioning\GlobalVersionInfo.cs"> + <Link>GlobalVersionInfo.cs</Link> + </Compile> + <Compile Include="App.xaml.cs"> + <DependentUpon>App.xaml</DependentUpon> + <SubType>Code</SubType> + </Compile> + <Compile Include="MainWindow.xaml.cs"> + <DependentUpon>MainWindow.xaml</DependentUpon> + <SubType>Code</SubType> + </Compile> + </ItemGroup> + <ItemGroup> + <Compile Include="Models\StubVM.cs" /> + <Compile Include="Properties\AssemblyInfo.cs"> + <SubType> + </SubType> + </Compile> + <Compile Include="Properties\Resources.Designer.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>Resources.resx</DependentUpon> + </Compile> + <Compile Include="Properties\Settings.Designer.cs"> + <AutoGen>True</AutoGen> + <DependentUpon>Settings.settings</DependentUpon> + <DesignTimeSharedInput>True</DesignTimeSharedInput> + </Compile> + <EmbeddedResource Include="Properties\Resources.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + </EmbeddedResource> + <None Include="packages.config" /> + <None Include="Properties\Settings.settings"> + <Generator>SettingsSingleFileGenerator</Generator> + <LastGenOutput>Settings.Designer.cs</LastGenOutput> + </None> + </ItemGroup> + <ItemGroup> + <None Include="App.config" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Tango.Core\Tango.Core.csproj"> + <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> + <Name>Tango.Core</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.Integration\Tango.Integration.csproj"> + <Project>{b6182925-8864-401f-a390-6eff737c4fc7}</Project> + <Name>Tango.Integration</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.Logging\Tango.Logging.csproj"> + <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project> + <Name>Tango.Logging</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.PMR\Tango.PMR.csproj"> + <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project> + <Name>Tango.PMR</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.Protobuf\Tango.Protobuf.csproj"> + <Project>{40073806-914e-4e78-97ab-fa9639308ebe}</Project> + <Name>Tango.Protobuf</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.SharedUI\Tango.SharedUI.csproj"> + <Project>{ac489889-6e50-4f16-9dba-ff4c6f9ec72b}</Project> + <Name>Tango.SharedUI</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Resource Include="Images\machine-trans.png" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Images\phone.png" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.Emulator/packages.config b/Software/Visual Studio/Tango.Emulator/packages.config new file mode 100644 index 000000000..72d96268c --- /dev/null +++ b/Software/Visual Studio/Tango.Emulator/packages.config @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="FontAwesome.WPF" version="4.7.0.9" targetFramework="net45" /> + <package id="Google.Protobuf" version="3.4.1" targetFramework="net45" /> + <package id="MahApps.Metro" version="1.5.0" targetFramework="net45" /> + <package id="System.Reactive" version="3.1.1" targetFramework="net45" /> + <package id="System.Reactive.Core" version="3.1.1" targetFramework="net45" /> + <package id="System.Reactive.Interfaces" version="3.1.1" targetFramework="net45" /> + <package id="System.Reactive.Linq" version="3.1.1" targetFramework="net45" /> + <package id="System.Reactive.PlatformServices" version="3.1.1" targetFramework="net45" /> + <package id="System.Reactive.Windows.Threading" version="3.1.1" targetFramework="net45" /> +</packages>
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.Integration/Adapters/ISerialAdapter.cs b/Software/Visual Studio/Tango.Integration/Adapters/ISerialAdapter.cs new file mode 100644 index 000000000..0da75704c --- /dev/null +++ b/Software/Visual Studio/Tango.Integration/Adapters/ISerialAdapter.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reactive; +using System.Reactive.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Integration.Adapters +{ + public interface ISerialAdapter : IDisposable + { + IObservable<Unit> Open(); + IObservable<Unit> Close(); + void Write(byte[] data); + IObservable<byte[]> ReceiveData(); + bool IsOpened { get; } + IObservable<Unit> SubscribeForDisconnection(); + } +} diff --git a/Software/Visual Studio/Tango.Integration/Adapters/TcpSerialAdapter.cs b/Software/Visual Studio/Tango.Integration/Adapters/TcpSerialAdapter.cs new file mode 100644 index 000000000..92d0894e1 --- /dev/null +++ b/Software/Visual Studio/Tango.Integration/Adapters/TcpSerialAdapter.cs @@ -0,0 +1,187 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Reactive; +using System.Reactive.Concurrency; +using System.Reactive.Disposables; +using System.Reactive.Linq; +using System.Reactive.Subjects; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Tango.Logging; + +namespace Tango.Integration.Adapters +{ + public class TcpSerialAdapter : ISerialAdapter + { + private TcpClient _socket; + private Thread _receiveThread; + private Subject<byte[]> _receiveSubject; + private Subject<Unit> _disconnectionSubject; + + public bool IsOpened { get; private set; } + + public String Address { get; set; } + + public int Port { get; set; } + + public TcpSerialAdapter() + { + _receiveSubject = new Subject<byte[]>(); + _disconnectionSubject = new Subject<Unit>(); + } + + public TcpSerialAdapter(String address, int port) : this() + { + Address = address; + Port = port; + } + + public TcpSerialAdapter(TcpClient socket) : this() + { + _socket = socket; + Start(); + } + + public IObservable<Unit> Open() + { + return Observable.Create<Unit>((x) => + { + try + { + if (!IsOpened) + { + _socket = new TcpClient(Address, Port); + Start(); + LogManager.Log("Adapter connected."); + } + + x.OnNext(Unit.Default); + } + catch (Exception ex) + { + x.OnError(LogManager.Log(ex, "Could not connect the adapter.")); + } + finally + { + x.OnCompleted(); + } + + return Disposable.Empty; + + }).ObserveOn(Scheduler.Default); + } + + private void Start() + { + IsOpened = true; + _receiveThread = new Thread(ReceiveThreadMethod); + _receiveThread.IsBackground = true; + _receiveThread.Start(); + } + + public IObservable<Unit> Close() + { + return Observable.Create<Unit>((x) => + { + try + { + if (IsOpened) + { + IsOpened = false; + _socket.GetStream().Close(); + _socket.Close(); + LogManager.Log("Adapter disconnected."); + } + + x.OnNext(Unit.Default); + } + catch (Exception ex) + { + x.OnError(LogManager.Log(ex, "Could not disconnect the adapter.")); + } + finally + { + x.OnCompleted(); + } + + return Disposable.Empty; + + }).ObserveOn(Scheduler.Default); + } + + public void Write(byte[] data) + { + _socket.GetStream().Write(data, 0, data.Length); + } + + public IObservable<byte[]> ReceiveData() + { + return _receiveSubject; + } + + private void ReceiveThreadMethod() + { + int counter = 0; + + try + { + while (IsOpened) + { + if (_socket.Available > 0) + { + byte[] data = new byte[_socket.Available]; + _socket.GetStream().Read(data, 0, data.Length); + + if (_receiveSubject != null) + { + _receiveSubject.OnNext(data); + } + } + + Thread.Sleep(10); + counter++; + + if (counter >= 200) + { + try + { + if (_socket.Client.Poll(1, SelectMode.SelectRead) && _socket.Client.Available == 0) + { + Close().Subscribe(); + _disconnectionSubject.OnError(LogManager.Log(new Exception("Client disconnected."))); + return; + } + } + catch (SocketException ex) + { + Close().Subscribe(); + _disconnectionSubject.OnError(LogManager.Log(ex)); + return; + } + + counter = 0; + } + } + + _receiveSubject.OnCompleted(); + } + catch (Exception ex) + { + _receiveSubject.OnError(LogManager.Log(ex)); + } + } + + public void Dispose() + { + Close(); + } + + public IObservable<Unit> SubscribeForDisconnection() + { + return _disconnectionSubject; + } + } +} diff --git a/Software/Visual Studio/Tango.Integration/Emulators/MachineEmulator.cs b/Software/Visual Studio/Tango.Integration/Emulators/MachineEmulator.cs new file mode 100644 index 000000000..cbb5f00f9 --- /dev/null +++ b/Software/Visual Studio/Tango.Integration/Emulators/MachineEmulator.cs @@ -0,0 +1,131 @@ +using Google.Protobuf; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Tango.Integration.Adapters; +using Tango.Integration.TCP; +using Tango.Integration.Transport; +using Tango.Logging; +using Tango.PMR; +using Tango.PMR.Common; +using Tango.PMR.Stubs; +using Tango.SharedUI; +using Tango.SharedUI.Commands; + +namespace Tango.Integration.Emulators +{ + public class MachineEmulator : ExtendedObject + { + private ITransporter _transporter; + + #region Properties + + private bool _isStarted; + /// <summary> + /// Gets or sets a value indicating whether the emulator is started. + /// </summary> + public bool IsStarted + { + get { return _isStarted; } + set { _isStarted = value; RaisePropertyChanged(nameof(IsStarted)); InvalidateRelayCommands(); } + } + + #endregion + + #region Commands + + /// <summary> + /// Gets or sets the start command. + /// </summary> + public RelayCommand StartCommand { get; set; } + + /// <summary> + /// Gets or sets the stop command. + /// </summary> + public RelayCommand StopCommand { get; set; } + + #endregion + + #region Constructors + + /// <summary> + /// Initializes a new instance of the <see cref="MachineEmulator"/> class. + /// </summary> + public MachineEmulator(ITransporter transporter) + { + _transporter = transporter; + _transporter.SubscribeForRequests().Subscribe(HandleRequest); + _transporter.SubscribeForDisconnection().Subscribe((x) => {}, (ex) => + { + LogManager.Log("Transporter disconnected."); + }); + StartCommand = new RelayCommand(Start, (x) => !IsStarted); + StopCommand = new RelayCommand(Stop, (x) => IsStarted); + } + + #endregion + + #region Public Methods + + /// <summary> + /// Stops this instance. + /// </summary> + public void Stop() + { + if (IsStarted) + { + _transporter.Disconnect().Subscribe(x => + { + IsStarted = false; + }, ex => { throw ex; }); + } + } + + /// <summary> + /// Starts this instance. + /// </summary> + public void Start() + { + if (!IsStarted) + { + _transporter.Connect().Subscribe(x => + { + IsStarted = true; + }, ex => { throw ex; }); + } + } + + #endregion + + #region Virtual Methods + + /// <summary> + /// Handles the request. + /// </summary> + /// <param name="container">The container.</param> + protected void HandleRequest(MessageContainer container) + { + switch (container.Type) + { + case MessageType.Stub1Request: + Task.Factory.StartNew(() => + { + Thread.Sleep(5000); + + var request = MessageFactory.ParseContainer<Stub1Request>(container); + var response = MessageFactory.CreateContainer<Stub1Response>(container.Token); + response.Message.Sum = request.A + request.B; + response.Container.Token = container.Token; + _transporter.SendResponse(response); + }); + break; + } + } + + #endregion + } +} diff --git a/Software/Visual Studio/Tango.Integration/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.Integration/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..d76cafb27 --- /dev/null +++ b/Software/Visual Studio/Tango.Integration/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Tango - Machine Integration Layer")] +[assembly: ComVisible(false)]
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.Integration/TCP/ClientConnectedEventArgs.cs b/Software/Visual Studio/Tango.Integration/TCP/ClientConnectedEventArgs.cs new file mode 100644 index 000000000..21e311b19 --- /dev/null +++ b/Software/Visual Studio/Tango.Integration/TCP/ClientConnectedEventArgs.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Integration.TCP +{ + public class ClientConnectedEventArgs : EventArgs + { + public TcpClient Socket { get; set; } + + public ClientConnectedEventArgs(TcpClient socket) + { + Socket = socket; + } + } +} diff --git a/Software/Visual Studio/Tango.Integration/TCP/TcpServer.cs b/Software/Visual Studio/Tango.Integration/TCP/TcpServer.cs new file mode 100644 index 000000000..6f24646ae --- /dev/null +++ b/Software/Visual Studio/Tango.Integration/TCP/TcpServer.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Tango.Logging; + +namespace Tango.Integration.TCP +{ + public class TcpServer + { + private TaskScheduler scheduler; + + /// <summary> + /// The TcpListener that is encapsulated behind this Server instance. + /// </summary> + public TcpListener Listener { get; set; } + /// <summary> + /// The Port that is used to listen to incoming connections. + /// </summary> + public int Port { get; set; } + /// <summary> + /// Returns true if the Server instance is running. + /// </summary> + public bool IsStarted { get; private set; } + + #region Events + + public event EventHandler<ClientConnectedEventArgs> ClientConnected; + + #endregion + + #region Constructors + + /// <summary> + /// Initializes a new Server instance. + /// </summary> + /// <param name="port">The port number that is used to listen for incoming connections.</param> + public TcpServer(int port) + { + Port = port; + scheduler = TaskScheduler.FromCurrentSynchronizationContext(); + } + #endregion + + #region Public Methods + + /// <summary> + /// Start Listening for incoming connections. + /// </summary> + public void Start() + { + if (!IsStarted) + { + Listener = new TcpListener(System.Net.IPAddress.Any, Port); + Listener.Start(); + IsStarted = true; + LogManager.Log("Server Started!"); + WaitForConnection(); + } + } + /// <summary> + /// Stop listening for incoming connections. + /// </summary> + public void Stop() + { + if (IsStarted) + { + Listener.Stop(); + IsStarted = false; + LogManager.Log("Server Stopped!"); + } + } + + #endregion + + #region Incoming Connections Methods + + private void WaitForConnection() + { + Listener.BeginAcceptTcpClient(new AsyncCallback(ConnectionHandler), null); + } + + private void ConnectionHandler(IAsyncResult ar) + { + if (IsStarted) + { + try + { + OnClientConnected(Listener.EndAcceptTcpClient(ar)); + Debug.WriteLine("New Client Connected"); + WaitForConnection(); + } + catch (ObjectDisposedException ex) + { + //Ignore.. + } + } + } + + #endregion + + #region Virtual Methods + + protected virtual void OnClientConnected(TcpClient socket) + { + LogManager.Log("Client Connected."); + + Task.Factory.StartNew(() => + { + + ClientConnected?.Invoke(this, new ClientConnectedEventArgs(socket)); + + },CancellationToken.None,TaskCreationOptions.None,scheduler); + } + + #endregion + } +} diff --git a/Software/Visual Studio/Tango.Integration/Tango.Integration.csproj b/Software/Visual Studio/Tango.Integration/Tango.Integration.csproj new file mode 100644 index 000000000..da3ee255e --- /dev/null +++ b/Software/Visual Studio/Tango.Integration/Tango.Integration.csproj @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{B6182925-8864-401F-A390-6EFF737C4FC7}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Tango.Integration</RootNamespace> + <AssemblyName>Tango.Integration</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>..\Build\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL"> + <HintPath>..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.Core" /> + <Reference Include="System.Reactive.Core, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Reactive.Core.3.1.1\lib\net45\System.Reactive.Core.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.Interfaces, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Reactive.Interfaces.3.1.1\lib\net45\System.Reactive.Interfaces.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.Linq, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Reactive.Linq.3.1.1\lib\net45\System.Reactive.Linq.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.PlatformServices, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Reactive.PlatformServices.3.1.1\lib\net45\System.Reactive.PlatformServices.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.Windows.Threading, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> + <HintPath>..\packages\System.Reactive.Windows.Threading.3.1.1\lib\net45\System.Reactive.Windows.Threading.dll</HintPath> + </Reference> + <Reference Include="System.Windows" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xml" /> + <Reference Include="WindowsBase" /> + </ItemGroup> + <ItemGroup> + <Compile Include="..\Versioning\GlobalVersionInfo.cs"> + <Link>GlobalVersionInfo.cs</Link> + </Compile> + <Compile Include="Adapters\ISerialAdapter.cs" /> + <Compile Include="Adapters\TcpSerialAdapter.cs" /> + <Compile Include="Emulators\MachineEmulator.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="TCP\ClientConnectedEventArgs.cs" /> + <Compile Include="TCP\TcpServer.cs" /> + <Compile Include="Transport\ITransporter.cs" /> + <Compile Include="Transport\MessageBase.cs" /> + <Compile Include="Transport\ProtoTransporter.cs" /> + <Compile Include="Transport\RequestMessage.cs" /> + <Compile Include="Transport\ResponseMessage.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Tango.Core\Tango.Core.csproj"> + <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> + <Name>Tango.Core</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.Logging\Tango.Logging.csproj"> + <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project> + <Name>Tango.Logging</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.PMR\Tango.PMR.csproj"> + <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project> + <Name>Tango.PMR</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.Protobuf\Tango.Protobuf.csproj"> + <Project>{40073806-914e-4e78-97ab-fa9639308ebe}</Project> + <Name>Tango.Protobuf</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.SharedUI\Tango.SharedUI.csproj"> + <Project>{ac489889-6e50-4f16-9dba-ff4c6f9ec72b}</Project> + <Name>Tango.SharedUI</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <None Include="packages.config" /> + </ItemGroup> + <ItemGroup /> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.Integration/Transport/ITransporter.cs b/Software/Visual Studio/Tango.Integration/Transport/ITransporter.cs new file mode 100644 index 000000000..cb4693efa --- /dev/null +++ b/Software/Visual Studio/Tango.Integration/Transport/ITransporter.cs @@ -0,0 +1,66 @@ +using Google.Protobuf; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reactive; +using System.Reactive.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Integration.Adapters; +using Tango.PMR; +using Tango.PMR.Common; + +namespace Tango.Integration.Transport +{ + public interface ITransporter : IDisposable + { + /// <summary> + /// Gets the serial adapter. + /// </summary> + ISerialAdapter Adapter { get; set; } + + /// <summary> + /// Gets a value indicating whether this transporter is connected. + /// </summary> + bool IsConnected { get; } + + /// <summary> + /// Sends a request. + /// </summary> + /// <typeparam name="Request">The type of the request.</typeparam> + /// <typeparam name="Response">The type of the response.</typeparam> + /// <param name="request">The request.</param> + /// <returns></returns> + IObservable<Response> SendRequest<Request, Response>(TangoMessage<Request> request) where Request : IMessage<Request> where Response : IMessage<Response>; + + /// <summary> + /// Sends a response. + /// </summary> + /// <typeparam name="Response">The type of the response.</typeparam> + /// <param name="response">The response.</param> + /// <returns></returns> + IObservable<object> SendResponse<Response>(TangoMessage<Response> response) where Response : IMessage<Response>; + + /// <summary> + /// Subscribes for requests. + /// </summary> + /// <returns></returns> + IObservable<MessageContainer> SubscribeForRequests(); + + /// <summary> + /// Opens a connection on the <see cref="Adapter"/>. + /// </summary> + IObservable<Unit> Connect(); + + /// <summary> + /// Closes the connection on the <see cref="Adapter"/>. + /// </summary> + IObservable<Unit> Disconnect(); + + /// <summary> + /// Subscribes for disconnection. + /// </summary> + /// <returns></returns> + IObservable<Unit> SubscribeForDisconnection(); + } +} diff --git a/Software/Visual Studio/Tango.Integration/Transport/MessageBase.cs b/Software/Visual Studio/Tango.Integration/Transport/MessageBase.cs new file mode 100644 index 000000000..46d5b3109 --- /dev/null +++ b/Software/Visual Studio/Tango.Integration/Transport/MessageBase.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reactive.Subjects; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Integration.Transport +{ + internal class MessageBase + { + public String Token { get; set; } + + public Subject<object> Subject { get; set; } + + private Func<byte[]> _toBytes; + + public object Message { get; set; } + + public byte[] ToBytes() + { + return _toBytes(); + } + + public MessageBase(String token, Subject<object> subject, object message, Func<byte[]> toBytes) + { + Token = token; + Subject = subject; + Message = message; + _toBytes = toBytes; + } + } +} diff --git a/Software/Visual Studio/Tango.Integration/Transport/ProtoTransporter.cs b/Software/Visual Studio/Tango.Integration/Transport/ProtoTransporter.cs new file mode 100644 index 000000000..aaaa5a5ce --- /dev/null +++ b/Software/Visual Studio/Tango.Integration/Transport/ProtoTransporter.cs @@ -0,0 +1,255 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reactive.Linq; +using System.Text; +using System.Threading.Tasks; +using Google.Protobuf; +using Tango.Integration.Adapters; +using Tango.PMR; +using Tango.PMR.Common; +using System.Collections.Concurrent; +using System.Reactive.Subjects; +using System.Threading; +using System.Reactive; +using System.Reactive.Disposables; +using Tango.Logging; + +namespace Tango.Integration.Transport +{ + public class ProtoTransporter : ITransporter + { + private ConcurrentQueue<MessageBase> _sendingQueue; + private List<RequestMessage> _pendingRequests; + private ConcurrentQueue<byte[]> _arrivedResponses; + + private Subject<MessageContainer> _requestSubject; + + private Thread _pushThread; + private Thread _pullThread; + + private ISerialAdapter _adapter; + /// <summary> + /// Gets the serial adapter. + /// </summary> + public ISerialAdapter Adapter + { + get { return _adapter; } + set + { + _adapter = value; + + if (IsConnected) + { + Connect(); + } + } + } + + /// <summary> + /// Gets a value indicating whether this transporter is connected. + /// </summary> + public bool IsConnected { get; private set; } + + /// <summary> + /// Initializes a new instance of the <see cref="ProtoTransporter"/> class. + /// </summary> + public ProtoTransporter() + { + _sendingQueue = new ConcurrentQueue<MessageBase>(); + _pendingRequests = new List<RequestMessage>(); + _arrivedResponses = new ConcurrentQueue<byte[]>(); + _requestSubject = new Subject<MessageContainer>(); + } + + /// <summary> + /// Initializes a new instance of the <see cref="ProtoTransporter"/> class. + /// </summary> + /// <param name="adapter">The adapter.</param> + public ProtoTransporter(ISerialAdapter adapter) : this() + { + Adapter = adapter; + } + + /// <summary> + /// Opens a connection on the <see cref="Adapter" />. + /// </summary> + public IObservable<Unit> Connect() + { + IsConnected = true; + Adapter.ReceiveData().Subscribe((data) => { _arrivedResponses.Enqueue(data); }); + StartThreads(); + return Adapter.Open(); + } + + /// <summary> + /// Closes the connection on the <see cref="Adapter" />. + /// </summary> + public IObservable<Unit> Disconnect() + { + IsConnected = false; + return Adapter.Close(); + } + + /// <summary> + /// Starts the threads. + /// </summary> + private void StartThreads() + { + _pullThread = new Thread(PullThreadMethod); + _pullThread.IsBackground = true; + _pullThread.Start(); + + _pushThread = new Thread(PushThreadMethod); + _pushThread.IsBackground = true; + _pushThread.Start(); + } + + /// <summary> + /// Push thread loop. + /// </summary> + private void PushThreadMethod() + { + while (IsConnected) + { + if (_sendingQueue.Count > 0) + { + MessageBase message; + if (_sendingQueue.TryDequeue(out message)) + { + try + { + Adapter.Write(message.ToBytes()); + + if (message.GetType() == typeof(RequestMessage)) + { + _pendingRequests.Add(message as RequestMessage); + } + else + { + message.Subject.OnNext(new object()); + message.Subject.OnCompleted(); + } + } + catch (Exception ex) + { + message.Subject.OnError(ex); + } + } + } + + Thread.Sleep(10); + } + } + + /// <summary> + /// Pull thread loop. + /// </summary> + private void PullThreadMethod() + { + while (IsConnected) + { + byte[] data; + + if (_arrivedResponses.Count > 0) + { + if (_arrivedResponses.TryDequeue(out data)) + { + MessageContainer container = MessageFactory.ParseContainerPartial(data); + RequestMessage request = _pendingRequests.SingleOrDefault(x => x.Token == container.Token); + + if (request != null) + { + _pendingRequests.Remove(request); + + try + { + request.Subject.OnNext(MessageFactory.ParseContainer(container)); + } + catch (Exception ex) + { + request.Subject.OnError(ex); + } + } + else + { + try + { + _requestSubject.OnNext(container); + } + catch (Exception ex) + { + _requestSubject.OnError(ex); + } + } + } + } + + Thread.Sleep(10); + } + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + Disconnect(); + } + + /// <summary> + /// Sends a request. + /// </summary> + /// <typeparam name="Request">The type of the request.</typeparam> + /// <typeparam name="Response">The type of the response.</typeparam> + /// <param name="request">The request.</param> + /// <returns></returns> + public IObservable<Response> SendRequest<Request, Response>(TangoMessage<Request> request) where Request : IMessage<Request> where Response : IMessage<Response> + { + Subject<object> subject = new Subject<object>(); + RequestMessage message = new RequestMessage(request.Container.Token, subject, request, request.ToBytes); + _sendingQueue.Enqueue(message); + IObservable<Response> observer = subject.Select(x => (Response)x); + return observer; + } + + /// <summary> + /// Sends a response. + /// </summary> + /// <typeparam name="Response">The type of the response.</typeparam> + /// <param name="response">The response.</param> + /// <returns></returns> + public IObservable<object> SendResponse<Response>(TangoMessage<Response> response) where Response : IMessage<Response> + { + Subject<object> subject = new Subject<object>(); + ResponseMessage message = new ResponseMessage(Guid.NewGuid().ToString(), subject, response, response.ToBytes); + _sendingQueue.Enqueue(message); + return subject; + } + + /// <summary> + /// Subscribes for requests. + /// </summary> + /// <returns></returns> + public IObservable<MessageContainer> SubscribeForRequests() + { + return _requestSubject; + } + + /// <summary> + /// Subscribes for disconnection. + /// </summary> + /// <returns></returns> + public IObservable<Unit> SubscribeForDisconnection() + { + var observable = Adapter.SubscribeForDisconnection(); + observable.Subscribe((x) => { }, (ex) => + { + LogManager.Log("Adapter closed. Disconnecting..."); + Disconnect().Subscribe(); + }); + + return observable; + } + } +} diff --git a/Software/Visual Studio/Tango.Integration/Transport/RequestMessage.cs b/Software/Visual Studio/Tango.Integration/Transport/RequestMessage.cs new file mode 100644 index 000000000..149712bee --- /dev/null +++ b/Software/Visual Studio/Tango.Integration/Transport/RequestMessage.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reactive.Subjects; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Integration.Transport +{ + internal class RequestMessage : MessageBase + { + public RequestMessage(String token, Subject<object> subject, object message, Func<byte[]> toBytes) : base(token, subject, message, toBytes) + { + + } + } +} diff --git a/Software/Visual Studio/Tango.Integration/Transport/ResponseMessage.cs b/Software/Visual Studio/Tango.Integration/Transport/ResponseMessage.cs new file mode 100644 index 000000000..8eb956eec --- /dev/null +++ b/Software/Visual Studio/Tango.Integration/Transport/ResponseMessage.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reactive.Subjects; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Integration.Transport +{ + internal class ResponseMessage : MessageBase + { + internal ResponseMessage(String token, Subject<object> subject, object message, Func<byte[]> toBytes) : base(token, subject, message, toBytes) + { + + } + } +} diff --git a/Software/Visual Studio/Tango.Integration/packages.config b/Software/Visual Studio/Tango.Integration/packages.config new file mode 100644 index 000000000..5a7de5f4e --- /dev/null +++ b/Software/Visual Studio/Tango.Integration/packages.config @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="Google.Protobuf" version="3.4.1" targetFramework="net45" /> + <package id="System.Reactive" version="3.1.1" targetFramework="net45" /> + <package id="System.Reactive.Core" version="3.1.1" targetFramework="net45" /> + <package id="System.Reactive.Interfaces" version="3.1.1" targetFramework="net45" /> + <package id="System.Reactive.Linq" version="3.1.1" targetFramework="net45" /> + <package id="System.Reactive.PlatformServices" version="3.1.1" targetFramework="net45" /> + <package id="System.Reactive.Windows.Threading" version="3.1.1" targetFramework="net45" /> +</packages>
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.Logging/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.Logging/Properties/AssemblyInfo.cs index 9155db1b4..161c5a04e 100644 --- a/Software/Visual Studio/Tango.Logging/Properties/AssemblyInfo.cs +++ b/Software/Visual Studio/Tango.Logging/Properties/AssemblyInfo.cs @@ -2,5 +2,5 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -[assembly: AssemblyTitle("Twine - Logging Library")] +[assembly: AssemblyTitle("Tango - Logging Library")] [assembly: ComVisible(false)]
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.PMR/Common/MessageContainer.cs b/Software/Visual Studio/Tango.PMR/Common/MessageContainer.cs index c887da2f4..4b4a437a9 100644 --- a/Software/Visual Studio/Tango.PMR/Common/MessageContainer.cs +++ b/Software/Visual Studio/Tango.PMR/Common/MessageContainer.cs @@ -23,13 +23,14 @@ namespace Tango.PMR.Common { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( "ChZNZXNzYWdlQ29udGFpbmVyLnByb3RvEhBUYW5nby5QTVIuQ29tbW9uGhFN", - "ZXNzYWdlVHlwZS5wcm90byJNChBNZXNzYWdlQ29udGFpbmVyEisKBFR5cGUY", - "ASABKA4yHS5UYW5nby5QTVIuQ29tbW9uLk1lc3NhZ2VUeXBlEgwKBERhdGEY", - "AiABKAxiBnByb3RvMw==")); + "ZXNzYWdlVHlwZS5wcm90byJcChBNZXNzYWdlQ29udGFpbmVyEisKBFR5cGUY", + "ASABKA4yHS5UYW5nby5QTVIuQ29tbW9uLk1lc3NhZ2VUeXBlEg0KBVRva2Vu", + "GAIgASgJEgwKBERhdGEYAyABKAxCHAoaY29tLnR3aW5lLnRhbmdvLnBtci5j", + "b21tb25iBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Tango.PMR.Common.MessageTypeReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Common.MessageContainer), global::Tango.PMR.Common.MessageContainer.Parser, new[]{ "Type", "Data" }, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Common.MessageContainer), global::Tango.PMR.Common.MessageContainer.Parser, new[]{ "Type", "Token", "Data" }, null, null, null) })); } #endregion @@ -61,6 +62,7 @@ namespace Tango.PMR.Common { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public MessageContainer(MessageContainer other) : this() { type_ = other.type_; + token_ = other.token_; data_ = other.data_; } @@ -80,8 +82,19 @@ namespace Tango.PMR.Common { } } + /// <summary>Field number for the "Token" field.</summary> + public const int TokenFieldNumber = 2; + private string token_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string Token { + get { return token_; } + set { + token_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + /// <summary>Field number for the "Data" field.</summary> - public const int DataFieldNumber = 2; + public const int DataFieldNumber = 3; private pb::ByteString data_ = pb::ByteString.Empty; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pb::ByteString Data { @@ -105,6 +118,7 @@ namespace Tango.PMR.Common { return true; } if (Type != other.Type) return false; + if (Token != other.Token) return false; if (Data != other.Data) return false; return true; } @@ -113,6 +127,7 @@ namespace Tango.PMR.Common { public override int GetHashCode() { int hash = 1; if (Type != 0) hash ^= Type.GetHashCode(); + if (Token.Length != 0) hash ^= Token.GetHashCode(); if (Data.Length != 0) hash ^= Data.GetHashCode(); return hash; } @@ -128,8 +143,12 @@ namespace Tango.PMR.Common { output.WriteRawTag(8); output.WriteEnum((int) Type); } - if (Data.Length != 0) { + if (Token.Length != 0) { output.WriteRawTag(18); + output.WriteString(Token); + } + if (Data.Length != 0) { + output.WriteRawTag(26); output.WriteBytes(Data); } } @@ -140,6 +159,9 @@ namespace Tango.PMR.Common { if (Type != 0) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type); } + if (Token.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Token); + } if (Data.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeBytesSize(Data); } @@ -154,6 +176,9 @@ namespace Tango.PMR.Common { if (other.Type != 0) { Type = other.Type; } + if (other.Token.Length != 0) { + Token = other.Token; + } if (other.Data.Length != 0) { Data = other.Data; } @@ -172,6 +197,10 @@ namespace Tango.PMR.Common { break; } case 18: { + Token = input.ReadString(); + break; + } + case 26: { Data = input.ReadBytes(); break; } diff --git a/Software/Visual Studio/Tango.PMR/Common/MessageType.cs b/Software/Visual Studio/Tango.PMR/Common/MessageType.cs index 667453399..c2ca7a47d 100644 --- a/Software/Visual Studio/Tango.PMR/Common/MessageType.cs +++ b/Software/Visual Studio/Tango.PMR/Common/MessageType.cs @@ -22,9 +22,10 @@ namespace Tango.PMR.Common { static MessageTypeReflection() { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( - "ChFNZXNzYWdlVHlwZS5wcm90bxIQVGFuZ28uUE1SLkNvbW1vbiosCgtNZXNz", - "YWdlVHlwZRIHCgNSR0IQABIHCgNKb2IQARILCgdTZWdtZW50EAJiBnByb3Rv", - "Mw==")); + "ChFNZXNzYWdlVHlwZS5wcm90bxIQVGFuZ28uUE1SLkNvbW1vbipRCgtNZXNz", + "YWdlVHlwZRIHCgNSR0IQABIHCgNKb2IQARILCgdTZWdtZW50EAISEAoMU3R1", + "YjFSZXF1ZXN0EAMSEQoNU3R1YjFSZXNwb25zZRAEQhwKGmNvbS50d2luZS50", + "YW5nby5wbXIuY29tbW9uYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Tango.PMR.Common.MessageType), }, null)); @@ -37,6 +38,8 @@ namespace Tango.PMR.Common { [pbr::OriginalName("RGB")] Rgb = 0, [pbr::OriginalName("Job")] Job = 1, [pbr::OriginalName("Segment")] Segment = 2, + [pbr::OriginalName("Stub1Request")] Stub1Request = 3, + [pbr::OriginalName("Stub1Response")] Stub1Response = 4, } #endregion diff --git a/Software/Visual Studio/Tango.PMR/Common/RGB.cs b/Software/Visual Studio/Tango.PMR/Common/RGB.cs index 3e69cf66c..23f335254 100644 --- a/Software/Visual Studio/Tango.PMR/Common/RGB.cs +++ b/Software/Visual Studio/Tango.PMR/Common/RGB.cs @@ -23,7 +23,8 @@ namespace Tango.PMR.Common { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( "CglSR0IucHJvdG8SEFRhbmdvLlBNUi5Db21tb24iJgoDUkdCEgkKAVIYASAB", - "KAUSCQoBRxgCIAEoBRIJCgFCGAMgASgFYgZwcm90bzM=")); + "KAUSCQoBRxgCIAEoBRIJCgFCGAMgASgFQhwKGmNvbS50d2luZS50YW5nby5w", + "bXIuY29tbW9uYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { diff --git a/Software/Visual Studio/Tango.PMR/Jobs/Job.cs b/Software/Visual Studio/Tango.PMR/Jobs/Job.cs index 543bc1e43..d505436d4 100644 --- a/Software/Visual Studio/Tango.PMR/Jobs/Job.cs +++ b/Software/Visual Studio/Tango.PMR/Jobs/Job.cs @@ -24,7 +24,8 @@ namespace Tango.PMR.Jobs { string.Concat( "CglKb2IucHJvdG8SDlRhbmdvLlBNUi5Kb2JzGg1TZWdtZW50LnByb3RvIj4K", "A0pvYhIMCgROYW1lGAEgASgJEikKCFNlZ21lbnRzGAIgAygLMhcuVGFuZ28u", - "UE1SLkpvYnMuU2VnbWVudGIGcHJvdG8z")); + "UE1SLkpvYnMuU2VnbWVudEIaChhjb20udHdpbmUudGFuZ28ucG1yLmpvYnNi", + "BnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Tango.PMR.Jobs.SegmentReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { diff --git a/Software/Visual Studio/Tango.PMR/Jobs/Segment.cs b/Software/Visual Studio/Tango.PMR/Jobs/Segment.cs index 2b2aa04de..440650812 100644 --- a/Software/Visual Studio/Tango.PMR/Jobs/Segment.cs +++ b/Software/Visual Studio/Tango.PMR/Jobs/Segment.cs @@ -24,7 +24,8 @@ namespace Tango.PMR.Jobs { string.Concat( "Cg1TZWdtZW50LnByb3RvEg5UYW5nby5QTVIuSm9icxoJUkdCLnByb3RvIk0K", "B1NlZ21lbnQSDAoETmFtZRgBIAEoCRIOCgZMZW5ndGgYAiABKAUSJAoFQ29s", - "b3IYAyABKAsyFS5UYW5nby5QTVIuQ29tbW9uLlJHQmIGcHJvdG8z")); + "b3IYAyABKAsyFS5UYW5nby5QTVIuQ29tbW9uLlJHQkIaChhjb20udHdpbmUu", + "dGFuZ28ucG1yLmpvYnNiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Tango.PMR.Common.RGBReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { diff --git a/Software/Visual Studio/Tango.PMR/MessageFactory.cs b/Software/Visual Studio/Tango.PMR/MessageFactory.cs index 9dc8643ee..b507b5c4e 100644 --- a/Software/Visual Studio/Tango.PMR/MessageFactory.cs +++ b/Software/Visual Studio/Tango.PMR/MessageFactory.cs @@ -25,6 +25,18 @@ namespace Tango.PMR } /// <summary> + /// Creates a new <see cref="TangoMessage{T}"/>. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <returns></returns> + public static TangoMessage<T> CreateContainer<T>(String token) where T : IMessage<T> + { + TangoMessage<T> message = new TangoMessage<T>(Activator.CreateInstance<T>(), (MessageType)Enum.Parse(typeof(MessageType), typeof(T).Name)); + message.Container.Token = token; + return message; + } + + /// <summary> /// Parses the specified <see cref="MessageContainer"/> bytes to <see cref="TangoMessage{T}"/>. /// </summary> /// <typeparam name="T"></typeparam> @@ -37,5 +49,37 @@ namespace Tango.PMR TangoMessage<T> tangoMessage = new TangoMessage<T>(parser.ParseFrom(container.Data), container.Type); return tangoMessage; } + + /// <summary> + /// Parses the specified <see cref="MessageContainer"/> bytes to <see cref="TangoMessage{T}"/>. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="data">The data.</param> + /// <returns></returns> + public static T ParseContainer<T>(MessageContainer container) where T : IMessage<T> + { + MessageParser<T> parser = new MessageParser<T>(() => Activator.CreateInstance<T>()); + return parser.ParseFrom(container.Data); + } + + + public static IMessage ParseContainer(MessageContainer container) + { + var type = typeof(MessageFactory).Assembly.GetTypes().ToList().SingleOrDefault(x => x.Name == container.Type.ToString()); + MessageParser parser = type.GetProperty("Parser").GetValue(container) as MessageParser; + return parser.ParseFrom(container.Data); + } + + /// <summary> + /// Parses the container partial. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="data">The data.</param> + /// <returns></returns> + public static MessageContainer ParseContainerPartial(byte[] data) + { + MessageContainer container = MessageContainer.Parser.ParseFrom(data); + return container; + } } } diff --git a/Software/Visual Studio/Tango.PMR/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.PMR/Properties/AssemblyInfo.cs index e795a8874..03126049b 100644 --- a/Software/Visual Studio/Tango.PMR/Properties/AssemblyInfo.cs +++ b/Software/Visual Studio/Tango.PMR/Properties/AssemblyInfo.cs @@ -2,5 +2,5 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -[assembly: AssemblyTitle("Twine - Protobuf Message Repository")] +[assembly: AssemblyTitle("Tango - Protobuf Message Repository")] [assembly: ComVisible(false)]
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.PMR/Stubs/Stub1.cs b/Software/Visual Studio/Tango.PMR/Stubs/Stub1.cs new file mode 100644 index 000000000..7d4960e9b --- /dev/null +++ b/Software/Visual Studio/Tango.PMR/Stubs/Stub1.cs @@ -0,0 +1,305 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Stub1.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Tango.PMR.Stubs { + + /// <summary>Holder for reflection information generated from Stub1.proto</summary> + public static partial class Stub1Reflection { + + #region Descriptor + /// <summary>File descriptor for Stub1.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static Stub1Reflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "CgtTdHViMS5wcm90bxIPVGFuZ28uUE1SLlN0dWJzIiQKDFN0dWIxUmVxdWVz", + "dBIJCgFBGAEgASgFEgkKAUIYAiABKAUiHAoNU3R1YjFSZXNwb25zZRILCgNT", + "dW0YASABKAVCGwoZY29tLnR3aW5lLnRhbmdvLnBtci5zdHVic2IGcHJvdG8z")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.Stub1Request), global::Tango.PMR.Stubs.Stub1Request.Parser, new[]{ "A", "B" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.Stub1Response), global::Tango.PMR.Stubs.Stub1Response.Parser, new[]{ "Sum" }, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class Stub1Request : pb::IMessage<Stub1Request> { + private static readonly pb::MessageParser<Stub1Request> _parser = new pb::MessageParser<Stub1Request>(() => new Stub1Request()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<Stub1Request> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Tango.PMR.Stubs.Stub1Reflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Stub1Request() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Stub1Request(Stub1Request other) : this() { + a_ = other.a_; + b_ = other.b_; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Stub1Request Clone() { + return new Stub1Request(this); + } + + /// <summary>Field number for the "A" field.</summary> + public const int AFieldNumber = 1; + private int a_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int A { + get { return a_; } + set { + a_ = value; + } + } + + /// <summary>Field number for the "B" field.</summary> + public const int BFieldNumber = 2; + private int b_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int B { + get { return b_; } + set { + b_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as Stub1Request); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(Stub1Request other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (A != other.A) return false; + if (B != other.B) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (A != 0) hash ^= A.GetHashCode(); + if (B != 0) hash ^= B.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (A != 0) { + output.WriteRawTag(8); + output.WriteInt32(A); + } + if (B != 0) { + output.WriteRawTag(16); + output.WriteInt32(B); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (A != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(A); + } + if (B != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(B); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(Stub1Request other) { + if (other == null) { + return; + } + if (other.A != 0) { + A = other.A; + } + if (other.B != 0) { + B = other.B; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 8: { + A = input.ReadInt32(); + break; + } + case 16: { + B = input.ReadInt32(); + break; + } + } + } + } + + } + + public sealed partial class Stub1Response : pb::IMessage<Stub1Response> { + private static readonly pb::MessageParser<Stub1Response> _parser = new pb::MessageParser<Stub1Response>(() => new Stub1Response()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<Stub1Response> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Tango.PMR.Stubs.Stub1Reflection.Descriptor.MessageTypes[1]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Stub1Response() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Stub1Response(Stub1Response other) : this() { + sum_ = other.sum_; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Stub1Response Clone() { + return new Stub1Response(this); + } + + /// <summary>Field number for the "Sum" field.</summary> + public const int SumFieldNumber = 1; + private int sum_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int Sum { + get { return sum_; } + set { + sum_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as Stub1Response); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(Stub1Response other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Sum != other.Sum) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Sum != 0) hash ^= Sum.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (Sum != 0) { + output.WriteRawTag(8); + output.WriteInt32(Sum); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Sum != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Sum); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(Stub1Response other) { + if (other == null) { + return; + } + if (other.Sum != 0) { + Sum = other.Sum; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 8: { + Sum = input.ReadInt32(); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/Software/Visual Studio/Tango.PMR/Tango.PMR.csproj b/Software/Visual Studio/Tango.PMR/Tango.PMR.csproj index 93f2f41d8..8039b352a 100644 --- a/Software/Visual Studio/Tango.PMR/Tango.PMR.csproj +++ b/Software/Visual Studio/Tango.PMR/Tango.PMR.csproj @@ -53,6 +53,7 @@ <Compile Include="Jobs\Segment.cs" /> <Compile Include="MessageFactory.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Stubs\Stub1.cs" /> <Compile Include="TangoMessage.cs" /> </ItemGroup> <ItemGroup> diff --git a/Software/Visual Studio/Tango.PMR/TangoMessage.cs b/Software/Visual Studio/Tango.PMR/TangoMessage.cs index 98cfdebe5..71d4a046b 100644 --- a/Software/Visual Studio/Tango.PMR/TangoMessage.cs +++ b/Software/Visual Studio/Tango.PMR/TangoMessage.cs @@ -16,6 +16,11 @@ namespace Tango.PMR public class TangoMessage<T> where T : IMessage<T> { /// <summary> + /// Gets the container. + /// </summary> + public MessageContainer Container { get; } + + /// <summary> /// Gets or sets the message. /// </summary> public T Message { get; set; } @@ -34,6 +39,10 @@ namespace Tango.PMR { Message = message; Type = type; + + Container = new MessageContainer(); + Container.Token = Guid.NewGuid().ToString(); + Container.Type = Type; } /// <summary> @@ -42,13 +51,11 @@ namespace Tango.PMR /// <returns></returns> public byte[] ToBytes() { - MessageContainer container = new MessageContainer(); - container.Type = Type; - container.Data = Message.ToByteString(); + Container.Data = Message.ToByteString(); using (MemoryStream ms = new MemoryStream()) { - container.WriteTo(ms); + Container.WriteTo(ms); return ms.ToArray(); } } diff --git a/Software/Visual Studio/Tango.Protobuf/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.Protobuf/Properties/AssemblyInfo.cs index 37ad6afb4..2296973b8 100644 --- a/Software/Visual Studio/Tango.Protobuf/Properties/AssemblyInfo.cs +++ b/Software/Visual Studio/Tango.Protobuf/Properties/AssemblyInfo.cs @@ -2,5 +2,5 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -[assembly: AssemblyTitle("Twine - Protobuf Components")] +[assembly: AssemblyTitle("Tango - Protobuf Components")] [assembly: ComVisible(false)]
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.SharedUI/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.SharedUI/Properties/AssemblyInfo.cs index ee384bb30..f30c525cc 100644 --- a/Software/Visual Studio/Tango.SharedUI/Properties/AssemblyInfo.cs +++ b/Software/Visual Studio/Tango.SharedUI/Properties/AssemblyInfo.cs @@ -2,5 +2,5 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -[assembly: AssemblyTitle("Twine - Shared UI Components")] +[assembly: AssemblyTitle("Tango - Shared UI Components")] [assembly: ComVisible(false)]
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.UnitTesting/Properties/AssemblyInfo.cs b/Software/Visual Studio/Tango.UnitTesting/Properties/AssemblyInfo.cs index d4438885e..0551f8f77 100644 --- a/Software/Visual Studio/Tango.UnitTesting/Properties/AssemblyInfo.cs +++ b/Software/Visual Studio/Tango.UnitTesting/Properties/AssemblyInfo.cs @@ -2,5 +2,5 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -[assembly: AssemblyTitle("Twine - Unit Testing")] +[assembly: AssemblyTitle("Tango - Unit Testing")] [assembly: ComVisible(false)]
\ No newline at end of file diff --git a/Software/Visual Studio/Tango.sln b/Software/Visual Studio/Tango.sln index 3013eef96..e1d820bea 100644 --- a/Software/Visual Studio/Tango.sln +++ b/Software/Visual Studio/Tango.sln @@ -31,6 +31,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Resources", "Resources", "{ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.PMR", "Tango.PMR\Tango.PMR.csproj", "{E4927038-348D-4295-AAF4-861C58CB3943}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Emulator", "Tango.Emulator\Tango.Emulator.csproj", "{FA15BBFC-AEAF-4364-9F90-CE4EFCE661FE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Integration", "Tango.Integration\Tango.Integration.csproj", "{B6182925-8864-401F-A390-6EFF737C4FC7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -69,6 +73,14 @@ Global {E4927038-348D-4295-AAF4-861C58CB3943}.Debug|Any CPU.Build.0 = Debug|Any CPU {E4927038-348D-4295-AAF4-861C58CB3943}.Release|Any CPU.ActiveCfg = Release|Any CPU {E4927038-348D-4295-AAF4-861C58CB3943}.Release|Any CPU.Build.0 = Release|Any CPU + {FA15BBFC-AEAF-4364-9F90-CE4EFCE661FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA15BBFC-AEAF-4364-9F90-CE4EFCE661FE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA15BBFC-AEAF-4364-9F90-CE4EFCE661FE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA15BBFC-AEAF-4364-9F90-CE4EFCE661FE}.Release|Any CPU.Build.0 = Release|Any CPU + {B6182925-8864-401F-A390-6EFF737C4FC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B6182925-8864-401F-A390-6EFF737C4FC7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B6182925-8864-401F-A390-6EFF737C4FC7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B6182925-8864-401F-A390-6EFF737C4FC7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Program.cs b/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Program.cs index 7232a9b6d..76b91d4da 100644 --- a/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Program.cs +++ b/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Program.cs @@ -47,12 +47,12 @@ namespace Tango.Protobuf.CLI } } - return ExitSuccess("Folder compiled to " + Path.GetFullPath(options.SourceFolder)); + return ExitSuccess("Protobuf folder compiled to " + Path.GetFullPath(options.SourceFolder)); } private static int ExitSuccess(String text) { - Console.WriteLine("Done!"); + Console.WriteLine(text); return 0; } diff --git a/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Properties/AssemblyInfo.cs b/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Properties/AssemblyInfo.cs index 00ace1d5d..316919706 100644 --- a/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Properties/AssemblyInfo.cs +++ b/Software/Visual Studio/Utilities/Tango.Protobuf.CLI/Properties/AssemblyInfo.cs @@ -2,5 +2,5 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -[assembly: AssemblyTitle("Twine - Protobuf Compilation CLI")] +[assembly: AssemblyTitle("Tango - Protobuf Compilation CLI")] [assembly: ComVisible(false)]
\ No newline at end of file diff --git a/Software/Visual Studio/Utilities/Tango.Protobuf.UI/Properties/AssemblyInfo.cs b/Software/Visual Studio/Utilities/Tango.Protobuf.UI/Properties/AssemblyInfo.cs index 002635e32..f391aa2a5 100644 --- a/Software/Visual Studio/Utilities/Tango.Protobuf.UI/Properties/AssemblyInfo.cs +++ b/Software/Visual Studio/Utilities/Tango.Protobuf.UI/Properties/AssemblyInfo.cs @@ -2,5 +2,5 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -[assembly: AssemblyTitle("Twine - Protobuf Compilation Utility")] +[assembly: AssemblyTitle("Tango - Protobuf Compilation Utility")] [assembly: ComVisible(false)]
\ No newline at end of file |
