aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2017-11-16 13:38:56 +0200
committerRoy Ben-Shabat <Roy@Twine-s.com>2017-11-16 13:38:56 +0200
commit914f4db513477d9aff726546bac47545195a3e37 (patch)
treed2ff190fd84b1dfaa03eec76563c431592ece7ff /Software/Visual_Studio
parent65d01ff549d80fbe13ff5e966df216c9f7c03653 (diff)
downloadTango-914f4db513477d9aff726546bac47545195a3e37.tar.gz
Tango-914f4db513477d9aff726546bac47545195a3e37.zip
Rename "Visual Studio" to "Visual_Studio"
Rename "External Repositories" to "External_Repositories".
Diffstat (limited to 'Software/Visual_Studio')
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateRequest.pb.cc444
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateRequest.pb.h220
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateResponse.pb.cc389
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateResponse.pb.h199
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Job.pb.cc525
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Job.pb.h290
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageContainer.pb.cc712
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageContainer.pb.h378
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageType.pb.cc138
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageType.pb.h123
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressRequest.pb.cc332
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressRequest.pb.h178
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressResponse.pb.cc389
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressResponse.pb.h199
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/RGB.pb.cc499
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/RGB.pb.h241
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Segment.pb.cc597
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Segment.pb.h318
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/ProtoTester.cpp18
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/ProtoTester.h42
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/Tango.ProtoTest.vcxproj151
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/Tango.ProtoTest.vcxproj.filters84
-rw-r--r--Software/Visual_Studio/Native/Tango.ProtoTest/libprotobuf.libbin0 -> 185734154 bytes
-rw-r--r--Software/Visual_Studio/Resources/dummyFile.txt1
-rw-r--r--Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs137
-rw-r--r--Software/Visual_Studio/Tango.Core/ExtensionMethods/EnumExtensions.cs33
-rw-r--r--Software/Visual_Studio/Tango.Core/ExtensionMethods/IMessageExtensions.cs25
-rw-r--r--Software/Visual_Studio/Tango.Core/ExtensionMethods/IParameterizedExtensions.cs124
-rw-r--r--Software/Visual_Studio/Tango.Core/ExtensionMethods/StringExtensions.cs52
-rw-r--r--Software/Visual_Studio/Tango.Core/Helpers/AssemblyHelper.cs21
-rw-r--r--Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs32
-rw-r--r--Software/Visual_Studio/Tango.Core/IParameterized.cs21
-rw-r--r--Software/Visual_Studio/Tango.Core/ParameterIgnoreAttribute.cs17
-rw-r--r--Software/Visual_Studio/Tango.Core/ParameterItem.cs157
-rw-r--r--Software/Visual_Studio/Tango.Core/ParameterItemAttribute.cs140
-rw-r--r--Software/Visual_Studio/Tango.Core/ParameterItemMode.cs23
-rw-r--r--Software/Visual_Studio/Tango.Core/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Tango.Core/Tango.Core.csproj72
-rw-r--r--Software/Visual_Studio/Tango.Core/packages.config4
-rw-r--r--Software/Visual_Studio/Tango.Emulations/EmulatorBase.cs172
-rw-r--r--Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs87
-rw-r--r--Software/Visual_Studio/Tango.Emulations/Emulators/MobileEmulator.cs62
-rw-r--r--Software/Visual_Studio/Tango.Emulations/IEmulator.cs43
-rw-r--r--Software/Visual_Studio/Tango.Emulations/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Tango.Emulations/Tango.Emulations.csproj81
-rw-r--r--Software/Visual_Studio/Tango.Emulations/packages.config4
-rw-r--r--Software/Visual_Studio/Tango.Logging/ApplicationCrashedEventArgs.cs34
-rw-r--r--Software/Visual_Studio/Tango.Logging/ConsoleLogger.cs104
-rw-r--r--Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml12
-rw-r--r--Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml.cs150
-rw-r--r--Software/Visual_Studio/Tango.Logging/ExceptionLogItem.cs34
-rw-r--r--Software/Visual_Studio/Tango.Logging/FileLogger.cs83
-rw-r--r--Software/Visual_Studio/Tango.Logging/GlobalExceptionTrapper.cs106
-rw-r--r--Software/Visual_Studio/Tango.Logging/IGlobalExceptionTrapper.cs19
-rw-r--r--Software/Visual_Studio/Tango.Logging/ILogger.cs36
-rw-r--r--Software/Visual_Studio/Tango.Logging/LogItemBase.cs39
-rw-r--r--Software/Visual_Studio/Tango.Logging/LogManager.cs220
-rw-r--r--Software/Visual_Studio/Tango.Logging/MessageLogItem.cs28
-rw-r--r--Software/Visual_Studio/Tango.Logging/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Tango.Logging/Tango.Logging.csproj80
-rw-r--r--Software/Visual_Studio/Tango.Logging/VSOutputLogger.cs64
-rw-r--r--Software/Visual_Studio/Tango.PMR/Common/MessageContainer.cs274
-rw-r--r--Software/Visual_Studio/Tango.PMR/Common/MessageType.cs52
-rw-r--r--Software/Visual_Studio/Tango.PMR/Common/RGB.cs215
-rw-r--r--Software/Visual_Studio/Tango.PMR/Jobs/Job.cs180
-rw-r--r--Software/Visual_Studio/Tango.PMR/Jobs/Segment.cs222
-rw-r--r--Software/Visual_Studio/Tango.PMR/MessageFactory.cs125
-rw-r--r--Software/Visual_Studio/Tango.PMR/NativePMR.cs79
-rw-r--r--Software/Visual_Studio/Tango.PMR/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Tango.PMR/Stubs/CalculateRequest.cs187
-rw-r--r--Software/Visual_Studio/Tango.PMR/Stubs/CalculateResponse.cs159
-rw-r--r--Software/Visual_Studio/Tango.PMR/Stubs/ProgressRequest.cs131
-rw-r--r--Software/Visual_Studio/Tango.PMR/Stubs/ProgressResponse.cs159
-rw-r--r--Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj70
-rw-r--r--Software/Visual_Studio/Tango.PMR/TangoMessage.cs111
-rw-r--r--Software/Visual_Studio/Tango.PMR/packages.config4
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/CompilerException.cs41
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/CompilerFactory.cs73
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/CompilerFileResult.cs81
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/CompilerFolderResult.cs100
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/CompilerLanguage.cs36
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Compilers/CCompiler.cs41
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Compilers/CSharpCompiler.cs29
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Compilers/CppCompiler.cs34
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Compilers/JavaCompiler.cs37
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Compilers/PythonCompiler.cs29
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/ICompilerResult.cs35
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/IProtoCompiler.cs57
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/ProtoCompiler.cs317
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-1.0M4.jarbin0 -> 3190277 bytes
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-c.exebin0 -> 3702784 bytes
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc.exebin0 -> 4418048 bytes
-rw-r--r--Software/Visual_Studio/Tango.Protobuf/Tango.Protobuf.csproj83
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Commands/RelayCommand.cs128
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml11
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml.cs473
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Controls/TransitionTypeEnum.cs42
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/BooleanInverseConverter.cs46
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/BooleanToVisibilityConverter.cs44
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/BooleanToVisibilityInverseConverter.cs44
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/DoubleToIntConverter.cs23
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/EnumToDescriptionConverter.cs64
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/EnumToItemsSourceConverter.cs24
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/IsEnumConverter.cs24
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/IsNullConverter.cs23
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/NullObjectToBooleanConverter.cs46
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/ParameterItemEditorTypeToEditorConverter.cs47
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/PathToShortPathConverter.cs37
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Converters/StringFormatConverter.cs42
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Editors/IParameterItemEditor.cs45
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Editors/ParameterItemEditor.cs58
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml45
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml.cs177
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml129
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml.cs242
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/ExtendedObject.cs53
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj104
-rw-r--r--Software/Visual_Studio/Tango.SharedUI/packages.config4
-rw-r--r--Software/Visual_Studio/Tango.Stubs/AvailableStub.cs30
-rw-r--r--Software/Visual_Studio/Tango.Stubs/IStub.cs16
-rw-r--r--Software/Visual_Studio/Tango.Stubs/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Tango.Stubs/StubAttribute.cs24
-rw-r--r--Software/Visual_Studio/Tango.Stubs/StubBase.cs87
-rw-r--r--Software/Visual_Studio/Tango.Stubs/StubDirection.cs15
-rw-r--r--Software/Visual_Studio/Tango.Stubs/StubState.cs17
-rw-r--r--Software/Visual_Studio/Tango.Stubs/Stubs/Calculate.cs40
-rw-r--r--Software/Visual_Studio/Tango.Stubs/Stubs/Progress.cs30
-rw-r--r--Software/Visual_Studio/Tango.Stubs/Tango.Stubs.csproj93
-rw-r--r--Software/Visual_Studio/Tango.Stubs/packages.config4
-rw-r--r--Software/Visual_Studio/Tango.Transport/Adapters/SplitterAdapter.cs26
-rw-r--r--Software/Visual_Studio/Tango.Transport/Adapters/TcpTransportAdapter.cs198
-rw-r--r--Software/Visual_Studio/Tango.Transport/Adapters/UsbTransportAdapter.cs150
-rw-r--r--Software/Visual_Studio/Tango.Transport/ITransportAdapter.cs33
-rw-r--r--Software/Visual_Studio/Tango.Transport/ITransportComponent.cs33
-rw-r--r--Software/Visual_Studio/Tango.Transport/ITransporter.cs95
-rw-r--r--Software/Visual_Studio/Tango.Transport/PendingResponse.cs35
-rw-r--r--Software/Visual_Studio/Tango.Transport/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Tango.Transport/Servers/ClientConnectedEventArgs.cs30
-rw-r--r--Software/Visual_Studio/Tango.Transport/Servers/TcpServer.cs124
-rw-r--r--Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj107
-rw-r--r--Software/Visual_Studio/Tango.Transport/TransportAdapterBase.cs132
-rw-r--r--Software/Visual_Studio/Tango.Transport/TransportComponentState.cs31
-rw-r--r--Software/Visual_Studio/Tango.Transport/TransportMessage.cs62
-rw-r--r--Software/Visual_Studio/Tango.Transport/TransportMessageBase.cs78
-rw-r--r--Software/Visual_Studio/Tango.Transport/TransportMessageDirection.cs23
-rw-r--r--Software/Visual_Studio/Tango.Transport/TransporterBase.cs574
-rw-r--r--Software/Visual_Studio/Tango.Transport/Transporters/JsonTransporter.cs60
-rw-r--r--Software/Visual_Studio/Tango.Transport/Transporters/ProtoTransporter.cs47
-rw-r--r--Software/Visual_Studio/Tango.Transport/packages.config10
-rw-r--r--Software/Visual_Studio/Tango.UnitTesting/Helper.cs102
-rw-r--r--Software/Visual_Studio/Tango.UnitTesting/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Tango.UnitTesting/Protobuf_TST.cs115
-rw-r--r--Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj100
-rw-r--r--Software/Visual_Studio/Tango.UnitTesting/packages.config7
-rw-r--r--Software/Visual_Studio/Tango.sln235
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/App.config6
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/App.xaml26
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/App.xaml.cs17
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Images/machine-trans.pngbin0 -> 45618 bytes
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/MainWindow.xaml16
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/MainWindow.xaml.cs33
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Properties/Resources.Designer.cs71
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Properties/Resources.resx117
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Properties/Settings.Designer.cs30
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Properties/Settings.settings7
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Tango.MachineEM.UI.csproj156
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/ViewModels/MainViewVM.cs242
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Views/MainView.xaml154
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Views/MainView.xaml.cs33
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MachineEM.UI/packages.config6
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.config6
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.xaml28
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.xaml.cs27
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Images/phone.pngbin0 -> 72384 bytes
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml81
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml.cs48
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Properties/Resources.Designer.cs71
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Properties/Resources.resx117
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Properties/Settings.Designer.cs30
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Properties/Settings.settings7
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Tango.MobileEM.UI.csproj173
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainViewVM.cs30
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainWindowVM.cs41
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubViewVM.cs65
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubsViewVM.cs42
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml29
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml.cs29
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml73
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml.cs33
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml28
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml.cs36
-rw-r--r--Software/Visual_Studio/Utilities/Tango.MobileEM.UI/packages.config6
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/App.config6
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Options.cs32
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Program.cs88
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Tango.Protobuf.CLI.csproj65
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/packages.config4
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/App.config6
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/App.xaml20
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/App.xaml.cs59
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/DirectoryItem.cs18
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/ExceptionWindow.xaml40
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/ExceptionWindow.xaml.cs31
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/FileItem.cs17
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Item.cs15
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/ItemProvider.cs44
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/MainWindow.xaml144
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/MainWindow.xaml.cs148
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Properties/AssemblyInfo.cs6
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Properties/Resources.Designer.cs71
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Properties/Resources.resx117
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Properties/Settings.Designer.cs30
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Properties/Settings.settings7
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Tango.Protobuf.UI.csproj151
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/packages.config7
-rw-r--r--Software/Visual_Studio/Utilities/Tango.Protobuf.UI/proto.icobin0 -> 370070 bytes
-rw-r--r--Software/Visual_Studio/Versioning/GlobalVersionInfo.cs13
222 files changed, 19607 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateRequest.pb.cc b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateRequest.pb.cc
new file mode 100644
index 000000000..240b597f4
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateRequest.pb.cc
@@ -0,0 +1,444 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: CalculateRequest.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "CalculateRequest.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace Tango {
+namespace PMR {
+namespace Stubs {
+class CalculateRequestDefaultTypeInternal {
+public:
+ ::google::protobuf::internal::ExplicitlyConstructed<CalculateRequest>
+ _instance;
+} _CalculateRequest_default_instance_;
+
+namespace protobuf_CalculateRequest_2eproto {
+
+
+namespace {
+
+::google::protobuf::Metadata file_level_metadata[1];
+
+} // namespace
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+ const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+ const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+ TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { NULL, NULL, 0, -1, -1, -1, -1, NULL, false },
+};
+
+const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ~0u, // no _has_bits_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CalculateRequest, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CalculateRequest, a_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CalculateRequest, b_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, sizeof(CalculateRequest)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::google::protobuf::Message*>(&_CalculateRequest_default_instance_),
+};
+
+namespace {
+
+void protobuf_AssignDescriptors() {
+ AddDescriptors();
+ ::google::protobuf::MessageFactory* factory = NULL;
+ AssignDescriptors(
+ "CalculateRequest.proto", schemas, file_default_instances, TableStruct::offsets, factory,
+ file_level_metadata, NULL, NULL);
+}
+
+void protobuf_AssignDescriptorsOnce() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
+void protobuf_RegisterTypes(const ::std::string&) {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
+}
+
+} // namespace
+void TableStruct::InitDefaultsImpl() {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ ::google::protobuf::internal::InitProtobufDefaults();
+ _CalculateRequest_default_instance_._instance.DefaultConstruct();
+ ::google::protobuf::internal::OnShutdownDestroyMessage(
+ &_CalculateRequest_default_instance_);}
+
+void InitDefaults() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl);
+}
+namespace {
+void AddDescriptorsImpl() {
+ InitDefaults();
+ static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ "\n\026CalculateRequest.proto\022\017Tango.PMR.Stub"
+ "s\"(\n\020CalculateRequest\022\t\n\001A\030\001 \001(\001\022\t\n\001B\030\002 "
+ "\001(\001B\033\n\031com.twine.tango.pmr.stubsb\006proto3"
+ };
+ ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+ descriptor, 120);
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+ "CalculateRequest.proto", &protobuf_RegisterTypes);
+}
+} // anonymous namespace
+
+void AddDescriptors() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
+}
+// Force AddDescriptors() to be called at dynamic initialization time.
+struct StaticDescriptorInitializer {
+ StaticDescriptorInitializer() {
+ AddDescriptors();
+ }
+} static_descriptor_initializer;
+
+} // namespace protobuf_CalculateRequest_2eproto
+
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int CalculateRequest::kAFieldNumber;
+const int CalculateRequest::kBFieldNumber;
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+CalculateRequest::CalculateRequest()
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+ if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
+ protobuf_CalculateRequest_2eproto::InitDefaults();
+ }
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:Tango.PMR.Stubs.CalculateRequest)
+}
+CalculateRequest::CalculateRequest(const CalculateRequest& from)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL),
+ _cached_size_(0) {
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ ::memcpy(&a_, &from.a_,
+ static_cast<size_t>(reinterpret_cast<char*>(&b_) -
+ reinterpret_cast<char*>(&a_)) + sizeof(b_));
+ // @@protoc_insertion_point(copy_constructor:Tango.PMR.Stubs.CalculateRequest)
+}
+
+void CalculateRequest::SharedCtor() {
+ ::memset(&a_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&b_) -
+ reinterpret_cast<char*>(&a_)) + sizeof(b_));
+ _cached_size_ = 0;
+}
+
+CalculateRequest::~CalculateRequest() {
+ // @@protoc_insertion_point(destructor:Tango.PMR.Stubs.CalculateRequest)
+ SharedDtor();
+}
+
+void CalculateRequest::SharedDtor() {
+}
+
+void CalculateRequest::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* CalculateRequest::descriptor() {
+ protobuf_CalculateRequest_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_CalculateRequest_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
+}
+
+const CalculateRequest& CalculateRequest::default_instance() {
+ protobuf_CalculateRequest_2eproto::InitDefaults();
+ return *internal_default_instance();
+}
+
+CalculateRequest* CalculateRequest::New(::google::protobuf::Arena* arena) const {
+ CalculateRequest* n = new CalculateRequest;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
+}
+
+void CalculateRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:Tango.PMR.Stubs.CalculateRequest)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ ::memset(&a_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&b_) -
+ reinterpret_cast<char*>(&a_)) + sizeof(b_));
+ _internal_metadata_.Clear();
+}
+
+bool CalculateRequest::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:Tango.PMR.Stubs.CalculateRequest)
+ for (;;) {
+ ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+ tag = p.first;
+ if (!p.second) goto handle_unusual;
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // double A = 1;
+ case 1: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(9u /* 9 & 0xFF */)) {
+
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
+ input, &a_)));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ // double B = 2;
+ case 2: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(17u /* 17 & 0xFF */)) {
+
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
+ input, &b_)));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ default: {
+ handle_unusual:
+ if (tag == 0) {
+ goto success;
+ }
+ DO_(::google::protobuf::internal::WireFormat::SkipField(
+ input, tag, _internal_metadata_.mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+success:
+ // @@protoc_insertion_point(parse_success:Tango.PMR.Stubs.CalculateRequest)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:Tango.PMR.Stubs.CalculateRequest)
+ return false;
+#undef DO_
+}
+
+void CalculateRequest::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:Tango.PMR.Stubs.CalculateRequest)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // double A = 1;
+ if (this->a() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->a(), output);
+ }
+
+ // double B = 2;
+ if (this->b() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->b(), output);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output);
+ }
+ // @@protoc_insertion_point(serialize_end:Tango.PMR.Stubs.CalculateRequest)
+}
+
+::google::protobuf::uint8* CalculateRequest::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
+ (void)deterministic; // Unused
+ // @@protoc_insertion_point(serialize_to_array_start:Tango.PMR.Stubs.CalculateRequest)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // double A = 1;
+ if (this->a() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->a(), target);
+ }
+
+ // double B = 2;
+ if (this->b() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(2, this->b(), target);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:Tango.PMR.Stubs.CalculateRequest)
+ return target;
+}
+
+size_t CalculateRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:Tango.PMR.Stubs.CalculateRequest)
+ size_t total_size = 0;
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ total_size +=
+ ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()));
+ }
+ // double A = 1;
+ if (this->a() != 0) {
+ total_size += 1 + 8;
+ }
+
+ // double B = 2;
+ if (this->b() != 0) {
+ total_size += 1 + 8;
+ }
+
+ int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = cached_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void CalculateRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:Tango.PMR.Stubs.CalculateRequest)
+ GOOGLE_DCHECK_NE(&from, this);
+ const CalculateRequest* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const CalculateRequest>(
+ &from);
+ if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Tango.PMR.Stubs.CalculateRequest)
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Tango.PMR.Stubs.CalculateRequest)
+ MergeFrom(*source);
+ }
+}
+
+void CalculateRequest::MergeFrom(const CalculateRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:Tango.PMR.Stubs.CalculateRequest)
+ GOOGLE_DCHECK_NE(&from, this);
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from.a() != 0) {
+ set_a(from.a());
+ }
+ if (from.b() != 0) {
+ set_b(from.b());
+ }
+}
+
+void CalculateRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Tango.PMR.Stubs.CalculateRequest)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void CalculateRequest::CopyFrom(const CalculateRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Tango.PMR.Stubs.CalculateRequest)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool CalculateRequest::IsInitialized() const {
+ return true;
+}
+
+void CalculateRequest::Swap(CalculateRequest* other) {
+ if (other == this) return;
+ InternalSwap(other);
+}
+void CalculateRequest::InternalSwap(CalculateRequest* other) {
+ using std::swap;
+ swap(a_, other->a_);
+ swap(b_, other->b_);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata CalculateRequest::GetMetadata() const {
+ protobuf_CalculateRequest_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_CalculateRequest_2eproto::file_level_metadata[kIndexInFileMessages];
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// CalculateRequest
+
+// double A = 1;
+void CalculateRequest::clear_a() {
+ a_ = 0;
+}
+double CalculateRequest::a() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Stubs.CalculateRequest.A)
+ return a_;
+}
+void CalculateRequest::set_a(double value) {
+
+ a_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Stubs.CalculateRequest.A)
+}
+
+// double B = 2;
+void CalculateRequest::clear_b() {
+ b_ = 0;
+}
+double CalculateRequest::b() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Stubs.CalculateRequest.B)
+ return b_;
+}
+void CalculateRequest::set_b(double value) {
+
+ b_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Stubs.CalculateRequest.B)
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace Stubs
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateRequest.pb.h b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateRequest.pb.h
new file mode 100644
index 000000000..3e527af42
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateRequest.pb.h
@@ -0,0 +1,220 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: CalculateRequest.proto
+
+#ifndef PROTOBUF_CalculateRequest_2eproto__INCLUDED
+#define PROTOBUF_CalculateRequest_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 3004000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3004000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h> // IWYU pragma: export
+#include <google/protobuf/extension_set.h> // IWYU pragma: export
+#include <google/protobuf/unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+namespace Tango {
+namespace PMR {
+namespace Stubs {
+class CalculateRequest;
+class CalculateRequestDefaultTypeInternal;
+extern CalculateRequestDefaultTypeInternal _CalculateRequest_default_instance_;
+} // namespace Stubs
+} // namespace PMR
+} // namespace Tango
+
+namespace Tango {
+namespace PMR {
+namespace Stubs {
+
+namespace protobuf_CalculateRequest_2eproto {
+// Internal implementation detail -- do not call these.
+struct TableStruct {
+ static const ::google::protobuf::internal::ParseTableField entries[];
+ static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+ static const ::google::protobuf::internal::ParseTable schema[];
+ static const ::google::protobuf::uint32 offsets[];
+ static const ::google::protobuf::internal::FieldMetadata field_metadata[];
+ static const ::google::protobuf::internal::SerializationTable serialization_table[];
+ static void InitDefaultsImpl();
+};
+void AddDescriptors();
+void InitDefaults();
+} // namespace protobuf_CalculateRequest_2eproto
+
+// ===================================================================
+
+class CalculateRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Tango.PMR.Stubs.CalculateRequest) */ {
+ public:
+ CalculateRequest();
+ virtual ~CalculateRequest();
+
+ CalculateRequest(const CalculateRequest& from);
+
+ inline CalculateRequest& operator=(const CalculateRequest& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ #if LANG_CXX11
+ CalculateRequest(CalculateRequest&& from) noexcept
+ : CalculateRequest() {
+ *this = ::std::move(from);
+ }
+
+ inline CalculateRequest& operator=(CalculateRequest&& from) noexcept {
+ if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+ if (this != &from) InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+ #endif
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const CalculateRequest& default_instance();
+
+ static inline const CalculateRequest* internal_default_instance() {
+ return reinterpret_cast<const CalculateRequest*>(
+ &_CalculateRequest_default_instance_);
+ }
+ static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+ 0;
+
+ void Swap(CalculateRequest* other);
+ friend void swap(CalculateRequest& a, CalculateRequest& b) {
+ a.Swap(&b);
+ }
+
+ // implements Message ----------------------------------------------
+
+ inline CalculateRequest* New() const PROTOBUF_FINAL { return New(NULL); }
+
+ CalculateRequest* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+ void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void CopyFrom(const CalculateRequest& from);
+ void MergeFrom(const CalculateRequest& from);
+ void Clear() PROTOBUF_FINAL;
+ bool IsInitialized() const PROTOBUF_FINAL;
+
+ size_t ByteSizeLong() const PROTOBUF_FINAL;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
+ int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const PROTOBUF_FINAL;
+ void InternalSwap(CalculateRequest* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return NULL;
+ }
+ inline void* MaybeArenaPtr() const {
+ return NULL;
+ }
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // double A = 1;
+ void clear_a();
+ static const int kAFieldNumber = 1;
+ double a() const;
+ void set_a(double value);
+
+ // double B = 2;
+ void clear_b();
+ static const int kBFieldNumber = 2;
+ double b() const;
+ void set_b(double value);
+
+ // @@protoc_insertion_point(class_scope:Tango.PMR.Stubs.CalculateRequest)
+ private:
+
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ double a_;
+ double b_;
+ mutable int _cached_size_;
+ friend struct protobuf_CalculateRequest_2eproto::TableStruct;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// CalculateRequest
+
+// double A = 1;
+inline void CalculateRequest::clear_a() {
+ a_ = 0;
+}
+inline double CalculateRequest::a() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Stubs.CalculateRequest.A)
+ return a_;
+}
+inline void CalculateRequest::set_a(double value) {
+
+ a_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Stubs.CalculateRequest.A)
+}
+
+// double B = 2;
+inline void CalculateRequest::clear_b() {
+ b_ = 0;
+}
+inline double CalculateRequest::b() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Stubs.CalculateRequest.B)
+ return b_;
+}
+inline void CalculateRequest::set_b(double value) {
+
+ b_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Stubs.CalculateRequest.B)
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+
+} // namespace Stubs
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_CalculateRequest_2eproto__INCLUDED
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateResponse.pb.cc b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateResponse.pb.cc
new file mode 100644
index 000000000..d7c9ab538
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateResponse.pb.cc
@@ -0,0 +1,389 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: CalculateResponse.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "CalculateResponse.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace Tango {
+namespace PMR {
+namespace Stubs {
+class CalculateResponseDefaultTypeInternal {
+public:
+ ::google::protobuf::internal::ExplicitlyConstructed<CalculateResponse>
+ _instance;
+} _CalculateResponse_default_instance_;
+
+namespace protobuf_CalculateResponse_2eproto {
+
+
+namespace {
+
+::google::protobuf::Metadata file_level_metadata[1];
+
+} // namespace
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+ const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+ const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+ TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { NULL, NULL, 0, -1, -1, -1, -1, NULL, false },
+};
+
+const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ~0u, // no _has_bits_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CalculateResponse, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CalculateResponse, sum_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, sizeof(CalculateResponse)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::google::protobuf::Message*>(&_CalculateResponse_default_instance_),
+};
+
+namespace {
+
+void protobuf_AssignDescriptors() {
+ AddDescriptors();
+ ::google::protobuf::MessageFactory* factory = NULL;
+ AssignDescriptors(
+ "CalculateResponse.proto", schemas, file_default_instances, TableStruct::offsets, factory,
+ file_level_metadata, NULL, NULL);
+}
+
+void protobuf_AssignDescriptorsOnce() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
+void protobuf_RegisterTypes(const ::std::string&) {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
+}
+
+} // namespace
+void TableStruct::InitDefaultsImpl() {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ ::google::protobuf::internal::InitProtobufDefaults();
+ _CalculateResponse_default_instance_._instance.DefaultConstruct();
+ ::google::protobuf::internal::OnShutdownDestroyMessage(
+ &_CalculateResponse_default_instance_);}
+
+void InitDefaults() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl);
+}
+namespace {
+void AddDescriptorsImpl() {
+ InitDefaults();
+ static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ "\n\027CalculateResponse.proto\022\017Tango.PMR.Stu"
+ "bs\" \n\021CalculateResponse\022\013\n\003Sum\030\001 \001(\001B\033\n\031"
+ "com.twine.tango.pmr.stubsb\006proto3"
+ };
+ ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+ descriptor, 113);
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+ "CalculateResponse.proto", &protobuf_RegisterTypes);
+}
+} // anonymous namespace
+
+void AddDescriptors() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
+}
+// Force AddDescriptors() to be called at dynamic initialization time.
+struct StaticDescriptorInitializer {
+ StaticDescriptorInitializer() {
+ AddDescriptors();
+ }
+} static_descriptor_initializer;
+
+} // namespace protobuf_CalculateResponse_2eproto
+
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int CalculateResponse::kSumFieldNumber;
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+CalculateResponse::CalculateResponse()
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+ if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
+ protobuf_CalculateResponse_2eproto::InitDefaults();
+ }
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:Tango.PMR.Stubs.CalculateResponse)
+}
+CalculateResponse::CalculateResponse(const CalculateResponse& from)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL),
+ _cached_size_(0) {
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ sum_ = from.sum_;
+ // @@protoc_insertion_point(copy_constructor:Tango.PMR.Stubs.CalculateResponse)
+}
+
+void CalculateResponse::SharedCtor() {
+ sum_ = 0;
+ _cached_size_ = 0;
+}
+
+CalculateResponse::~CalculateResponse() {
+ // @@protoc_insertion_point(destructor:Tango.PMR.Stubs.CalculateResponse)
+ SharedDtor();
+}
+
+void CalculateResponse::SharedDtor() {
+}
+
+void CalculateResponse::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* CalculateResponse::descriptor() {
+ protobuf_CalculateResponse_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_CalculateResponse_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
+}
+
+const CalculateResponse& CalculateResponse::default_instance() {
+ protobuf_CalculateResponse_2eproto::InitDefaults();
+ return *internal_default_instance();
+}
+
+CalculateResponse* CalculateResponse::New(::google::protobuf::Arena* arena) const {
+ CalculateResponse* n = new CalculateResponse;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
+}
+
+void CalculateResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:Tango.PMR.Stubs.CalculateResponse)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ sum_ = 0;
+ _internal_metadata_.Clear();
+}
+
+bool CalculateResponse::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:Tango.PMR.Stubs.CalculateResponse)
+ for (;;) {
+ ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+ tag = p.first;
+ if (!p.second) goto handle_unusual;
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // double Sum = 1;
+ case 1: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(9u /* 9 & 0xFF */)) {
+
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
+ input, &sum_)));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ default: {
+ handle_unusual:
+ if (tag == 0) {
+ goto success;
+ }
+ DO_(::google::protobuf::internal::WireFormat::SkipField(
+ input, tag, _internal_metadata_.mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+success:
+ // @@protoc_insertion_point(parse_success:Tango.PMR.Stubs.CalculateResponse)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:Tango.PMR.Stubs.CalculateResponse)
+ return false;
+#undef DO_
+}
+
+void CalculateResponse::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:Tango.PMR.Stubs.CalculateResponse)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // double Sum = 1;
+ if (this->sum() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->sum(), output);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output);
+ }
+ // @@protoc_insertion_point(serialize_end:Tango.PMR.Stubs.CalculateResponse)
+}
+
+::google::protobuf::uint8* CalculateResponse::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
+ (void)deterministic; // Unused
+ // @@protoc_insertion_point(serialize_to_array_start:Tango.PMR.Stubs.CalculateResponse)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // double Sum = 1;
+ if (this->sum() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->sum(), target);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:Tango.PMR.Stubs.CalculateResponse)
+ return target;
+}
+
+size_t CalculateResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:Tango.PMR.Stubs.CalculateResponse)
+ size_t total_size = 0;
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ total_size +=
+ ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()));
+ }
+ // double Sum = 1;
+ if (this->sum() != 0) {
+ total_size += 1 + 8;
+ }
+
+ int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = cached_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void CalculateResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:Tango.PMR.Stubs.CalculateResponse)
+ GOOGLE_DCHECK_NE(&from, this);
+ const CalculateResponse* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const CalculateResponse>(
+ &from);
+ if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Tango.PMR.Stubs.CalculateResponse)
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Tango.PMR.Stubs.CalculateResponse)
+ MergeFrom(*source);
+ }
+}
+
+void CalculateResponse::MergeFrom(const CalculateResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:Tango.PMR.Stubs.CalculateResponse)
+ GOOGLE_DCHECK_NE(&from, this);
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from.sum() != 0) {
+ set_sum(from.sum());
+ }
+}
+
+void CalculateResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Tango.PMR.Stubs.CalculateResponse)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void CalculateResponse::CopyFrom(const CalculateResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Tango.PMR.Stubs.CalculateResponse)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool CalculateResponse::IsInitialized() const {
+ return true;
+}
+
+void CalculateResponse::Swap(CalculateResponse* other) {
+ if (other == this) return;
+ InternalSwap(other);
+}
+void CalculateResponse::InternalSwap(CalculateResponse* other) {
+ using std::swap;
+ swap(sum_, other->sum_);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata CalculateResponse::GetMetadata() const {
+ protobuf_CalculateResponse_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_CalculateResponse_2eproto::file_level_metadata[kIndexInFileMessages];
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// CalculateResponse
+
+// double Sum = 1;
+void CalculateResponse::clear_sum() {
+ sum_ = 0;
+}
+double CalculateResponse::sum() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Stubs.CalculateResponse.Sum)
+ return sum_;
+}
+void CalculateResponse::set_sum(double value) {
+
+ sum_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Stubs.CalculateResponse.Sum)
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace Stubs
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateResponse.pb.h b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateResponse.pb.h
new file mode 100644
index 000000000..1bcf86e80
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/CalculateResponse.pb.h
@@ -0,0 +1,199 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: CalculateResponse.proto
+
+#ifndef PROTOBUF_CalculateResponse_2eproto__INCLUDED
+#define PROTOBUF_CalculateResponse_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 3004000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3004000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h> // IWYU pragma: export
+#include <google/protobuf/extension_set.h> // IWYU pragma: export
+#include <google/protobuf/unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+namespace Tango {
+namespace PMR {
+namespace Stubs {
+class CalculateResponse;
+class CalculateResponseDefaultTypeInternal;
+extern CalculateResponseDefaultTypeInternal _CalculateResponse_default_instance_;
+} // namespace Stubs
+} // namespace PMR
+} // namespace Tango
+
+namespace Tango {
+namespace PMR {
+namespace Stubs {
+
+namespace protobuf_CalculateResponse_2eproto {
+// Internal implementation detail -- do not call these.
+struct TableStruct {
+ static const ::google::protobuf::internal::ParseTableField entries[];
+ static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+ static const ::google::protobuf::internal::ParseTable schema[];
+ static const ::google::protobuf::uint32 offsets[];
+ static const ::google::protobuf::internal::FieldMetadata field_metadata[];
+ static const ::google::protobuf::internal::SerializationTable serialization_table[];
+ static void InitDefaultsImpl();
+};
+void AddDescriptors();
+void InitDefaults();
+} // namespace protobuf_CalculateResponse_2eproto
+
+// ===================================================================
+
+class CalculateResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Tango.PMR.Stubs.CalculateResponse) */ {
+ public:
+ CalculateResponse();
+ virtual ~CalculateResponse();
+
+ CalculateResponse(const CalculateResponse& from);
+
+ inline CalculateResponse& operator=(const CalculateResponse& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ #if LANG_CXX11
+ CalculateResponse(CalculateResponse&& from) noexcept
+ : CalculateResponse() {
+ *this = ::std::move(from);
+ }
+
+ inline CalculateResponse& operator=(CalculateResponse&& from) noexcept {
+ if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+ if (this != &from) InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+ #endif
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const CalculateResponse& default_instance();
+
+ static inline const CalculateResponse* internal_default_instance() {
+ return reinterpret_cast<const CalculateResponse*>(
+ &_CalculateResponse_default_instance_);
+ }
+ static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+ 0;
+
+ void Swap(CalculateResponse* other);
+ friend void swap(CalculateResponse& a, CalculateResponse& b) {
+ a.Swap(&b);
+ }
+
+ // implements Message ----------------------------------------------
+
+ inline CalculateResponse* New() const PROTOBUF_FINAL { return New(NULL); }
+
+ CalculateResponse* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+ void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void CopyFrom(const CalculateResponse& from);
+ void MergeFrom(const CalculateResponse& from);
+ void Clear() PROTOBUF_FINAL;
+ bool IsInitialized() const PROTOBUF_FINAL;
+
+ size_t ByteSizeLong() const PROTOBUF_FINAL;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
+ int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const PROTOBUF_FINAL;
+ void InternalSwap(CalculateResponse* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return NULL;
+ }
+ inline void* MaybeArenaPtr() const {
+ return NULL;
+ }
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // double Sum = 1;
+ void clear_sum();
+ static const int kSumFieldNumber = 1;
+ double sum() const;
+ void set_sum(double value);
+
+ // @@protoc_insertion_point(class_scope:Tango.PMR.Stubs.CalculateResponse)
+ private:
+
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ double sum_;
+ mutable int _cached_size_;
+ friend struct protobuf_CalculateResponse_2eproto::TableStruct;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// CalculateResponse
+
+// double Sum = 1;
+inline void CalculateResponse::clear_sum() {
+ sum_ = 0;
+}
+inline double CalculateResponse::sum() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Stubs.CalculateResponse.Sum)
+ return sum_;
+}
+inline void CalculateResponse::set_sum(double value) {
+
+ sum_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Stubs.CalculateResponse.Sum)
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+
+} // namespace Stubs
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_CalculateResponse_2eproto__INCLUDED
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Job.pb.cc b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Job.pb.cc
new file mode 100644
index 000000000..78a895b4b
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Job.pb.cc
@@ -0,0 +1,525 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: Job.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "Job.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace Tango {
+namespace PMR {
+namespace Jobs {
+class JobDefaultTypeInternal {
+public:
+ ::google::protobuf::internal::ExplicitlyConstructed<Job>
+ _instance;
+} _Job_default_instance_;
+
+namespace protobuf_Job_2eproto {
+
+
+namespace {
+
+::google::protobuf::Metadata file_level_metadata[1];
+
+} // namespace
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+ const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+ const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+ TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { NULL, NULL, 0, -1, -1, -1, -1, NULL, false },
+};
+
+const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ~0u, // no _has_bits_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Job, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Job, name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Job, segments_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, sizeof(Job)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::google::protobuf::Message*>(&_Job_default_instance_),
+};
+
+namespace {
+
+void protobuf_AssignDescriptors() {
+ AddDescriptors();
+ ::google::protobuf::MessageFactory* factory = NULL;
+ AssignDescriptors(
+ "Job.proto", schemas, file_default_instances, TableStruct::offsets, factory,
+ file_level_metadata, NULL, NULL);
+}
+
+void protobuf_AssignDescriptorsOnce() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
+void protobuf_RegisterTypes(const ::std::string&) {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
+}
+
+} // namespace
+void TableStruct::InitDefaultsImpl() {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ ::google::protobuf::internal::InitProtobufDefaults();
+ ::Tango::PMR::Jobs::protobuf_Segment_2eproto::InitDefaults();
+ _Job_default_instance_._instance.DefaultConstruct();
+ ::google::protobuf::internal::OnShutdownDestroyMessage(
+ &_Job_default_instance_);}
+
+void InitDefaults() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl);
+}
+namespace {
+void AddDescriptorsImpl() {
+ InitDefaults();
+ static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ "\n\tJob.proto\022\016Tango.PMR.Jobs\032\rSegment.pro"
+ "to\">\n\003Job\022\014\n\004Name\030\001 \001(\t\022)\n\010Segments\030\002 \003("
+ "\0132\027.Tango.PMR.Jobs.SegmentB\032\n\030com.twine."
+ "tango.pmr.jobsb\006proto3"
+ };
+ ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+ descriptor, 142);
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+ "Job.proto", &protobuf_RegisterTypes);
+ ::Tango::PMR::Jobs::protobuf_Segment_2eproto::AddDescriptors();
+}
+} // anonymous namespace
+
+void AddDescriptors() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
+}
+// Force AddDescriptors() to be called at dynamic initialization time.
+struct StaticDescriptorInitializer {
+ StaticDescriptorInitializer() {
+ AddDescriptors();
+ }
+} static_descriptor_initializer;
+
+} // namespace protobuf_Job_2eproto
+
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Job::kNameFieldNumber;
+const int Job::kSegmentsFieldNumber;
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Job::Job()
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+ if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
+ protobuf_Job_2eproto::InitDefaults();
+ }
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:Tango.PMR.Jobs.Job)
+}
+Job::Job(const Job& from)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL),
+ segments_(from.segments_),
+ _cached_size_(0) {
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ if (from.name().size() > 0) {
+ name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+ }
+ // @@protoc_insertion_point(copy_constructor:Tango.PMR.Jobs.Job)
+}
+
+void Job::SharedCtor() {
+ name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ _cached_size_ = 0;
+}
+
+Job::~Job() {
+ // @@protoc_insertion_point(destructor:Tango.PMR.Jobs.Job)
+ SharedDtor();
+}
+
+void Job::SharedDtor() {
+ name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void Job::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* Job::descriptor() {
+ protobuf_Job_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_Job_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
+}
+
+const Job& Job::default_instance() {
+ protobuf_Job_2eproto::InitDefaults();
+ return *internal_default_instance();
+}
+
+Job* Job::New(::google::protobuf::Arena* arena) const {
+ Job* n = new Job;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
+}
+
+void Job::Clear() {
+// @@protoc_insertion_point(message_clear_start:Tango.PMR.Jobs.Job)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ segments_.Clear();
+ name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ _internal_metadata_.Clear();
+}
+
+bool Job::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:Tango.PMR.Jobs.Job)
+ for (;;) {
+ ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+ tag = p.first;
+ if (!p.second) goto handle_unusual;
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // string Name = 1;
+ case 1: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_name()));
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->name().data(), static_cast<int>(this->name().length()),
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "Tango.PMR.Jobs.Job.Name"));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ // repeated .Tango.PMR.Jobs.Segment Segments = 2;
+ case 2: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_segments()));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ default: {
+ handle_unusual:
+ if (tag == 0) {
+ goto success;
+ }
+ DO_(::google::protobuf::internal::WireFormat::SkipField(
+ input, tag, _internal_metadata_.mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+success:
+ // @@protoc_insertion_point(parse_success:Tango.PMR.Jobs.Job)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:Tango.PMR.Jobs.Job)
+ return false;
+#undef DO_
+}
+
+void Job::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:Tango.PMR.Jobs.Job)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // string Name = 1;
+ if (this->name().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->name().data(), static_cast<int>(this->name().length()),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "Tango.PMR.Jobs.Job.Name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+ 1, this->name(), output);
+ }
+
+ // repeated .Tango.PMR.Jobs.Segment Segments = 2;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->segments_size()); i < n; i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 2, this->segments(static_cast<int>(i)), output);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output);
+ }
+ // @@protoc_insertion_point(serialize_end:Tango.PMR.Jobs.Job)
+}
+
+::google::protobuf::uint8* Job::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
+ (void)deterministic; // Unused
+ // @@protoc_insertion_point(serialize_to_array_start:Tango.PMR.Jobs.Job)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // string Name = 1;
+ if (this->name().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->name().data(), static_cast<int>(this->name().length()),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "Tango.PMR.Jobs.Job.Name");
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->name(), target);
+ }
+
+ // repeated .Tango.PMR.Jobs.Segment Segments = 2;
+ for (unsigned int i = 0,
+ n = static_cast<unsigned int>(this->segments_size()); i < n; i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ InternalWriteMessageNoVirtualToArray(
+ 2, this->segments(static_cast<int>(i)), deterministic, target);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:Tango.PMR.Jobs.Job)
+ return target;
+}
+
+size_t Job::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:Tango.PMR.Jobs.Job)
+ size_t total_size = 0;
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ total_size +=
+ ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()));
+ }
+ // repeated .Tango.PMR.Jobs.Segment Segments = 2;
+ {
+ unsigned int count = static_cast<unsigned int>(this->segments_size());
+ total_size += 1UL * count;
+ for (unsigned int i = 0; i < count; i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->segments(static_cast<int>(i)));
+ }
+ }
+
+ // string Name = 1;
+ if (this->name().size() > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name());
+ }
+
+ int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = cached_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void Job::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:Tango.PMR.Jobs.Job)
+ GOOGLE_DCHECK_NE(&from, this);
+ const Job* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const Job>(
+ &from);
+ if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Tango.PMR.Jobs.Job)
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Tango.PMR.Jobs.Job)
+ MergeFrom(*source);
+ }
+}
+
+void Job::MergeFrom(const Job& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:Tango.PMR.Jobs.Job)
+ GOOGLE_DCHECK_NE(&from, this);
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ segments_.MergeFrom(from.segments_);
+ if (from.name().size() > 0) {
+
+ name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+ }
+}
+
+void Job::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Tango.PMR.Jobs.Job)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void Job::CopyFrom(const Job& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Tango.PMR.Jobs.Job)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Job::IsInitialized() const {
+ return true;
+}
+
+void Job::Swap(Job* other) {
+ if (other == this) return;
+ InternalSwap(other);
+}
+void Job::InternalSwap(Job* other) {
+ using std::swap;
+ segments_.InternalSwap(&other->segments_);
+ name_.Swap(&other->name_);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata Job::GetMetadata() const {
+ protobuf_Job_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_Job_2eproto::file_level_metadata[kIndexInFileMessages];
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// Job
+
+// string Name = 1;
+void Job::clear_name() {
+ name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+const ::std::string& Job::name() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Jobs.Job.Name)
+ return name_.GetNoArena();
+}
+void Job::set_name(const ::std::string& value) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:Tango.PMR.Jobs.Job.Name)
+}
+#if LANG_CXX11
+void Job::set_name(::std::string&& value) {
+
+ name_.SetNoArena(
+ &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+ // @@protoc_insertion_point(field_set_rvalue:Tango.PMR.Jobs.Job.Name)
+}
+#endif
+void Job::set_name(const char* value) {
+ GOOGLE_DCHECK(value != NULL);
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:Tango.PMR.Jobs.Job.Name)
+}
+void Job::set_name(const char* value, size_t size) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:Tango.PMR.Jobs.Job.Name)
+}
+::std::string* Job::mutable_name() {
+
+ // @@protoc_insertion_point(field_mutable:Tango.PMR.Jobs.Job.Name)
+ return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+::std::string* Job::release_name() {
+ // @@protoc_insertion_point(field_release:Tango.PMR.Jobs.Job.Name)
+
+ return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void Job::set_allocated_name(::std::string* name) {
+ if (name != NULL) {
+
+ } else {
+
+ }
+ name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+ // @@protoc_insertion_point(field_set_allocated:Tango.PMR.Jobs.Job.Name)
+}
+
+// repeated .Tango.PMR.Jobs.Segment Segments = 2;
+int Job::segments_size() const {
+ return segments_.size();
+}
+void Job::clear_segments() {
+ segments_.Clear();
+}
+const ::Tango::PMR::Jobs::Segment& Job::segments(int index) const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Jobs.Job.Segments)
+ return segments_.Get(index);
+}
+::Tango::PMR::Jobs::Segment* Job::mutable_segments(int index) {
+ // @@protoc_insertion_point(field_mutable:Tango.PMR.Jobs.Job.Segments)
+ return segments_.Mutable(index);
+}
+::Tango::PMR::Jobs::Segment* Job::add_segments() {
+ // @@protoc_insertion_point(field_add:Tango.PMR.Jobs.Job.Segments)
+ return segments_.Add();
+}
+::google::protobuf::RepeatedPtrField< ::Tango::PMR::Jobs::Segment >*
+Job::mutable_segments() {
+ // @@protoc_insertion_point(field_mutable_list:Tango.PMR.Jobs.Job.Segments)
+ return &segments_;
+}
+const ::google::protobuf::RepeatedPtrField< ::Tango::PMR::Jobs::Segment >&
+Job::segments() const {
+ // @@protoc_insertion_point(field_list:Tango.PMR.Jobs.Job.Segments)
+ return segments_;
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace Jobs
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Job.pb.h b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Job.pb.h
new file mode 100644
index 000000000..6cd09051c
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Job.pb.h
@@ -0,0 +1,290 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: Job.proto
+
+#ifndef PROTOBUF_Job_2eproto__INCLUDED
+#define PROTOBUF_Job_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 3004000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3004000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h> // IWYU pragma: export
+#include <google/protobuf/extension_set.h> // IWYU pragma: export
+#include <google/protobuf/unknown_field_set.h>
+#include "Segment.pb.h"
+// @@protoc_insertion_point(includes)
+namespace Tango {
+namespace PMR {
+namespace Jobs {
+class Job;
+class JobDefaultTypeInternal;
+extern JobDefaultTypeInternal _Job_default_instance_;
+} // namespace Jobs
+} // namespace PMR
+} // namespace Tango
+
+namespace Tango {
+namespace PMR {
+namespace Jobs {
+
+namespace protobuf_Job_2eproto {
+// Internal implementation detail -- do not call these.
+struct TableStruct {
+ static const ::google::protobuf::internal::ParseTableField entries[];
+ static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+ static const ::google::protobuf::internal::ParseTable schema[];
+ static const ::google::protobuf::uint32 offsets[];
+ static const ::google::protobuf::internal::FieldMetadata field_metadata[];
+ static const ::google::protobuf::internal::SerializationTable serialization_table[];
+ static void InitDefaultsImpl();
+};
+void AddDescriptors();
+void InitDefaults();
+} // namespace protobuf_Job_2eproto
+
+// ===================================================================
+
+class Job : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Tango.PMR.Jobs.Job) */ {
+ public:
+ Job();
+ virtual ~Job();
+
+ Job(const Job& from);
+
+ inline Job& operator=(const Job& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ #if LANG_CXX11
+ Job(Job&& from) noexcept
+ : Job() {
+ *this = ::std::move(from);
+ }
+
+ inline Job& operator=(Job&& from) noexcept {
+ if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+ if (this != &from) InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+ #endif
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const Job& default_instance();
+
+ static inline const Job* internal_default_instance() {
+ return reinterpret_cast<const Job*>(
+ &_Job_default_instance_);
+ }
+ static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+ 0;
+
+ void Swap(Job* other);
+ friend void swap(Job& a, Job& b) {
+ a.Swap(&b);
+ }
+
+ // implements Message ----------------------------------------------
+
+ inline Job* New() const PROTOBUF_FINAL { return New(NULL); }
+
+ Job* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+ void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void CopyFrom(const Job& from);
+ void MergeFrom(const Job& from);
+ void Clear() PROTOBUF_FINAL;
+ bool IsInitialized() const PROTOBUF_FINAL;
+
+ size_t ByteSizeLong() const PROTOBUF_FINAL;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
+ int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const PROTOBUF_FINAL;
+ void InternalSwap(Job* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return NULL;
+ }
+ inline void* MaybeArenaPtr() const {
+ return NULL;
+ }
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // repeated .Tango.PMR.Jobs.Segment Segments = 2;
+ int segments_size() const;
+ void clear_segments();
+ static const int kSegmentsFieldNumber = 2;
+ const ::Tango::PMR::Jobs::Segment& segments(int index) const;
+ ::Tango::PMR::Jobs::Segment* mutable_segments(int index);
+ ::Tango::PMR::Jobs::Segment* add_segments();
+ ::google::protobuf::RepeatedPtrField< ::Tango::PMR::Jobs::Segment >*
+ mutable_segments();
+ const ::google::protobuf::RepeatedPtrField< ::Tango::PMR::Jobs::Segment >&
+ segments() const;
+
+ // string Name = 1;
+ void clear_name();
+ static const int kNameFieldNumber = 1;
+ const ::std::string& name() const;
+ void set_name(const ::std::string& value);
+ #if LANG_CXX11
+ void set_name(::std::string&& value);
+ #endif
+ void set_name(const char* value);
+ void set_name(const char* value, size_t size);
+ ::std::string* mutable_name();
+ ::std::string* release_name();
+ void set_allocated_name(::std::string* name);
+
+ // @@protoc_insertion_point(class_scope:Tango.PMR.Jobs.Job)
+ private:
+
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ ::google::protobuf::RepeatedPtrField< ::Tango::PMR::Jobs::Segment > segments_;
+ ::google::protobuf::internal::ArenaStringPtr name_;
+ mutable int _cached_size_;
+ friend struct protobuf_Job_2eproto::TableStruct;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// Job
+
+// string Name = 1;
+inline void Job::clear_name() {
+ name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Job::name() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Jobs.Job.Name)
+ return name_.GetNoArena();
+}
+inline void Job::set_name(const ::std::string& value) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:Tango.PMR.Jobs.Job.Name)
+}
+#if LANG_CXX11
+inline void Job::set_name(::std::string&& value) {
+
+ name_.SetNoArena(
+ &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+ // @@protoc_insertion_point(field_set_rvalue:Tango.PMR.Jobs.Job.Name)
+}
+#endif
+inline void Job::set_name(const char* value) {
+ GOOGLE_DCHECK(value != NULL);
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:Tango.PMR.Jobs.Job.Name)
+}
+inline void Job::set_name(const char* value, size_t size) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:Tango.PMR.Jobs.Job.Name)
+}
+inline ::std::string* Job::mutable_name() {
+
+ // @@protoc_insertion_point(field_mutable:Tango.PMR.Jobs.Job.Name)
+ return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Job::release_name() {
+ // @@protoc_insertion_point(field_release:Tango.PMR.Jobs.Job.Name)
+
+ return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Job::set_allocated_name(::std::string* name) {
+ if (name != NULL) {
+
+ } else {
+
+ }
+ name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+ // @@protoc_insertion_point(field_set_allocated:Tango.PMR.Jobs.Job.Name)
+}
+
+// repeated .Tango.PMR.Jobs.Segment Segments = 2;
+inline int Job::segments_size() const {
+ return segments_.size();
+}
+inline void Job::clear_segments() {
+ segments_.Clear();
+}
+inline const ::Tango::PMR::Jobs::Segment& Job::segments(int index) const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Jobs.Job.Segments)
+ return segments_.Get(index);
+}
+inline ::Tango::PMR::Jobs::Segment* Job::mutable_segments(int index) {
+ // @@protoc_insertion_point(field_mutable:Tango.PMR.Jobs.Job.Segments)
+ return segments_.Mutable(index);
+}
+inline ::Tango::PMR::Jobs::Segment* Job::add_segments() {
+ // @@protoc_insertion_point(field_add:Tango.PMR.Jobs.Job.Segments)
+ return segments_.Add();
+}
+inline ::google::protobuf::RepeatedPtrField< ::Tango::PMR::Jobs::Segment >*
+Job::mutable_segments() {
+ // @@protoc_insertion_point(field_mutable_list:Tango.PMR.Jobs.Job.Segments)
+ return &segments_;
+}
+inline const ::google::protobuf::RepeatedPtrField< ::Tango::PMR::Jobs::Segment >&
+Job::segments() const {
+ // @@protoc_insertion_point(field_list:Tango.PMR.Jobs.Job.Segments)
+ return segments_;
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+
+} // namespace Jobs
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_Job_2eproto__INCLUDED
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageContainer.pb.cc b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageContainer.pb.cc
new file mode 100644
index 000000000..e06fad270
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageContainer.pb.cc
@@ -0,0 +1,712 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: MessageContainer.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "MessageContainer.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace Tango {
+namespace PMR {
+namespace Common {
+class MessageContainerDefaultTypeInternal {
+public:
+ ::google::protobuf::internal::ExplicitlyConstructed<MessageContainer>
+ _instance;
+} _MessageContainer_default_instance_;
+
+namespace protobuf_MessageContainer_2eproto {
+
+
+namespace {
+
+::google::protobuf::Metadata file_level_metadata[1];
+
+} // namespace
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+ const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+ const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+ TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { NULL, NULL, 0, -1, -1, -1, -1, NULL, false },
+};
+
+const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ~0u, // no _has_bits_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageContainer, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageContainer, type_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageContainer, token_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageContainer, continuous_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageContainer, completed_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageContainer, data_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, sizeof(MessageContainer)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::google::protobuf::Message*>(&_MessageContainer_default_instance_),
+};
+
+namespace {
+
+void protobuf_AssignDescriptors() {
+ AddDescriptors();
+ ::google::protobuf::MessageFactory* factory = NULL;
+ AssignDescriptors(
+ "MessageContainer.proto", schemas, file_default_instances, TableStruct::offsets, factory,
+ file_level_metadata, NULL, NULL);
+}
+
+void protobuf_AssignDescriptorsOnce() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
+void protobuf_RegisterTypes(const ::std::string&) {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
+}
+
+} // namespace
+void TableStruct::InitDefaultsImpl() {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ ::google::protobuf::internal::InitProtobufDefaults();
+ ::Tango::PMR::Common::protobuf_MessageType_2eproto::InitDefaults();
+ _MessageContainer_default_instance_._instance.DefaultConstruct();
+ ::google::protobuf::internal::OnShutdownDestroyMessage(
+ &_MessageContainer_default_instance_);}
+
+void InitDefaults() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl);
+}
+namespace {
+void AddDescriptorsImpl() {
+ InitDefaults();
+ static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ "\n\026MessageContainer.proto\022\020Tango.PMR.Comm"
+ "on\032\021MessageType.proto\"\203\001\n\020MessageContain"
+ "er\022+\n\004Type\030\001 \001(\0162\035.Tango.PMR.Common.Mess"
+ "ageType\022\r\n\005Token\030\002 \001(\t\022\022\n\nContinuous\030\003 \001"
+ "(\010\022\021\n\tCompleted\030\004 \001(\010\022\014\n\004Data\030\005 \001(\014B\034\n\032c"
+ "om.twine.tango.pmr.commonb\006proto3"
+ };
+ ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+ descriptor, 233);
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+ "MessageContainer.proto", &protobuf_RegisterTypes);
+ ::Tango::PMR::Common::protobuf_MessageType_2eproto::AddDescriptors();
+}
+} // anonymous namespace
+
+void AddDescriptors() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
+}
+// Force AddDescriptors() to be called at dynamic initialization time.
+struct StaticDescriptorInitializer {
+ StaticDescriptorInitializer() {
+ AddDescriptors();
+ }
+} static_descriptor_initializer;
+
+} // namespace protobuf_MessageContainer_2eproto
+
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int MessageContainer::kTypeFieldNumber;
+const int MessageContainer::kTokenFieldNumber;
+const int MessageContainer::kContinuousFieldNumber;
+const int MessageContainer::kCompletedFieldNumber;
+const int MessageContainer::kDataFieldNumber;
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+MessageContainer::MessageContainer()
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+ if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
+ protobuf_MessageContainer_2eproto::InitDefaults();
+ }
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:Tango.PMR.Common.MessageContainer)
+}
+MessageContainer::MessageContainer(const MessageContainer& from)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL),
+ _cached_size_(0) {
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ token_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ if (from.token().size() > 0) {
+ token_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.token_);
+ }
+ data_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ if (from.data().size() > 0) {
+ data_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.data_);
+ }
+ ::memcpy(&type_, &from.type_,
+ static_cast<size_t>(reinterpret_cast<char*>(&completed_) -
+ reinterpret_cast<char*>(&type_)) + sizeof(completed_));
+ // @@protoc_insertion_point(copy_constructor:Tango.PMR.Common.MessageContainer)
+}
+
+void MessageContainer::SharedCtor() {
+ token_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ data_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ ::memset(&type_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&completed_) -
+ reinterpret_cast<char*>(&type_)) + sizeof(completed_));
+ _cached_size_ = 0;
+}
+
+MessageContainer::~MessageContainer() {
+ // @@protoc_insertion_point(destructor:Tango.PMR.Common.MessageContainer)
+ SharedDtor();
+}
+
+void MessageContainer::SharedDtor() {
+ token_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ data_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void MessageContainer::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* MessageContainer::descriptor() {
+ protobuf_MessageContainer_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_MessageContainer_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
+}
+
+const MessageContainer& MessageContainer::default_instance() {
+ protobuf_MessageContainer_2eproto::InitDefaults();
+ return *internal_default_instance();
+}
+
+MessageContainer* MessageContainer::New(::google::protobuf::Arena* arena) const {
+ MessageContainer* n = new MessageContainer;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
+}
+
+void MessageContainer::Clear() {
+// @@protoc_insertion_point(message_clear_start:Tango.PMR.Common.MessageContainer)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ token_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ data_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ ::memset(&type_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&completed_) -
+ reinterpret_cast<char*>(&type_)) + sizeof(completed_));
+ _internal_metadata_.Clear();
+}
+
+bool MessageContainer::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:Tango.PMR.Common.MessageContainer)
+ for (;;) {
+ ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+ tag = p.first;
+ if (!p.second) goto handle_unusual;
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // .Tango.PMR.Common.MessageType Type = 1;
+ case 1: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ set_type(static_cast< ::Tango::PMR::Common::MessageType >(value));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ // string Token = 2;
+ case 2: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_token()));
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->token().data(), static_cast<int>(this->token().length()),
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "Tango.PMR.Common.MessageContainer.Token"));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ // bool Continuous = 3;
+ case 3: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
+
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &continuous_)));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ // bool Completed = 4;
+ case 4: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
+
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &completed_)));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ // bytes Data = 5;
+ case 5: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
+ input, this->mutable_data()));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ default: {
+ handle_unusual:
+ if (tag == 0) {
+ goto success;
+ }
+ DO_(::google::protobuf::internal::WireFormat::SkipField(
+ input, tag, _internal_metadata_.mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+success:
+ // @@protoc_insertion_point(parse_success:Tango.PMR.Common.MessageContainer)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:Tango.PMR.Common.MessageContainer)
+ return false;
+#undef DO_
+}
+
+void MessageContainer::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:Tango.PMR.Common.MessageContainer)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // .Tango.PMR.Common.MessageType Type = 1;
+ if (this->type() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 1, this->type(), output);
+ }
+
+ // string Token = 2;
+ if (this->token().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->token().data(), static_cast<int>(this->token().length()),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "Tango.PMR.Common.MessageContainer.Token");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+ 2, this->token(), output);
+ }
+
+ // bool Continuous = 3;
+ if (this->continuous() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->continuous(), output);
+ }
+
+ // bool Completed = 4;
+ if (this->completed() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(4, this->completed(), output);
+ }
+
+ // bytes Data = 5;
+ if (this->data().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
+ 5, this->data(), output);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output);
+ }
+ // @@protoc_insertion_point(serialize_end:Tango.PMR.Common.MessageContainer)
+}
+
+::google::protobuf::uint8* MessageContainer::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
+ (void)deterministic; // Unused
+ // @@protoc_insertion_point(serialize_to_array_start:Tango.PMR.Common.MessageContainer)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // .Tango.PMR.Common.MessageType Type = 1;
+ if (this->type() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+ 1, this->type(), target);
+ }
+
+ // string Token = 2;
+ if (this->token().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->token().data(), static_cast<int>(this->token().length()),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "Tango.PMR.Common.MessageContainer.Token");
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 2, this->token(), target);
+ }
+
+ // bool Continuous = 3;
+ if (this->continuous() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->continuous(), target);
+ }
+
+ // bool Completed = 4;
+ if (this->completed() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(4, this->completed(), target);
+ }
+
+ // bytes Data = 5;
+ if (this->data().size() > 0) {
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
+ 5, this->data(), target);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:Tango.PMR.Common.MessageContainer)
+ return target;
+}
+
+size_t MessageContainer::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:Tango.PMR.Common.MessageContainer)
+ size_t total_size = 0;
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ total_size +=
+ ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()));
+ }
+ // string Token = 2;
+ if (this->token().size() > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->token());
+ }
+
+ // bytes Data = 5;
+ if (this->data().size() > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::BytesSize(
+ this->data());
+ }
+
+ // .Tango.PMR.Common.MessageType Type = 1;
+ if (this->type() != 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
+ }
+
+ // bool Continuous = 3;
+ if (this->continuous() != 0) {
+ total_size += 1 + 1;
+ }
+
+ // bool Completed = 4;
+ if (this->completed() != 0) {
+ total_size += 1 + 1;
+ }
+
+ int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = cached_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void MessageContainer::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:Tango.PMR.Common.MessageContainer)
+ GOOGLE_DCHECK_NE(&from, this);
+ const MessageContainer* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const MessageContainer>(
+ &from);
+ if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Tango.PMR.Common.MessageContainer)
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Tango.PMR.Common.MessageContainer)
+ MergeFrom(*source);
+ }
+}
+
+void MessageContainer::MergeFrom(const MessageContainer& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:Tango.PMR.Common.MessageContainer)
+ GOOGLE_DCHECK_NE(&from, this);
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from.token().size() > 0) {
+
+ token_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.token_);
+ }
+ if (from.data().size() > 0) {
+
+ data_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.data_);
+ }
+ if (from.type() != 0) {
+ set_type(from.type());
+ }
+ if (from.continuous() != 0) {
+ set_continuous(from.continuous());
+ }
+ if (from.completed() != 0) {
+ set_completed(from.completed());
+ }
+}
+
+void MessageContainer::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Tango.PMR.Common.MessageContainer)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void MessageContainer::CopyFrom(const MessageContainer& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Tango.PMR.Common.MessageContainer)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool MessageContainer::IsInitialized() const {
+ return true;
+}
+
+void MessageContainer::Swap(MessageContainer* other) {
+ if (other == this) return;
+ InternalSwap(other);
+}
+void MessageContainer::InternalSwap(MessageContainer* other) {
+ using std::swap;
+ token_.Swap(&other->token_);
+ data_.Swap(&other->data_);
+ swap(type_, other->type_);
+ swap(continuous_, other->continuous_);
+ swap(completed_, other->completed_);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata MessageContainer::GetMetadata() const {
+ protobuf_MessageContainer_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_MessageContainer_2eproto::file_level_metadata[kIndexInFileMessages];
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// MessageContainer
+
+// .Tango.PMR.Common.MessageType Type = 1;
+void MessageContainer::clear_type() {
+ type_ = 0;
+}
+::Tango::PMR::Common::MessageType MessageContainer::type() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.MessageContainer.Type)
+ return static_cast< ::Tango::PMR::Common::MessageType >(type_);
+}
+void MessageContainer::set_type(::Tango::PMR::Common::MessageType value) {
+
+ type_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.MessageContainer.Type)
+}
+
+// string Token = 2;
+void MessageContainer::clear_token() {
+ token_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+const ::std::string& MessageContainer::token() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.MessageContainer.Token)
+ return token_.GetNoArena();
+}
+void MessageContainer::set_token(const ::std::string& value) {
+
+ token_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.MessageContainer.Token)
+}
+#if LANG_CXX11
+void MessageContainer::set_token(::std::string&& value) {
+
+ token_.SetNoArena(
+ &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+ // @@protoc_insertion_point(field_set_rvalue:Tango.PMR.Common.MessageContainer.Token)
+}
+#endif
+void MessageContainer::set_token(const char* value) {
+ GOOGLE_DCHECK(value != NULL);
+
+ token_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:Tango.PMR.Common.MessageContainer.Token)
+}
+void MessageContainer::set_token(const char* value, size_t size) {
+
+ token_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:Tango.PMR.Common.MessageContainer.Token)
+}
+::std::string* MessageContainer::mutable_token() {
+
+ // @@protoc_insertion_point(field_mutable:Tango.PMR.Common.MessageContainer.Token)
+ return token_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+::std::string* MessageContainer::release_token() {
+ // @@protoc_insertion_point(field_release:Tango.PMR.Common.MessageContainer.Token)
+
+ return token_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void MessageContainer::set_allocated_token(::std::string* token) {
+ if (token != NULL) {
+
+ } else {
+
+ }
+ token_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), token);
+ // @@protoc_insertion_point(field_set_allocated:Tango.PMR.Common.MessageContainer.Token)
+}
+
+// bool Continuous = 3;
+void MessageContainer::clear_continuous() {
+ continuous_ = false;
+}
+bool MessageContainer::continuous() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.MessageContainer.Continuous)
+ return continuous_;
+}
+void MessageContainer::set_continuous(bool value) {
+
+ continuous_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.MessageContainer.Continuous)
+}
+
+// bool Completed = 4;
+void MessageContainer::clear_completed() {
+ completed_ = false;
+}
+bool MessageContainer::completed() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.MessageContainer.Completed)
+ return completed_;
+}
+void MessageContainer::set_completed(bool value) {
+
+ completed_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.MessageContainer.Completed)
+}
+
+// bytes Data = 5;
+void MessageContainer::clear_data() {
+ data_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+const ::std::string& MessageContainer::data() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.MessageContainer.Data)
+ return data_.GetNoArena();
+}
+void MessageContainer::set_data(const ::std::string& value) {
+
+ data_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.MessageContainer.Data)
+}
+#if LANG_CXX11
+void MessageContainer::set_data(::std::string&& value) {
+
+ data_.SetNoArena(
+ &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+ // @@protoc_insertion_point(field_set_rvalue:Tango.PMR.Common.MessageContainer.Data)
+}
+#endif
+void MessageContainer::set_data(const char* value) {
+ GOOGLE_DCHECK(value != NULL);
+
+ data_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:Tango.PMR.Common.MessageContainer.Data)
+}
+void MessageContainer::set_data(const void* value, size_t size) {
+
+ data_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:Tango.PMR.Common.MessageContainer.Data)
+}
+::std::string* MessageContainer::mutable_data() {
+
+ // @@protoc_insertion_point(field_mutable:Tango.PMR.Common.MessageContainer.Data)
+ return data_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+::std::string* MessageContainer::release_data() {
+ // @@protoc_insertion_point(field_release:Tango.PMR.Common.MessageContainer.Data)
+
+ return data_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void MessageContainer::set_allocated_data(::std::string* data) {
+ if (data != NULL) {
+
+ } else {
+
+ }
+ data_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), data);
+ // @@protoc_insertion_point(field_set_allocated:Tango.PMR.Common.MessageContainer.Data)
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace Common
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageContainer.pb.h b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageContainer.pb.h
new file mode 100644
index 000000000..b853ede29
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageContainer.pb.h
@@ -0,0 +1,378 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: MessageContainer.proto
+
+#ifndef PROTOBUF_MessageContainer_2eproto__INCLUDED
+#define PROTOBUF_MessageContainer_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 3004000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3004000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h> // IWYU pragma: export
+#include <google/protobuf/extension_set.h> // IWYU pragma: export
+#include <google/protobuf/unknown_field_set.h>
+#include "MessageType.pb.h"
+// @@protoc_insertion_point(includes)
+namespace Tango {
+namespace PMR {
+namespace Common {
+class MessageContainer;
+class MessageContainerDefaultTypeInternal;
+extern MessageContainerDefaultTypeInternal _MessageContainer_default_instance_;
+} // namespace Common
+} // namespace PMR
+} // namespace Tango
+
+namespace Tango {
+namespace PMR {
+namespace Common {
+
+namespace protobuf_MessageContainer_2eproto {
+// Internal implementation detail -- do not call these.
+struct TableStruct {
+ static const ::google::protobuf::internal::ParseTableField entries[];
+ static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+ static const ::google::protobuf::internal::ParseTable schema[];
+ static const ::google::protobuf::uint32 offsets[];
+ static const ::google::protobuf::internal::FieldMetadata field_metadata[];
+ static const ::google::protobuf::internal::SerializationTable serialization_table[];
+ static void InitDefaultsImpl();
+};
+void AddDescriptors();
+void InitDefaults();
+} // namespace protobuf_MessageContainer_2eproto
+
+// ===================================================================
+
+class MessageContainer : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Tango.PMR.Common.MessageContainer) */ {
+ public:
+ MessageContainer();
+ virtual ~MessageContainer();
+
+ MessageContainer(const MessageContainer& from);
+
+ inline MessageContainer& operator=(const MessageContainer& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ #if LANG_CXX11
+ MessageContainer(MessageContainer&& from) noexcept
+ : MessageContainer() {
+ *this = ::std::move(from);
+ }
+
+ inline MessageContainer& operator=(MessageContainer&& from) noexcept {
+ if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+ if (this != &from) InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+ #endif
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const MessageContainer& default_instance();
+
+ static inline const MessageContainer* internal_default_instance() {
+ return reinterpret_cast<const MessageContainer*>(
+ &_MessageContainer_default_instance_);
+ }
+ static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+ 0;
+
+ void Swap(MessageContainer* other);
+ friend void swap(MessageContainer& a, MessageContainer& b) {
+ a.Swap(&b);
+ }
+
+ // implements Message ----------------------------------------------
+
+ inline MessageContainer* New() const PROTOBUF_FINAL { return New(NULL); }
+
+ MessageContainer* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+ void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void CopyFrom(const MessageContainer& from);
+ void MergeFrom(const MessageContainer& from);
+ void Clear() PROTOBUF_FINAL;
+ bool IsInitialized() const PROTOBUF_FINAL;
+
+ size_t ByteSizeLong() const PROTOBUF_FINAL;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
+ int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const PROTOBUF_FINAL;
+ void InternalSwap(MessageContainer* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return NULL;
+ }
+ inline void* MaybeArenaPtr() const {
+ return NULL;
+ }
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // string Token = 2;
+ void clear_token();
+ static const int kTokenFieldNumber = 2;
+ const ::std::string& token() const;
+ void set_token(const ::std::string& value);
+ #if LANG_CXX11
+ void set_token(::std::string&& value);
+ #endif
+ void set_token(const char* value);
+ void set_token(const char* value, size_t size);
+ ::std::string* mutable_token();
+ ::std::string* release_token();
+ void set_allocated_token(::std::string* token);
+
+ // bytes Data = 5;
+ void clear_data();
+ static const int kDataFieldNumber = 5;
+ const ::std::string& data() const;
+ void set_data(const ::std::string& value);
+ #if LANG_CXX11
+ void set_data(::std::string&& value);
+ #endif
+ void set_data(const char* value);
+ void set_data(const void* value, size_t size);
+ ::std::string* mutable_data();
+ ::std::string* release_data();
+ void set_allocated_data(::std::string* data);
+
+ // .Tango.PMR.Common.MessageType Type = 1;
+ void clear_type();
+ static const int kTypeFieldNumber = 1;
+ ::Tango::PMR::Common::MessageType type() const;
+ void set_type(::Tango::PMR::Common::MessageType value);
+
+ // bool Continuous = 3;
+ void clear_continuous();
+ static const int kContinuousFieldNumber = 3;
+ bool continuous() const;
+ void set_continuous(bool value);
+
+ // bool Completed = 4;
+ void clear_completed();
+ static const int kCompletedFieldNumber = 4;
+ bool completed() const;
+ void set_completed(bool value);
+
+ // @@protoc_insertion_point(class_scope:Tango.PMR.Common.MessageContainer)
+ private:
+
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ ::google::protobuf::internal::ArenaStringPtr token_;
+ ::google::protobuf::internal::ArenaStringPtr data_;
+ int type_;
+ bool continuous_;
+ bool completed_;
+ mutable int _cached_size_;
+ friend struct protobuf_MessageContainer_2eproto::TableStruct;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// MessageContainer
+
+// .Tango.PMR.Common.MessageType Type = 1;
+inline void MessageContainer::clear_type() {
+ type_ = 0;
+}
+inline ::Tango::PMR::Common::MessageType MessageContainer::type() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.MessageContainer.Type)
+ return static_cast< ::Tango::PMR::Common::MessageType >(type_);
+}
+inline void MessageContainer::set_type(::Tango::PMR::Common::MessageType value) {
+
+ type_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.MessageContainer.Type)
+}
+
+// string Token = 2;
+inline void MessageContainer::clear_token() {
+ token_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& MessageContainer::token() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.MessageContainer.Token)
+ return token_.GetNoArena();
+}
+inline void MessageContainer::set_token(const ::std::string& value) {
+
+ token_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.MessageContainer.Token)
+}
+#if LANG_CXX11
+inline void MessageContainer::set_token(::std::string&& value) {
+
+ token_.SetNoArena(
+ &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+ // @@protoc_insertion_point(field_set_rvalue:Tango.PMR.Common.MessageContainer.Token)
+}
+#endif
+inline void MessageContainer::set_token(const char* value) {
+ GOOGLE_DCHECK(value != NULL);
+
+ token_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:Tango.PMR.Common.MessageContainer.Token)
+}
+inline void MessageContainer::set_token(const char* value, size_t size) {
+
+ token_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:Tango.PMR.Common.MessageContainer.Token)
+}
+inline ::std::string* MessageContainer::mutable_token() {
+
+ // @@protoc_insertion_point(field_mutable:Tango.PMR.Common.MessageContainer.Token)
+ return token_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* MessageContainer::release_token() {
+ // @@protoc_insertion_point(field_release:Tango.PMR.Common.MessageContainer.Token)
+
+ return token_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void MessageContainer::set_allocated_token(::std::string* token) {
+ if (token != NULL) {
+
+ } else {
+
+ }
+ token_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), token);
+ // @@protoc_insertion_point(field_set_allocated:Tango.PMR.Common.MessageContainer.Token)
+}
+
+// bool Continuous = 3;
+inline void MessageContainer::clear_continuous() {
+ continuous_ = false;
+}
+inline bool MessageContainer::continuous() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.MessageContainer.Continuous)
+ return continuous_;
+}
+inline void MessageContainer::set_continuous(bool value) {
+
+ continuous_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.MessageContainer.Continuous)
+}
+
+// bool Completed = 4;
+inline void MessageContainer::clear_completed() {
+ completed_ = false;
+}
+inline bool MessageContainer::completed() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.MessageContainer.Completed)
+ return completed_;
+}
+inline void MessageContainer::set_completed(bool value) {
+
+ completed_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.MessageContainer.Completed)
+}
+
+// bytes Data = 5;
+inline void MessageContainer::clear_data() {
+ data_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& MessageContainer::data() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.MessageContainer.Data)
+ return data_.GetNoArena();
+}
+inline void MessageContainer::set_data(const ::std::string& value) {
+
+ data_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.MessageContainer.Data)
+}
+#if LANG_CXX11
+inline void MessageContainer::set_data(::std::string&& value) {
+
+ data_.SetNoArena(
+ &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+ // @@protoc_insertion_point(field_set_rvalue:Tango.PMR.Common.MessageContainer.Data)
+}
+#endif
+inline void MessageContainer::set_data(const char* value) {
+ GOOGLE_DCHECK(value != NULL);
+
+ data_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:Tango.PMR.Common.MessageContainer.Data)
+}
+inline void MessageContainer::set_data(const void* value, size_t size) {
+
+ data_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:Tango.PMR.Common.MessageContainer.Data)
+}
+inline ::std::string* MessageContainer::mutable_data() {
+
+ // @@protoc_insertion_point(field_mutable:Tango.PMR.Common.MessageContainer.Data)
+ return data_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* MessageContainer::release_data() {
+ // @@protoc_insertion_point(field_release:Tango.PMR.Common.MessageContainer.Data)
+
+ return data_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void MessageContainer::set_allocated_data(::std::string* data) {
+ if (data != NULL) {
+
+ } else {
+
+ }
+ data_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), data);
+ // @@protoc_insertion_point(field_set_allocated:Tango.PMR.Common.MessageContainer.Data)
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+
+} // namespace Common
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_MessageContainer_2eproto__INCLUDED
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageType.pb.cc b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageType.pb.cc
new file mode 100644
index 000000000..f1c5e4280
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageType.pb.cc
@@ -0,0 +1,138 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: MessageType.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "MessageType.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace Tango {
+namespace PMR {
+namespace Common {
+
+namespace protobuf_MessageType_2eproto {
+
+
+namespace {
+
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[1];
+
+} // namespace
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+ const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+ const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+ TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { NULL, NULL, 0, -1, -1, -1, -1, NULL, false },
+};
+
+const ::google::protobuf::uint32 TableStruct::offsets[1] = {};
+static const ::google::protobuf::internal::MigrationSchema* schemas = NULL;
+static const ::google::protobuf::Message* const* file_default_instances = NULL;
+namespace {
+
+void protobuf_AssignDescriptors() {
+ AddDescriptors();
+ ::google::protobuf::MessageFactory* factory = NULL;
+ AssignDescriptors(
+ "MessageType.proto", schemas, file_default_instances, TableStruct::offsets, factory,
+ NULL, file_level_enum_descriptors, NULL);
+}
+
+void protobuf_AssignDescriptorsOnce() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
+void protobuf_RegisterTypes(const ::std::string&) {
+ protobuf_AssignDescriptorsOnce();
+}
+
+} // namespace
+void TableStruct::InitDefaultsImpl() {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ ::google::protobuf::internal::InitProtobufDefaults();
+}
+
+void InitDefaults() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl);
+}
+namespace {
+void AddDescriptorsImpl() {
+ InitDefaults();
+ static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ "\n\021MessageType.proto\022\020Tango.PMR.Common*\204\001"
+ "\n\013MessageType\022\007\n\003RGB\020\000\022\007\n\003Job\020\001\022\013\n\007Segme"
+ "nt\020\002\022\024\n\020CalculateRequest\020\003\022\025\n\021CalculateR"
+ "esponse\020\004\022\023\n\017ProgressRequest\020\005\022\024\n\020Progre"
+ "ssResponse\020\006B\034\n\032com.twine.tango.pmr.comm"
+ "onb\006proto3"
+ };
+ ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+ descriptor, 210);
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+ "MessageType.proto", &protobuf_RegisterTypes);
+}
+} // anonymous namespace
+
+void AddDescriptors() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
+}
+// Force AddDescriptors() to be called at dynamic initialization time.
+struct StaticDescriptorInitializer {
+ StaticDescriptorInitializer() {
+ AddDescriptors();
+ }
+} static_descriptor_initializer;
+
+} // namespace protobuf_MessageType_2eproto
+
+const ::google::protobuf::EnumDescriptor* MessageType_descriptor() {
+ protobuf_MessageType_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_MessageType_2eproto::file_level_enum_descriptors[0];
+}
+bool MessageType_IsValid(int value) {
+ switch (value) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ return true;
+ default:
+ return false;
+ }
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace Common
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageType.pb.h b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageType.pb.h
new file mode 100644
index 000000000..45020a960
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/MessageType.pb.h
@@ -0,0 +1,123 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: MessageType.proto
+
+#ifndef PROTOBUF_MessageType_2eproto__INCLUDED
+#define PROTOBUF_MessageType_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 3004000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3004000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/repeated_field.h> // IWYU pragma: export
+#include <google/protobuf/extension_set.h> // IWYU pragma: export
+#include <google/protobuf/generated_enum_reflection.h>
+// @@protoc_insertion_point(includes)
+namespace Tango {
+namespace PMR {
+namespace Common {
+} // namespace Common
+} // namespace PMR
+} // namespace Tango
+
+namespace Tango {
+namespace PMR {
+namespace Common {
+
+namespace protobuf_MessageType_2eproto {
+// Internal implementation detail -- do not call these.
+struct TableStruct {
+ static const ::google::protobuf::internal::ParseTableField entries[];
+ static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+ static const ::google::protobuf::internal::ParseTable schema[];
+ static const ::google::protobuf::uint32 offsets[];
+ static const ::google::protobuf::internal::FieldMetadata field_metadata[];
+ static const ::google::protobuf::internal::SerializationTable serialization_table[];
+ static void InitDefaultsImpl();
+};
+void AddDescriptors();
+void InitDefaults();
+} // namespace protobuf_MessageType_2eproto
+
+enum MessageType {
+ RGB = 0,
+ Job = 1,
+ Segment = 2,
+ CalculateRequest = 3,
+ CalculateResponse = 4,
+ ProgressRequest = 5,
+ ProgressResponse = 6,
+ MessageType_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,
+ MessageType_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
+};
+bool MessageType_IsValid(int value);
+const MessageType MessageType_MIN = RGB;
+const MessageType MessageType_MAX = ProgressResponse;
+const int MessageType_ARRAYSIZE = MessageType_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* MessageType_descriptor();
+inline const ::std::string& MessageType_Name(MessageType value) {
+ return ::google::protobuf::internal::NameOfEnum(
+ MessageType_descriptor(), value);
+}
+inline bool MessageType_Parse(
+ const ::std::string& name, MessageType* value) {
+ return ::google::protobuf::internal::ParseNamedEnum<MessageType>(
+ MessageType_descriptor(), name, value);
+}
+// ===================================================================
+
+
+// ===================================================================
+
+
+// ===================================================================
+
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+
+} // namespace Common
+} // namespace PMR
+} // namespace Tango
+
+namespace google {
+namespace protobuf {
+
+template <> struct is_proto_enum< ::Tango::PMR::Common::MessageType> : ::google::protobuf::internal::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::Tango::PMR::Common::MessageType>() {
+ return ::Tango::PMR::Common::MessageType_descriptor();
+}
+
+} // namespace protobuf
+} // namespace google
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_MessageType_2eproto__INCLUDED
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressRequest.pb.cc b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressRequest.pb.cc
new file mode 100644
index 000000000..39adb6a72
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressRequest.pb.cc
@@ -0,0 +1,332 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: ProgressRequest.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "ProgressRequest.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace Tango {
+namespace PMR {
+namespace Stubs {
+class ProgressRequestDefaultTypeInternal {
+public:
+ ::google::protobuf::internal::ExplicitlyConstructed<ProgressRequest>
+ _instance;
+} _ProgressRequest_default_instance_;
+
+namespace protobuf_ProgressRequest_2eproto {
+
+
+namespace {
+
+::google::protobuf::Metadata file_level_metadata[1];
+
+} // namespace
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+ const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+ const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+ TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { NULL, NULL, 0, -1, -1, -1, -1, NULL, false },
+};
+
+const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ~0u, // no _has_bits_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ProgressRequest, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, sizeof(ProgressRequest)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::google::protobuf::Message*>(&_ProgressRequest_default_instance_),
+};
+
+namespace {
+
+void protobuf_AssignDescriptors() {
+ AddDescriptors();
+ ::google::protobuf::MessageFactory* factory = NULL;
+ AssignDescriptors(
+ "ProgressRequest.proto", schemas, file_default_instances, TableStruct::offsets, factory,
+ file_level_metadata, NULL, NULL);
+}
+
+void protobuf_AssignDescriptorsOnce() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
+void protobuf_RegisterTypes(const ::std::string&) {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
+}
+
+} // namespace
+void TableStruct::InitDefaultsImpl() {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ ::google::protobuf::internal::InitProtobufDefaults();
+ _ProgressRequest_default_instance_._instance.DefaultConstruct();
+ ::google::protobuf::internal::OnShutdownDestroyMessage(
+ &_ProgressRequest_default_instance_);}
+
+void InitDefaults() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl);
+}
+namespace {
+void AddDescriptorsImpl() {
+ InitDefaults();
+ static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ "\n\025ProgressRequest.proto\022\017Tango.PMR.Stubs"
+ "\"\021\n\017ProgressRequestB\033\n\031com.twine.tango.p"
+ "mr.stubsb\006proto3"
+ };
+ ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+ descriptor, 96);
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+ "ProgressRequest.proto", &protobuf_RegisterTypes);
+}
+} // anonymous namespace
+
+void AddDescriptors() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
+}
+// Force AddDescriptors() to be called at dynamic initialization time.
+struct StaticDescriptorInitializer {
+ StaticDescriptorInitializer() {
+ AddDescriptors();
+ }
+} static_descriptor_initializer;
+
+} // namespace protobuf_ProgressRequest_2eproto
+
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ProgressRequest::ProgressRequest()
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+ if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
+ protobuf_ProgressRequest_2eproto::InitDefaults();
+ }
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:Tango.PMR.Stubs.ProgressRequest)
+}
+ProgressRequest::ProgressRequest(const ProgressRequest& from)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL),
+ _cached_size_(0) {
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ // @@protoc_insertion_point(copy_constructor:Tango.PMR.Stubs.ProgressRequest)
+}
+
+void ProgressRequest::SharedCtor() {
+ _cached_size_ = 0;
+}
+
+ProgressRequest::~ProgressRequest() {
+ // @@protoc_insertion_point(destructor:Tango.PMR.Stubs.ProgressRequest)
+ SharedDtor();
+}
+
+void ProgressRequest::SharedDtor() {
+}
+
+void ProgressRequest::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ProgressRequest::descriptor() {
+ protobuf_ProgressRequest_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_ProgressRequest_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
+}
+
+const ProgressRequest& ProgressRequest::default_instance() {
+ protobuf_ProgressRequest_2eproto::InitDefaults();
+ return *internal_default_instance();
+}
+
+ProgressRequest* ProgressRequest::New(::google::protobuf::Arena* arena) const {
+ ProgressRequest* n = new ProgressRequest;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
+}
+
+void ProgressRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:Tango.PMR.Stubs.ProgressRequest)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ _internal_metadata_.Clear();
+}
+
+bool ProgressRequest::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:Tango.PMR.Stubs.ProgressRequest)
+ for (;;) {
+ ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+ tag = p.first;
+ if (!p.second) goto handle_unusual;
+ handle_unusual:
+ if (tag == 0) {
+ goto success;
+ }
+ DO_(::google::protobuf::internal::WireFormat::SkipField(
+ input, tag, _internal_metadata_.mutable_unknown_fields()));
+ }
+success:
+ // @@protoc_insertion_point(parse_success:Tango.PMR.Stubs.ProgressRequest)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:Tango.PMR.Stubs.ProgressRequest)
+ return false;
+#undef DO_
+}
+
+void ProgressRequest::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:Tango.PMR.Stubs.ProgressRequest)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output);
+ }
+ // @@protoc_insertion_point(serialize_end:Tango.PMR.Stubs.ProgressRequest)
+}
+
+::google::protobuf::uint8* ProgressRequest::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
+ (void)deterministic; // Unused
+ // @@protoc_insertion_point(serialize_to_array_start:Tango.PMR.Stubs.ProgressRequest)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:Tango.PMR.Stubs.ProgressRequest)
+ return target;
+}
+
+size_t ProgressRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:Tango.PMR.Stubs.ProgressRequest)
+ size_t total_size = 0;
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ total_size +=
+ ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()));
+ }
+ int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = cached_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void ProgressRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:Tango.PMR.Stubs.ProgressRequest)
+ GOOGLE_DCHECK_NE(&from, this);
+ const ProgressRequest* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const ProgressRequest>(
+ &from);
+ if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Tango.PMR.Stubs.ProgressRequest)
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Tango.PMR.Stubs.ProgressRequest)
+ MergeFrom(*source);
+ }
+}
+
+void ProgressRequest::MergeFrom(const ProgressRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:Tango.PMR.Stubs.ProgressRequest)
+ GOOGLE_DCHECK_NE(&from, this);
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+}
+
+void ProgressRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Tango.PMR.Stubs.ProgressRequest)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void ProgressRequest::CopyFrom(const ProgressRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Tango.PMR.Stubs.ProgressRequest)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool ProgressRequest::IsInitialized() const {
+ return true;
+}
+
+void ProgressRequest::Swap(ProgressRequest* other) {
+ if (other == this) return;
+ InternalSwap(other);
+}
+void ProgressRequest::InternalSwap(ProgressRequest* other) {
+ using std::swap;
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata ProgressRequest::GetMetadata() const {
+ protobuf_ProgressRequest_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_ProgressRequest_2eproto::file_level_metadata[kIndexInFileMessages];
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ProgressRequest
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace Stubs
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressRequest.pb.h b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressRequest.pb.h
new file mode 100644
index 000000000..a41147953
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressRequest.pb.h
@@ -0,0 +1,178 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: ProgressRequest.proto
+
+#ifndef PROTOBUF_ProgressRequest_2eproto__INCLUDED
+#define PROTOBUF_ProgressRequest_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 3004000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3004000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h> // IWYU pragma: export
+#include <google/protobuf/extension_set.h> // IWYU pragma: export
+#include <google/protobuf/unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+namespace Tango {
+namespace PMR {
+namespace Stubs {
+class ProgressRequest;
+class ProgressRequestDefaultTypeInternal;
+extern ProgressRequestDefaultTypeInternal _ProgressRequest_default_instance_;
+} // namespace Stubs
+} // namespace PMR
+} // namespace Tango
+
+namespace Tango {
+namespace PMR {
+namespace Stubs {
+
+namespace protobuf_ProgressRequest_2eproto {
+// Internal implementation detail -- do not call these.
+struct TableStruct {
+ static const ::google::protobuf::internal::ParseTableField entries[];
+ static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+ static const ::google::protobuf::internal::ParseTable schema[];
+ static const ::google::protobuf::uint32 offsets[];
+ static const ::google::protobuf::internal::FieldMetadata field_metadata[];
+ static const ::google::protobuf::internal::SerializationTable serialization_table[];
+ static void InitDefaultsImpl();
+};
+void AddDescriptors();
+void InitDefaults();
+} // namespace protobuf_ProgressRequest_2eproto
+
+// ===================================================================
+
+class ProgressRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Tango.PMR.Stubs.ProgressRequest) */ {
+ public:
+ ProgressRequest();
+ virtual ~ProgressRequest();
+
+ ProgressRequest(const ProgressRequest& from);
+
+ inline ProgressRequest& operator=(const ProgressRequest& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ #if LANG_CXX11
+ ProgressRequest(ProgressRequest&& from) noexcept
+ : ProgressRequest() {
+ *this = ::std::move(from);
+ }
+
+ inline ProgressRequest& operator=(ProgressRequest&& from) noexcept {
+ if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+ if (this != &from) InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+ #endif
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const ProgressRequest& default_instance();
+
+ static inline const ProgressRequest* internal_default_instance() {
+ return reinterpret_cast<const ProgressRequest*>(
+ &_ProgressRequest_default_instance_);
+ }
+ static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+ 0;
+
+ void Swap(ProgressRequest* other);
+ friend void swap(ProgressRequest& a, ProgressRequest& b) {
+ a.Swap(&b);
+ }
+
+ // implements Message ----------------------------------------------
+
+ inline ProgressRequest* New() const PROTOBUF_FINAL { return New(NULL); }
+
+ ProgressRequest* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+ void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void CopyFrom(const ProgressRequest& from);
+ void MergeFrom(const ProgressRequest& from);
+ void Clear() PROTOBUF_FINAL;
+ bool IsInitialized() const PROTOBUF_FINAL;
+
+ size_t ByteSizeLong() const PROTOBUF_FINAL;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
+ int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const PROTOBUF_FINAL;
+ void InternalSwap(ProgressRequest* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return NULL;
+ }
+ inline void* MaybeArenaPtr() const {
+ return NULL;
+ }
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // @@protoc_insertion_point(class_scope:Tango.PMR.Stubs.ProgressRequest)
+ private:
+
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ mutable int _cached_size_;
+ friend struct protobuf_ProgressRequest_2eproto::TableStruct;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// ProgressRequest
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+
+} // namespace Stubs
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_ProgressRequest_2eproto__INCLUDED
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressResponse.pb.cc b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressResponse.pb.cc
new file mode 100644
index 000000000..7769c1c0c
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressResponse.pb.cc
@@ -0,0 +1,389 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: ProgressResponse.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "ProgressResponse.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace Tango {
+namespace PMR {
+namespace Stubs {
+class ProgressResponseDefaultTypeInternal {
+public:
+ ::google::protobuf::internal::ExplicitlyConstructed<ProgressResponse>
+ _instance;
+} _ProgressResponse_default_instance_;
+
+namespace protobuf_ProgressResponse_2eproto {
+
+
+namespace {
+
+::google::protobuf::Metadata file_level_metadata[1];
+
+} // namespace
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+ const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+ const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+ TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { NULL, NULL, 0, -1, -1, -1, -1, NULL, false },
+};
+
+const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ~0u, // no _has_bits_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ProgressResponse, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ProgressResponse, progress_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, sizeof(ProgressResponse)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::google::protobuf::Message*>(&_ProgressResponse_default_instance_),
+};
+
+namespace {
+
+void protobuf_AssignDescriptors() {
+ AddDescriptors();
+ ::google::protobuf::MessageFactory* factory = NULL;
+ AssignDescriptors(
+ "ProgressResponse.proto", schemas, file_default_instances, TableStruct::offsets, factory,
+ file_level_metadata, NULL, NULL);
+}
+
+void protobuf_AssignDescriptorsOnce() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
+void protobuf_RegisterTypes(const ::std::string&) {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
+}
+
+} // namespace
+void TableStruct::InitDefaultsImpl() {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ ::google::protobuf::internal::InitProtobufDefaults();
+ _ProgressResponse_default_instance_._instance.DefaultConstruct();
+ ::google::protobuf::internal::OnShutdownDestroyMessage(
+ &_ProgressResponse_default_instance_);}
+
+void InitDefaults() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl);
+}
+namespace {
+void AddDescriptorsImpl() {
+ InitDefaults();
+ static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ "\n\026ProgressResponse.proto\022\017Tango.PMR.Stub"
+ "s\"$\n\020ProgressResponse\022\020\n\010Progress\030\001 \001(\001B"
+ "\033\n\031com.twine.tango.pmr.stubsb\006proto3"
+ };
+ ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+ descriptor, 116);
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+ "ProgressResponse.proto", &protobuf_RegisterTypes);
+}
+} // anonymous namespace
+
+void AddDescriptors() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
+}
+// Force AddDescriptors() to be called at dynamic initialization time.
+struct StaticDescriptorInitializer {
+ StaticDescriptorInitializer() {
+ AddDescriptors();
+ }
+} static_descriptor_initializer;
+
+} // namespace protobuf_ProgressResponse_2eproto
+
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ProgressResponse::kProgressFieldNumber;
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ProgressResponse::ProgressResponse()
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+ if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
+ protobuf_ProgressResponse_2eproto::InitDefaults();
+ }
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:Tango.PMR.Stubs.ProgressResponse)
+}
+ProgressResponse::ProgressResponse(const ProgressResponse& from)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL),
+ _cached_size_(0) {
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ progress_ = from.progress_;
+ // @@protoc_insertion_point(copy_constructor:Tango.PMR.Stubs.ProgressResponse)
+}
+
+void ProgressResponse::SharedCtor() {
+ progress_ = 0;
+ _cached_size_ = 0;
+}
+
+ProgressResponse::~ProgressResponse() {
+ // @@protoc_insertion_point(destructor:Tango.PMR.Stubs.ProgressResponse)
+ SharedDtor();
+}
+
+void ProgressResponse::SharedDtor() {
+}
+
+void ProgressResponse::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ProgressResponse::descriptor() {
+ protobuf_ProgressResponse_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_ProgressResponse_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
+}
+
+const ProgressResponse& ProgressResponse::default_instance() {
+ protobuf_ProgressResponse_2eproto::InitDefaults();
+ return *internal_default_instance();
+}
+
+ProgressResponse* ProgressResponse::New(::google::protobuf::Arena* arena) const {
+ ProgressResponse* n = new ProgressResponse;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
+}
+
+void ProgressResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:Tango.PMR.Stubs.ProgressResponse)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ progress_ = 0;
+ _internal_metadata_.Clear();
+}
+
+bool ProgressResponse::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:Tango.PMR.Stubs.ProgressResponse)
+ for (;;) {
+ ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+ tag = p.first;
+ if (!p.second) goto handle_unusual;
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // double Progress = 1;
+ case 1: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(9u /* 9 & 0xFF */)) {
+
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
+ input, &progress_)));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ default: {
+ handle_unusual:
+ if (tag == 0) {
+ goto success;
+ }
+ DO_(::google::protobuf::internal::WireFormat::SkipField(
+ input, tag, _internal_metadata_.mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+success:
+ // @@protoc_insertion_point(parse_success:Tango.PMR.Stubs.ProgressResponse)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:Tango.PMR.Stubs.ProgressResponse)
+ return false;
+#undef DO_
+}
+
+void ProgressResponse::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:Tango.PMR.Stubs.ProgressResponse)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // double Progress = 1;
+ if (this->progress() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->progress(), output);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output);
+ }
+ // @@protoc_insertion_point(serialize_end:Tango.PMR.Stubs.ProgressResponse)
+}
+
+::google::protobuf::uint8* ProgressResponse::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
+ (void)deterministic; // Unused
+ // @@protoc_insertion_point(serialize_to_array_start:Tango.PMR.Stubs.ProgressResponse)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // double Progress = 1;
+ if (this->progress() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->progress(), target);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:Tango.PMR.Stubs.ProgressResponse)
+ return target;
+}
+
+size_t ProgressResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:Tango.PMR.Stubs.ProgressResponse)
+ size_t total_size = 0;
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ total_size +=
+ ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()));
+ }
+ // double Progress = 1;
+ if (this->progress() != 0) {
+ total_size += 1 + 8;
+ }
+
+ int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = cached_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void ProgressResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:Tango.PMR.Stubs.ProgressResponse)
+ GOOGLE_DCHECK_NE(&from, this);
+ const ProgressResponse* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const ProgressResponse>(
+ &from);
+ if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Tango.PMR.Stubs.ProgressResponse)
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Tango.PMR.Stubs.ProgressResponse)
+ MergeFrom(*source);
+ }
+}
+
+void ProgressResponse::MergeFrom(const ProgressResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:Tango.PMR.Stubs.ProgressResponse)
+ GOOGLE_DCHECK_NE(&from, this);
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from.progress() != 0) {
+ set_progress(from.progress());
+ }
+}
+
+void ProgressResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Tango.PMR.Stubs.ProgressResponse)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void ProgressResponse::CopyFrom(const ProgressResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Tango.PMR.Stubs.ProgressResponse)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool ProgressResponse::IsInitialized() const {
+ return true;
+}
+
+void ProgressResponse::Swap(ProgressResponse* other) {
+ if (other == this) return;
+ InternalSwap(other);
+}
+void ProgressResponse::InternalSwap(ProgressResponse* other) {
+ using std::swap;
+ swap(progress_, other->progress_);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata ProgressResponse::GetMetadata() const {
+ protobuf_ProgressResponse_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_ProgressResponse_2eproto::file_level_metadata[kIndexInFileMessages];
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ProgressResponse
+
+// double Progress = 1;
+void ProgressResponse::clear_progress() {
+ progress_ = 0;
+}
+double ProgressResponse::progress() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Stubs.ProgressResponse.Progress)
+ return progress_;
+}
+void ProgressResponse::set_progress(double value) {
+
+ progress_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Stubs.ProgressResponse.Progress)
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace Stubs
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressResponse.pb.h b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressResponse.pb.h
new file mode 100644
index 000000000..74f5ecc57
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/ProgressResponse.pb.h
@@ -0,0 +1,199 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: ProgressResponse.proto
+
+#ifndef PROTOBUF_ProgressResponse_2eproto__INCLUDED
+#define PROTOBUF_ProgressResponse_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 3004000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3004000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h> // IWYU pragma: export
+#include <google/protobuf/extension_set.h> // IWYU pragma: export
+#include <google/protobuf/unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+namespace Tango {
+namespace PMR {
+namespace Stubs {
+class ProgressResponse;
+class ProgressResponseDefaultTypeInternal;
+extern ProgressResponseDefaultTypeInternal _ProgressResponse_default_instance_;
+} // namespace Stubs
+} // namespace PMR
+} // namespace Tango
+
+namespace Tango {
+namespace PMR {
+namespace Stubs {
+
+namespace protobuf_ProgressResponse_2eproto {
+// Internal implementation detail -- do not call these.
+struct TableStruct {
+ static const ::google::protobuf::internal::ParseTableField entries[];
+ static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+ static const ::google::protobuf::internal::ParseTable schema[];
+ static const ::google::protobuf::uint32 offsets[];
+ static const ::google::protobuf::internal::FieldMetadata field_metadata[];
+ static const ::google::protobuf::internal::SerializationTable serialization_table[];
+ static void InitDefaultsImpl();
+};
+void AddDescriptors();
+void InitDefaults();
+} // namespace protobuf_ProgressResponse_2eproto
+
+// ===================================================================
+
+class ProgressResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Tango.PMR.Stubs.ProgressResponse) */ {
+ public:
+ ProgressResponse();
+ virtual ~ProgressResponse();
+
+ ProgressResponse(const ProgressResponse& from);
+
+ inline ProgressResponse& operator=(const ProgressResponse& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ #if LANG_CXX11
+ ProgressResponse(ProgressResponse&& from) noexcept
+ : ProgressResponse() {
+ *this = ::std::move(from);
+ }
+
+ inline ProgressResponse& operator=(ProgressResponse&& from) noexcept {
+ if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+ if (this != &from) InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+ #endif
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const ProgressResponse& default_instance();
+
+ static inline const ProgressResponse* internal_default_instance() {
+ return reinterpret_cast<const ProgressResponse*>(
+ &_ProgressResponse_default_instance_);
+ }
+ static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+ 0;
+
+ void Swap(ProgressResponse* other);
+ friend void swap(ProgressResponse& a, ProgressResponse& b) {
+ a.Swap(&b);
+ }
+
+ // implements Message ----------------------------------------------
+
+ inline ProgressResponse* New() const PROTOBUF_FINAL { return New(NULL); }
+
+ ProgressResponse* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+ void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void CopyFrom(const ProgressResponse& from);
+ void MergeFrom(const ProgressResponse& from);
+ void Clear() PROTOBUF_FINAL;
+ bool IsInitialized() const PROTOBUF_FINAL;
+
+ size_t ByteSizeLong() const PROTOBUF_FINAL;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
+ int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const PROTOBUF_FINAL;
+ void InternalSwap(ProgressResponse* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return NULL;
+ }
+ inline void* MaybeArenaPtr() const {
+ return NULL;
+ }
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // double Progress = 1;
+ void clear_progress();
+ static const int kProgressFieldNumber = 1;
+ double progress() const;
+ void set_progress(double value);
+
+ // @@protoc_insertion_point(class_scope:Tango.PMR.Stubs.ProgressResponse)
+ private:
+
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ double progress_;
+ mutable int _cached_size_;
+ friend struct protobuf_ProgressResponse_2eproto::TableStruct;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// ProgressResponse
+
+// double Progress = 1;
+inline void ProgressResponse::clear_progress() {
+ progress_ = 0;
+}
+inline double ProgressResponse::progress() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Stubs.ProgressResponse.Progress)
+ return progress_;
+}
+inline void ProgressResponse::set_progress(double value) {
+
+ progress_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Stubs.ProgressResponse.Progress)
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+
+} // namespace Stubs
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_ProgressResponse_2eproto__INCLUDED
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/RGB.pb.cc b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/RGB.pb.cc
new file mode 100644
index 000000000..6e729877b
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/RGB.pb.cc
@@ -0,0 +1,499 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: RGB.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "RGB.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace Tango {
+namespace PMR {
+namespace Common {
+class RGBDefaultTypeInternal {
+public:
+ ::google::protobuf::internal::ExplicitlyConstructed<RGB>
+ _instance;
+} _RGB_default_instance_;
+
+namespace protobuf_RGB_2eproto {
+
+
+namespace {
+
+::google::protobuf::Metadata file_level_metadata[1];
+
+} // namespace
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+ const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+ const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+ TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { NULL, NULL, 0, -1, -1, -1, -1, NULL, false },
+};
+
+const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ~0u, // no _has_bits_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RGB, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RGB, r_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RGB, g_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RGB, b_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, sizeof(RGB)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::google::protobuf::Message*>(&_RGB_default_instance_),
+};
+
+namespace {
+
+void protobuf_AssignDescriptors() {
+ AddDescriptors();
+ ::google::protobuf::MessageFactory* factory = NULL;
+ AssignDescriptors(
+ "RGB.proto", schemas, file_default_instances, TableStruct::offsets, factory,
+ file_level_metadata, NULL, NULL);
+}
+
+void protobuf_AssignDescriptorsOnce() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
+void protobuf_RegisterTypes(const ::std::string&) {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
+}
+
+} // namespace
+void TableStruct::InitDefaultsImpl() {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ ::google::protobuf::internal::InitProtobufDefaults();
+ _RGB_default_instance_._instance.DefaultConstruct();
+ ::google::protobuf::internal::OnShutdownDestroyMessage(
+ &_RGB_default_instance_);}
+
+void InitDefaults() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl);
+}
+namespace {
+void AddDescriptorsImpl() {
+ InitDefaults();
+ static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ "\n\tRGB.proto\022\020Tango.PMR.Common\"&\n\003RGB\022\t\n\001"
+ "R\030\001 \001(\005\022\t\n\001G\030\002 \001(\005\022\t\n\001B\030\003 \001(\005B\034\n\032com.twi"
+ "ne.tango.pmr.commonb\006proto3"
+ };
+ ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+ descriptor, 107);
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+ "RGB.proto", &protobuf_RegisterTypes);
+}
+} // anonymous namespace
+
+void AddDescriptors() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
+}
+// Force AddDescriptors() to be called at dynamic initialization time.
+struct StaticDescriptorInitializer {
+ StaticDescriptorInitializer() {
+ AddDescriptors();
+ }
+} static_descriptor_initializer;
+
+} // namespace protobuf_RGB_2eproto
+
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int RGB::kRFieldNumber;
+const int RGB::kGFieldNumber;
+const int RGB::kBFieldNumber;
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+RGB::RGB()
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+ if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
+ protobuf_RGB_2eproto::InitDefaults();
+ }
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:Tango.PMR.Common.RGB)
+}
+RGB::RGB(const RGB& from)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL),
+ _cached_size_(0) {
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ ::memcpy(&r_, &from.r_,
+ static_cast<size_t>(reinterpret_cast<char*>(&b_) -
+ reinterpret_cast<char*>(&r_)) + sizeof(b_));
+ // @@protoc_insertion_point(copy_constructor:Tango.PMR.Common.RGB)
+}
+
+void RGB::SharedCtor() {
+ ::memset(&r_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&b_) -
+ reinterpret_cast<char*>(&r_)) + sizeof(b_));
+ _cached_size_ = 0;
+}
+
+RGB::~RGB() {
+ // @@protoc_insertion_point(destructor:Tango.PMR.Common.RGB)
+ SharedDtor();
+}
+
+void RGB::SharedDtor() {
+}
+
+void RGB::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* RGB::descriptor() {
+ protobuf_RGB_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_RGB_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
+}
+
+const RGB& RGB::default_instance() {
+ protobuf_RGB_2eproto::InitDefaults();
+ return *internal_default_instance();
+}
+
+RGB* RGB::New(::google::protobuf::Arena* arena) const {
+ RGB* n = new RGB;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
+}
+
+void RGB::Clear() {
+// @@protoc_insertion_point(message_clear_start:Tango.PMR.Common.RGB)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ ::memset(&r_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&b_) -
+ reinterpret_cast<char*>(&r_)) + sizeof(b_));
+ _internal_metadata_.Clear();
+}
+
+bool RGB::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:Tango.PMR.Common.RGB)
+ for (;;) {
+ ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+ tag = p.first;
+ if (!p.second) goto handle_unusual;
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // int32 R = 1;
+ case 1: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &r_)));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ // int32 G = 2;
+ case 2: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
+
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &g_)));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ // int32 B = 3;
+ case 3: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
+
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &b_)));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ default: {
+ handle_unusual:
+ if (tag == 0) {
+ goto success;
+ }
+ DO_(::google::protobuf::internal::WireFormat::SkipField(
+ input, tag, _internal_metadata_.mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+success:
+ // @@protoc_insertion_point(parse_success:Tango.PMR.Common.RGB)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:Tango.PMR.Common.RGB)
+ return false;
+#undef DO_
+}
+
+void RGB::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:Tango.PMR.Common.RGB)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // int32 R = 1;
+ if (this->r() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->r(), output);
+ }
+
+ // int32 G = 2;
+ if (this->g() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->g(), output);
+ }
+
+ // int32 B = 3;
+ if (this->b() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->b(), output);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output);
+ }
+ // @@protoc_insertion_point(serialize_end:Tango.PMR.Common.RGB)
+}
+
+::google::protobuf::uint8* RGB::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
+ (void)deterministic; // Unused
+ // @@protoc_insertion_point(serialize_to_array_start:Tango.PMR.Common.RGB)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // int32 R = 1;
+ if (this->r() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->r(), target);
+ }
+
+ // int32 G = 2;
+ if (this->g() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->g(), target);
+ }
+
+ // int32 B = 3;
+ if (this->b() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->b(), target);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:Tango.PMR.Common.RGB)
+ return target;
+}
+
+size_t RGB::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:Tango.PMR.Common.RGB)
+ size_t total_size = 0;
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ total_size +=
+ ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()));
+ }
+ // int32 R = 1;
+ if (this->r() != 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->r());
+ }
+
+ // int32 G = 2;
+ if (this->g() != 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->g());
+ }
+
+ // int32 B = 3;
+ if (this->b() != 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->b());
+ }
+
+ int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = cached_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void RGB::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:Tango.PMR.Common.RGB)
+ GOOGLE_DCHECK_NE(&from, this);
+ const RGB* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const RGB>(
+ &from);
+ if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Tango.PMR.Common.RGB)
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Tango.PMR.Common.RGB)
+ MergeFrom(*source);
+ }
+}
+
+void RGB::MergeFrom(const RGB& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:Tango.PMR.Common.RGB)
+ GOOGLE_DCHECK_NE(&from, this);
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from.r() != 0) {
+ set_r(from.r());
+ }
+ if (from.g() != 0) {
+ set_g(from.g());
+ }
+ if (from.b() != 0) {
+ set_b(from.b());
+ }
+}
+
+void RGB::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Tango.PMR.Common.RGB)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void RGB::CopyFrom(const RGB& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Tango.PMR.Common.RGB)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool RGB::IsInitialized() const {
+ return true;
+}
+
+void RGB::Swap(RGB* other) {
+ if (other == this) return;
+ InternalSwap(other);
+}
+void RGB::InternalSwap(RGB* other) {
+ using std::swap;
+ swap(r_, other->r_);
+ swap(g_, other->g_);
+ swap(b_, other->b_);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata RGB::GetMetadata() const {
+ protobuf_RGB_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_RGB_2eproto::file_level_metadata[kIndexInFileMessages];
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// RGB
+
+// int32 R = 1;
+void RGB::clear_r() {
+ r_ = 0;
+}
+::google::protobuf::int32 RGB::r() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.RGB.R)
+ return r_;
+}
+void RGB::set_r(::google::protobuf::int32 value) {
+
+ r_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.RGB.R)
+}
+
+// int32 G = 2;
+void RGB::clear_g() {
+ g_ = 0;
+}
+::google::protobuf::int32 RGB::g() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.RGB.G)
+ return g_;
+}
+void RGB::set_g(::google::protobuf::int32 value) {
+
+ g_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.RGB.G)
+}
+
+// int32 B = 3;
+void RGB::clear_b() {
+ b_ = 0;
+}
+::google::protobuf::int32 RGB::b() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.RGB.B)
+ return b_;
+}
+void RGB::set_b(::google::protobuf::int32 value) {
+
+ b_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.RGB.B)
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace Common
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/RGB.pb.h b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/RGB.pb.h
new file mode 100644
index 000000000..615906e12
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/RGB.pb.h
@@ -0,0 +1,241 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: RGB.proto
+
+#ifndef PROTOBUF_RGB_2eproto__INCLUDED
+#define PROTOBUF_RGB_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 3004000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3004000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h> // IWYU pragma: export
+#include <google/protobuf/extension_set.h> // IWYU pragma: export
+#include <google/protobuf/unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+namespace Tango {
+namespace PMR {
+namespace Common {
+class RGB;
+class RGBDefaultTypeInternal;
+extern RGBDefaultTypeInternal _RGB_default_instance_;
+} // namespace Common
+} // namespace PMR
+} // namespace Tango
+
+namespace Tango {
+namespace PMR {
+namespace Common {
+
+namespace protobuf_RGB_2eproto {
+// Internal implementation detail -- do not call these.
+struct TableStruct {
+ static const ::google::protobuf::internal::ParseTableField entries[];
+ static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+ static const ::google::protobuf::internal::ParseTable schema[];
+ static const ::google::protobuf::uint32 offsets[];
+ static const ::google::protobuf::internal::FieldMetadata field_metadata[];
+ static const ::google::protobuf::internal::SerializationTable serialization_table[];
+ static void InitDefaultsImpl();
+};
+void AddDescriptors();
+void InitDefaults();
+} // namespace protobuf_RGB_2eproto
+
+// ===================================================================
+
+class RGB : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Tango.PMR.Common.RGB) */ {
+ public:
+ RGB();
+ virtual ~RGB();
+
+ RGB(const RGB& from);
+
+ inline RGB& operator=(const RGB& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ #if LANG_CXX11
+ RGB(RGB&& from) noexcept
+ : RGB() {
+ *this = ::std::move(from);
+ }
+
+ inline RGB& operator=(RGB&& from) noexcept {
+ if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+ if (this != &from) InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+ #endif
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const RGB& default_instance();
+
+ static inline const RGB* internal_default_instance() {
+ return reinterpret_cast<const RGB*>(
+ &_RGB_default_instance_);
+ }
+ static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+ 0;
+
+ void Swap(RGB* other);
+ friend void swap(RGB& a, RGB& b) {
+ a.Swap(&b);
+ }
+
+ // implements Message ----------------------------------------------
+
+ inline RGB* New() const PROTOBUF_FINAL { return New(NULL); }
+
+ RGB* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+ void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void CopyFrom(const RGB& from);
+ void MergeFrom(const RGB& from);
+ void Clear() PROTOBUF_FINAL;
+ bool IsInitialized() const PROTOBUF_FINAL;
+
+ size_t ByteSizeLong() const PROTOBUF_FINAL;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
+ int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const PROTOBUF_FINAL;
+ void InternalSwap(RGB* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return NULL;
+ }
+ inline void* MaybeArenaPtr() const {
+ return NULL;
+ }
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // int32 R = 1;
+ void clear_r();
+ static const int kRFieldNumber = 1;
+ ::google::protobuf::int32 r() const;
+ void set_r(::google::protobuf::int32 value);
+
+ // int32 G = 2;
+ void clear_g();
+ static const int kGFieldNumber = 2;
+ ::google::protobuf::int32 g() const;
+ void set_g(::google::protobuf::int32 value);
+
+ // int32 B = 3;
+ void clear_b();
+ static const int kBFieldNumber = 3;
+ ::google::protobuf::int32 b() const;
+ void set_b(::google::protobuf::int32 value);
+
+ // @@protoc_insertion_point(class_scope:Tango.PMR.Common.RGB)
+ private:
+
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ ::google::protobuf::int32 r_;
+ ::google::protobuf::int32 g_;
+ ::google::protobuf::int32 b_;
+ mutable int _cached_size_;
+ friend struct protobuf_RGB_2eproto::TableStruct;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// RGB
+
+// int32 R = 1;
+inline void RGB::clear_r() {
+ r_ = 0;
+}
+inline ::google::protobuf::int32 RGB::r() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.RGB.R)
+ return r_;
+}
+inline void RGB::set_r(::google::protobuf::int32 value) {
+
+ r_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.RGB.R)
+}
+
+// int32 G = 2;
+inline void RGB::clear_g() {
+ g_ = 0;
+}
+inline ::google::protobuf::int32 RGB::g() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.RGB.G)
+ return g_;
+}
+inline void RGB::set_g(::google::protobuf::int32 value) {
+
+ g_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.RGB.G)
+}
+
+// int32 B = 3;
+inline void RGB::clear_b() {
+ b_ = 0;
+}
+inline ::google::protobuf::int32 RGB::b() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Common.RGB.B)
+ return b_;
+}
+inline void RGB::set_b(::google::protobuf::int32 value) {
+
+ b_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Common.RGB.B)
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+
+} // namespace Common
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_RGB_2eproto__INCLUDED
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Segment.pb.cc b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Segment.pb.cc
new file mode 100644
index 000000000..aaa262f6c
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Segment.pb.cc
@@ -0,0 +1,597 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: Segment.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "Segment.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace Tango {
+namespace PMR {
+namespace Jobs {
+class SegmentDefaultTypeInternal {
+public:
+ ::google::protobuf::internal::ExplicitlyConstructed<Segment>
+ _instance;
+} _Segment_default_instance_;
+
+namespace protobuf_Segment_2eproto {
+
+
+namespace {
+
+::google::protobuf::Metadata file_level_metadata[1];
+
+} // namespace
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField
+ const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},
+};
+
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField
+ const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ::google::protobuf::internal::AuxillaryParseTableField(),
+};
+PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const
+ TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { NULL, NULL, 0, -1, -1, -1, -1, NULL, false },
+};
+
+const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ ~0u, // no _has_bits_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Segment, _internal_metadata_),
+ ~0u, // no _extensions_
+ ~0u, // no _oneof_case_
+ ~0u, // no _weak_field_map_
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Segment, name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Segment, length_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Segment, color_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ { 0, -1, sizeof(Segment)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+ reinterpret_cast<const ::google::protobuf::Message*>(&_Segment_default_instance_),
+};
+
+namespace {
+
+void protobuf_AssignDescriptors() {
+ AddDescriptors();
+ ::google::protobuf::MessageFactory* factory = NULL;
+ AssignDescriptors(
+ "Segment.proto", schemas, file_default_instances, TableStruct::offsets, factory,
+ file_level_metadata, NULL, NULL);
+}
+
+void protobuf_AssignDescriptorsOnce() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
+void protobuf_RegisterTypes(const ::std::string&) {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
+}
+
+} // namespace
+void TableStruct::InitDefaultsImpl() {
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ ::google::protobuf::internal::InitProtobufDefaults();
+ ::Tango::PMR::Common::protobuf_RGB_2eproto::InitDefaults();
+ _Segment_default_instance_._instance.DefaultConstruct();
+ ::google::protobuf::internal::OnShutdownDestroyMessage(
+ &_Segment_default_instance_);_Segment_default_instance_._instance.get_mutable()->color_ = const_cast< ::Tango::PMR::Common::RGB*>(
+ ::Tango::PMR::Common::RGB::internal_default_instance());
+}
+
+void InitDefaults() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl);
+}
+namespace {
+void AddDescriptorsImpl() {
+ InitDefaults();
+ static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ "\n\rSegment.proto\022\016Tango.PMR.Jobs\032\tRGB.pro"
+ "to\"M\n\007Segment\022\014\n\004Name\030\001 \001(\t\022\016\n\006Length\030\002 "
+ "\001(\005\022$\n\005Color\030\003 \001(\0132\025.Tango.PMR.Common.RG"
+ "BB\032\n\030com.twine.tango.pmr.jobsb\006proto3"
+ };
+ ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+ descriptor, 157);
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+ "Segment.proto", &protobuf_RegisterTypes);
+ ::Tango::PMR::Common::protobuf_RGB_2eproto::AddDescriptors();
+}
+} // anonymous namespace
+
+void AddDescriptors() {
+ static GOOGLE_PROTOBUF_DECLARE_ONCE(once);
+ ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);
+}
+// Force AddDescriptors() to be called at dynamic initialization time.
+struct StaticDescriptorInitializer {
+ StaticDescriptorInitializer() {
+ AddDescriptors();
+ }
+} static_descriptor_initializer;
+
+} // namespace protobuf_Segment_2eproto
+
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Segment::kNameFieldNumber;
+const int Segment::kLengthFieldNumber;
+const int Segment::kColorFieldNumber;
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Segment::Segment()
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+ if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
+ protobuf_Segment_2eproto::InitDefaults();
+ }
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:Tango.PMR.Jobs.Segment)
+}
+Segment::Segment(const Segment& from)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL),
+ _cached_size_(0) {
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ if (from.name().size() > 0) {
+ name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+ }
+ if (from.has_color()) {
+ color_ = new ::Tango::PMR::Common::RGB(*from.color_);
+ } else {
+ color_ = NULL;
+ }
+ length_ = from.length_;
+ // @@protoc_insertion_point(copy_constructor:Tango.PMR.Jobs.Segment)
+}
+
+void Segment::SharedCtor() {
+ name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ ::memset(&color_, 0, static_cast<size_t>(
+ reinterpret_cast<char*>(&length_) -
+ reinterpret_cast<char*>(&color_)) + sizeof(length_));
+ _cached_size_ = 0;
+}
+
+Segment::~Segment() {
+ // @@protoc_insertion_point(destructor:Tango.PMR.Jobs.Segment)
+ SharedDtor();
+}
+
+void Segment::SharedDtor() {
+ name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ if (this != internal_default_instance()) delete color_;
+}
+
+void Segment::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* Segment::descriptor() {
+ protobuf_Segment_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_Segment_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
+}
+
+const Segment& Segment::default_instance() {
+ protobuf_Segment_2eproto::InitDefaults();
+ return *internal_default_instance();
+}
+
+Segment* Segment::New(::google::protobuf::Arena* arena) const {
+ Segment* n = new Segment;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
+}
+
+void Segment::Clear() {
+// @@protoc_insertion_point(message_clear_start:Tango.PMR.Jobs.Segment)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void) cached_has_bits;
+
+ name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ if (GetArenaNoVirtual() == NULL && color_ != NULL) {
+ delete color_;
+ }
+ color_ = NULL;
+ length_ = 0;
+ _internal_metadata_.Clear();
+}
+
+bool Segment::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:Tango.PMR.Jobs.Segment)
+ for (;;) {
+ ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+ tag = p.first;
+ if (!p.second) goto handle_unusual;
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // string Name = 1;
+ case 1: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_name()));
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->name().data(), static_cast<int>(this->name().length()),
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "Tango.PMR.Jobs.Segment.Name"));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ // int32 Length = 2;
+ case 2: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
+
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &length_)));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ // .Tango.PMR.Common.RGB Color = 3;
+ case 3: {
+ if (static_cast< ::google::protobuf::uint8>(tag) ==
+ static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_color()));
+ } else {
+ goto handle_unusual;
+ }
+ break;
+ }
+
+ default: {
+ handle_unusual:
+ if (tag == 0) {
+ goto success;
+ }
+ DO_(::google::protobuf::internal::WireFormat::SkipField(
+ input, tag, _internal_metadata_.mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+success:
+ // @@protoc_insertion_point(parse_success:Tango.PMR.Jobs.Segment)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:Tango.PMR.Jobs.Segment)
+ return false;
+#undef DO_
+}
+
+void Segment::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:Tango.PMR.Jobs.Segment)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // string Name = 1;
+ if (this->name().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->name().data(), static_cast<int>(this->name().length()),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "Tango.PMR.Jobs.Segment.Name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+ 1, this->name(), output);
+ }
+
+ // int32 Length = 2;
+ if (this->length() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->length(), output);
+ }
+
+ // .Tango.PMR.Common.RGB Color = 3;
+ if (this->has_color()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 3, *this->color_, output);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output);
+ }
+ // @@protoc_insertion_point(serialize_end:Tango.PMR.Jobs.Segment)
+}
+
+::google::protobuf::uint8* Segment::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
+ (void)deterministic; // Unused
+ // @@protoc_insertion_point(serialize_to_array_start:Tango.PMR.Jobs.Segment)
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ // string Name = 1;
+ if (this->name().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->name().data(), static_cast<int>(this->name().length()),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "Tango.PMR.Jobs.Segment.Name");
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->name(), target);
+ }
+
+ // int32 Length = 2;
+ if (this->length() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->length(), target);
+ }
+
+ // .Tango.PMR.Common.RGB Color = 3;
+ if (this->has_color()) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ InternalWriteMessageNoVirtualToArray(
+ 3, *this->color_, deterministic, target);
+ }
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:Tango.PMR.Jobs.Segment)
+ return target;
+}
+
+size_t Segment::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:Tango.PMR.Jobs.Segment)
+ size_t total_size = 0;
+
+ if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+ total_size +=
+ ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+ (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()));
+ }
+ // string Name = 1;
+ if (this->name().size() > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name());
+ }
+
+ // .Tango.PMR.Common.RGB Color = 3;
+ if (this->has_color()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ *this->color_);
+ }
+
+ // int32 Length = 2;
+ if (this->length() != 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->length());
+ }
+
+ int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = cached_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void Segment::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:Tango.PMR.Jobs.Segment)
+ GOOGLE_DCHECK_NE(&from, this);
+ const Segment* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const Segment>(
+ &from);
+ if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:Tango.PMR.Jobs.Segment)
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:Tango.PMR.Jobs.Segment)
+ MergeFrom(*source);
+ }
+}
+
+void Segment::MergeFrom(const Segment& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:Tango.PMR.Jobs.Segment)
+ GOOGLE_DCHECK_NE(&from, this);
+ _internal_metadata_.MergeFrom(from._internal_metadata_);
+ ::google::protobuf::uint32 cached_has_bits = 0;
+ (void) cached_has_bits;
+
+ if (from.name().size() > 0) {
+
+ name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+ }
+ if (from.has_color()) {
+ mutable_color()->::Tango::PMR::Common::RGB::MergeFrom(from.color());
+ }
+ if (from.length() != 0) {
+ set_length(from.length());
+ }
+}
+
+void Segment::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:Tango.PMR.Jobs.Segment)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void Segment::CopyFrom(const Segment& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:Tango.PMR.Jobs.Segment)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Segment::IsInitialized() const {
+ return true;
+}
+
+void Segment::Swap(Segment* other) {
+ if (other == this) return;
+ InternalSwap(other);
+}
+void Segment::InternalSwap(Segment* other) {
+ using std::swap;
+ name_.Swap(&other->name_);
+ swap(color_, other->color_);
+ swap(length_, other->length_);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata Segment::GetMetadata() const {
+ protobuf_Segment_2eproto::protobuf_AssignDescriptorsOnce();
+ return protobuf_Segment_2eproto::file_level_metadata[kIndexInFileMessages];
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// Segment
+
+// string Name = 1;
+void Segment::clear_name() {
+ name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+const ::std::string& Segment::name() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Jobs.Segment.Name)
+ return name_.GetNoArena();
+}
+void Segment::set_name(const ::std::string& value) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:Tango.PMR.Jobs.Segment.Name)
+}
+#if LANG_CXX11
+void Segment::set_name(::std::string&& value) {
+
+ name_.SetNoArena(
+ &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+ // @@protoc_insertion_point(field_set_rvalue:Tango.PMR.Jobs.Segment.Name)
+}
+#endif
+void Segment::set_name(const char* value) {
+ GOOGLE_DCHECK(value != NULL);
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:Tango.PMR.Jobs.Segment.Name)
+}
+void Segment::set_name(const char* value, size_t size) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:Tango.PMR.Jobs.Segment.Name)
+}
+::std::string* Segment::mutable_name() {
+
+ // @@protoc_insertion_point(field_mutable:Tango.PMR.Jobs.Segment.Name)
+ return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+::std::string* Segment::release_name() {
+ // @@protoc_insertion_point(field_release:Tango.PMR.Jobs.Segment.Name)
+
+ return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void Segment::set_allocated_name(::std::string* name) {
+ if (name != NULL) {
+
+ } else {
+
+ }
+ name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+ // @@protoc_insertion_point(field_set_allocated:Tango.PMR.Jobs.Segment.Name)
+}
+
+// int32 Length = 2;
+void Segment::clear_length() {
+ length_ = 0;
+}
+::google::protobuf::int32 Segment::length() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Jobs.Segment.Length)
+ return length_;
+}
+void Segment::set_length(::google::protobuf::int32 value) {
+
+ length_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Jobs.Segment.Length)
+}
+
+// .Tango.PMR.Common.RGB Color = 3;
+bool Segment::has_color() const {
+ return this != internal_default_instance() && color_ != NULL;
+}
+void Segment::clear_color() {
+ if (GetArenaNoVirtual() == NULL && color_ != NULL) delete color_;
+ color_ = NULL;
+}
+const ::Tango::PMR::Common::RGB& Segment::color() const {
+ const ::Tango::PMR::Common::RGB* p = color_;
+ // @@protoc_insertion_point(field_get:Tango.PMR.Jobs.Segment.Color)
+ return p != NULL ? *p : *reinterpret_cast<const ::Tango::PMR::Common::RGB*>(
+ &::Tango::PMR::Common::_RGB_default_instance_);
+}
+::Tango::PMR::Common::RGB* Segment::mutable_color() {
+
+ if (color_ == NULL) {
+ color_ = new ::Tango::PMR::Common::RGB;
+ }
+ // @@protoc_insertion_point(field_mutable:Tango.PMR.Jobs.Segment.Color)
+ return color_;
+}
+::Tango::PMR::Common::RGB* Segment::release_color() {
+ // @@protoc_insertion_point(field_release:Tango.PMR.Jobs.Segment.Color)
+
+ ::Tango::PMR::Common::RGB* temp = color_;
+ color_ = NULL;
+ return temp;
+}
+void Segment::set_allocated_color(::Tango::PMR::Common::RGB* color) {
+ delete color_;
+ color_ = color;
+ if (color) {
+
+ } else {
+
+ }
+ // @@protoc_insertion_point(field_set_allocated:Tango.PMR.Jobs.Segment.Color)
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace Jobs
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Segment.pb.h b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Segment.pb.h
new file mode 100644
index 000000000..11de65191
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/PMR/Segment.pb.h
@@ -0,0 +1,318 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: Segment.proto
+
+#ifndef PROTOBUF_Segment_2eproto__INCLUDED
+#define PROTOBUF_Segment_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 3004000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3004000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h> // IWYU pragma: export
+#include <google/protobuf/extension_set.h> // IWYU pragma: export
+#include <google/protobuf/unknown_field_set.h>
+#include "RGB.pb.h"
+// @@protoc_insertion_point(includes)
+namespace Tango {
+namespace PMR {
+namespace Jobs {
+class Segment;
+class SegmentDefaultTypeInternal;
+extern SegmentDefaultTypeInternal _Segment_default_instance_;
+} // namespace Jobs
+} // namespace PMR
+} // namespace Tango
+
+namespace Tango {
+namespace PMR {
+namespace Jobs {
+
+namespace protobuf_Segment_2eproto {
+// Internal implementation detail -- do not call these.
+struct TableStruct {
+ static const ::google::protobuf::internal::ParseTableField entries[];
+ static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
+ static const ::google::protobuf::internal::ParseTable schema[];
+ static const ::google::protobuf::uint32 offsets[];
+ static const ::google::protobuf::internal::FieldMetadata field_metadata[];
+ static const ::google::protobuf::internal::SerializationTable serialization_table[];
+ static void InitDefaultsImpl();
+};
+void AddDescriptors();
+void InitDefaults();
+} // namespace protobuf_Segment_2eproto
+
+// ===================================================================
+
+class Segment : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:Tango.PMR.Jobs.Segment) */ {
+ public:
+ Segment();
+ virtual ~Segment();
+
+ Segment(const Segment& from);
+
+ inline Segment& operator=(const Segment& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ #if LANG_CXX11
+ Segment(Segment&& from) noexcept
+ : Segment() {
+ *this = ::std::move(from);
+ }
+
+ inline Segment& operator=(Segment&& from) noexcept {
+ if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+ if (this != &from) InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+ #endif
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const Segment& default_instance();
+
+ static inline const Segment* internal_default_instance() {
+ return reinterpret_cast<const Segment*>(
+ &_Segment_default_instance_);
+ }
+ static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
+ 0;
+
+ void Swap(Segment* other);
+ friend void swap(Segment& a, Segment& b) {
+ a.Swap(&b);
+ }
+
+ // implements Message ----------------------------------------------
+
+ inline Segment* New() const PROTOBUF_FINAL { return New(NULL); }
+
+ Segment* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+ void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+ void CopyFrom(const Segment& from);
+ void MergeFrom(const Segment& from);
+ void Clear() PROTOBUF_FINAL;
+ bool IsInitialized() const PROTOBUF_FINAL;
+
+ size_t ByteSizeLong() const PROTOBUF_FINAL;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
+ int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const PROTOBUF_FINAL;
+ void InternalSwap(Segment* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return NULL;
+ }
+ inline void* MaybeArenaPtr() const {
+ return NULL;
+ }
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // string Name = 1;
+ void clear_name();
+ static const int kNameFieldNumber = 1;
+ const ::std::string& name() const;
+ void set_name(const ::std::string& value);
+ #if LANG_CXX11
+ void set_name(::std::string&& value);
+ #endif
+ void set_name(const char* value);
+ void set_name(const char* value, size_t size);
+ ::std::string* mutable_name();
+ ::std::string* release_name();
+ void set_allocated_name(::std::string* name);
+
+ // .Tango.PMR.Common.RGB Color = 3;
+ bool has_color() const;
+ void clear_color();
+ static const int kColorFieldNumber = 3;
+ const ::Tango::PMR::Common::RGB& color() const;
+ ::Tango::PMR::Common::RGB* mutable_color();
+ ::Tango::PMR::Common::RGB* release_color();
+ void set_allocated_color(::Tango::PMR::Common::RGB* color);
+
+ // int32 Length = 2;
+ void clear_length();
+ static const int kLengthFieldNumber = 2;
+ ::google::protobuf::int32 length() const;
+ void set_length(::google::protobuf::int32 value);
+
+ // @@protoc_insertion_point(class_scope:Tango.PMR.Jobs.Segment)
+ private:
+
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ ::google::protobuf::internal::ArenaStringPtr name_;
+ ::Tango::PMR::Common::RGB* color_;
+ ::google::protobuf::int32 length_;
+ mutable int _cached_size_;
+ friend struct protobuf_Segment_2eproto::TableStruct;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
+#ifdef __GNUC__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// Segment
+
+// string Name = 1;
+inline void Segment::clear_name() {
+ name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Segment::name() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Jobs.Segment.Name)
+ return name_.GetNoArena();
+}
+inline void Segment::set_name(const ::std::string& value) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:Tango.PMR.Jobs.Segment.Name)
+}
+#if LANG_CXX11
+inline void Segment::set_name(::std::string&& value) {
+
+ name_.SetNoArena(
+ &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+ // @@protoc_insertion_point(field_set_rvalue:Tango.PMR.Jobs.Segment.Name)
+}
+#endif
+inline void Segment::set_name(const char* value) {
+ GOOGLE_DCHECK(value != NULL);
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:Tango.PMR.Jobs.Segment.Name)
+}
+inline void Segment::set_name(const char* value, size_t size) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:Tango.PMR.Jobs.Segment.Name)
+}
+inline ::std::string* Segment::mutable_name() {
+
+ // @@protoc_insertion_point(field_mutable:Tango.PMR.Jobs.Segment.Name)
+ return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Segment::release_name() {
+ // @@protoc_insertion_point(field_release:Tango.PMR.Jobs.Segment.Name)
+
+ return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Segment::set_allocated_name(::std::string* name) {
+ if (name != NULL) {
+
+ } else {
+
+ }
+ name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+ // @@protoc_insertion_point(field_set_allocated:Tango.PMR.Jobs.Segment.Name)
+}
+
+// int32 Length = 2;
+inline void Segment::clear_length() {
+ length_ = 0;
+}
+inline ::google::protobuf::int32 Segment::length() const {
+ // @@protoc_insertion_point(field_get:Tango.PMR.Jobs.Segment.Length)
+ return length_;
+}
+inline void Segment::set_length(::google::protobuf::int32 value) {
+
+ length_ = value;
+ // @@protoc_insertion_point(field_set:Tango.PMR.Jobs.Segment.Length)
+}
+
+// .Tango.PMR.Common.RGB Color = 3;
+inline bool Segment::has_color() const {
+ return this != internal_default_instance() && color_ != NULL;
+}
+inline void Segment::clear_color() {
+ if (GetArenaNoVirtual() == NULL && color_ != NULL) delete color_;
+ color_ = NULL;
+}
+inline const ::Tango::PMR::Common::RGB& Segment::color() const {
+ const ::Tango::PMR::Common::RGB* p = color_;
+ // @@protoc_insertion_point(field_get:Tango.PMR.Jobs.Segment.Color)
+ return p != NULL ? *p : *reinterpret_cast<const ::Tango::PMR::Common::RGB*>(
+ &::Tango::PMR::Common::_RGB_default_instance_);
+}
+inline ::Tango::PMR::Common::RGB* Segment::mutable_color() {
+
+ if (color_ == NULL) {
+ color_ = new ::Tango::PMR::Common::RGB;
+ }
+ // @@protoc_insertion_point(field_mutable:Tango.PMR.Jobs.Segment.Color)
+ return color_;
+}
+inline ::Tango::PMR::Common::RGB* Segment::release_color() {
+ // @@protoc_insertion_point(field_release:Tango.PMR.Jobs.Segment.Color)
+
+ ::Tango::PMR::Common::RGB* temp = color_;
+ color_ = NULL;
+ return temp;
+}
+inline void Segment::set_allocated_color(::Tango::PMR::Common::RGB* color) {
+ delete color_;
+ color_ = color;
+ if (color) {
+
+ } else {
+
+ }
+ // @@protoc_insertion_point(field_set_allocated:Tango.PMR.Jobs.Segment.Color)
+}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif // __GNUC__
+#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+
+} // namespace Jobs
+} // namespace PMR
+} // namespace Tango
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_Segment_2eproto__INCLUDED
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/ProtoTester.cpp b/Software/Visual_Studio/Native/Tango.ProtoTest/ProtoTester.cpp
new file mode 100644
index 000000000..08faf6155
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/ProtoTester.cpp
@@ -0,0 +1,18 @@
+#include "ProtoTester.h"
+
+
+namespace Tango
+{
+ namespace ProtoTest
+ {
+ ProtoTester::ProtoTester()
+ {
+
+ }
+
+ ProtoTester::~ProtoTester()
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/ProtoTester.h b/Software/Visual_Studio/Native/Tango.ProtoTest/ProtoTester.h
new file mode 100644
index 000000000..7bb7ee4d2
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/ProtoTester.h
@@ -0,0 +1,42 @@
+#include <cstdlib>
+#include "PMR/CalculateRequest.pb.h"
+#include "PMR/CalculateResponse.pb.h"
+
+#pragma once
+
+#define EXPORT_API __declspec(dllexport)
+
+using namespace std;
+using namespace Tango::PMR::Stubs;
+
+namespace Tango
+{
+ namespace ProtoTest
+ {
+
+ class ProtoTester
+ {
+ public:
+ ProtoTester();
+ ~ProtoTester();
+
+ };
+ }
+}
+
+extern "C" EXPORT_API int __cdecl Calculate(unsigned char* data, int size, unsigned char* *output)
+{
+ CalculateRequest request;
+ request.ParseFromArray(data, size);
+
+ CalculateResponse* response = new CalculateResponse();
+ response->set_sum(request.a() + request.b());
+
+
+ unsigned char* stream = (unsigned char*)malloc(response->ByteSize());
+ response->SerializeToArray(stream, response->ByteSize());
+ *output = stream;
+
+ return response->ByteSize();
+}
+
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/Tango.ProtoTest.vcxproj b/Software/Visual_Studio/Native/Tango.ProtoTest/Tango.ProtoTest.vcxproj
new file mode 100644
index 000000000..4959792e2
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/Tango.ProtoTest.vcxproj
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>15.0</VCProjectVersion>
+ <ProjectGuid>{35397DDA-DDC7-46BE-A802-3B722B6858E9}</ProjectGuid>
+ <RootNamespace>TangoProtoTest</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetExt>.dll</TargetExt>
+ <OutDir>$(SolutionDir)Build\Debug</OutDir>
+ <IncludePath>..\..\..\External Repositories\Protobuf\protobuf-3.4.1\src;$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <PreBuildEvent>
+ <Command>"$(TargetDir)proto-tc.exe" -i "$(SolutionDir)..\PMR\Messages" -o "$(SolutionDir)Native\Tango.ProtoTest\PMR" -l CPP</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="PMR\CalculateRequest.pb.h" />
+ <ClInclude Include="PMR\CalculateResponse.pb.h" />
+ <ClInclude Include="PMR\Job.pb.h" />
+ <ClInclude Include="PMR\MessageContainer.pb.h" />
+ <ClInclude Include="PMR\MessageType.pb.h" />
+ <ClInclude Include="PMR\ProgressRequest.pb.h" />
+ <ClInclude Include="PMR\ProgressResponse.pb.h" />
+ <ClInclude Include="PMR\RGB.pb.h" />
+ <ClInclude Include="PMR\Segment.pb.h" />
+ <ClInclude Include="ProtoTester.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="PMR\CalculateRequest.pb.cc" />
+ <ClCompile Include="PMR\CalculateResponse.pb.cc" />
+ <ClCompile Include="PMR\Job.pb.cc" />
+ <ClCompile Include="PMR\MessageContainer.pb.cc" />
+ <ClCompile Include="PMR\MessageType.pb.cc" />
+ <ClCompile Include="PMR\ProgressRequest.pb.cc" />
+ <ClCompile Include="PMR\ProgressResponse.pb.cc" />
+ <ClCompile Include="PMR\RGB.pb.cc" />
+ <ClCompile Include="PMR\Segment.pb.cc" />
+ <ClCompile Include="ProtoTester.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Library Include="libprotobuf.lib" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/Tango.ProtoTest.vcxproj.filters b/Software/Visual_Studio/Native/Tango.ProtoTest/Tango.ProtoTest.vcxproj.filters
new file mode 100644
index 000000000..0b835c2c4
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/Tango.ProtoTest.vcxproj.filters
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="ProtoTester.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="PMR\CalculateRequest.pb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="PMR\CalculateResponse.pb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="PMR\Job.pb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="PMR\MessageContainer.pb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="PMR\MessageType.pb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="PMR\ProgressRequest.pb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="PMR\ProgressResponse.pb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="PMR\RGB.pb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="PMR\Segment.pb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="ProtoTester.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="PMR\CalculateRequest.pb.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="PMR\CalculateResponse.pb.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="PMR\Job.pb.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="PMR\MessageContainer.pb.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="PMR\MessageType.pb.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="PMR\ProgressRequest.pb.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="PMR\ProgressResponse.pb.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="PMR\RGB.pb.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="PMR\Segment.pb.cc">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Library Include="libprotobuf.lib" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Native/Tango.ProtoTest/libprotobuf.lib b/Software/Visual_Studio/Native/Tango.ProtoTest/libprotobuf.lib
new file mode 100644
index 000000000..cbe32c777
--- /dev/null
+++ b/Software/Visual_Studio/Native/Tango.ProtoTest/libprotobuf.lib
Binary files differ
diff --git a/Software/Visual_Studio/Resources/dummyFile.txt b/Software/Visual_Studio/Resources/dummyFile.txt
new file mode 100644
index 000000000..af5dee191
--- /dev/null
+++ b/Software/Visual_Studio/Resources/dummyFile.txt
@@ -0,0 +1 @@
+I'm dumb! \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs
new file mode 100644
index 000000000..16fd43728
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/DependencyObjectExtensions.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+/// <exclude/>
+/// <summary>
+/// Contains a collection of DependencyObject extension methods.
+/// </summary>
+public static class DependencyObjectExtensions
+{
+ /// <summary>
+ /// Invokes the current dependency object dispatcher.
+ /// </summary>
+ /// <param name="dependencyObject">The dependency object.</param>
+ /// <param name="action">The action.</param>
+ public static void BeginInvoke(this DependencyObject dependencyObject, Action action)
+ {
+ dependencyObject.Dispatcher.BeginInvoke(action);
+ }
+
+ /// <summary>
+ /// Invokes the specified action.
+ /// </summary>
+ /// <param name="dependencyObject">The dependency object.</param>
+ /// <param name="action">The action.</param>
+ public static void Invoke(this DependencyObject dependencyObject, Action action)
+ {
+ dependencyObject.Dispatcher.Invoke(action);
+ }
+
+ /// <summary>
+ /// Determines whether this object is currently in design time mode.
+ /// </summary>
+ /// <param name="obj">The object.</param>
+ /// <returns></returns>
+ public static bool IsInDesignMode(this DependencyObject obj)
+ {
+ return (DesignerProperties.GetIsInDesignMode(obj));
+ }
+
+
+ /// <summary>
+ /// Binds the specified dependency property to a another object property.
+ /// </summary>
+ /// <param name="target">The target dependency object.</param>
+ /// <param name="targetDP">The target dependency property.</param>
+ /// <param name="source">The source object.</param>
+ /// <param name="sourceDP">The source dependency property.</param>
+ /// <param name="mode">Binding mode.</param>
+ /// <param name="converter">Binding converter.</param>
+ /// <returns></returns>
+ public static Binding Bind(this DependencyObject target, DependencyProperty targetDP, DependencyObject source, DependencyProperty sourceDP, BindingMode mode, IValueConverter converter = null)
+ {
+ Binding binding = new Binding();
+ binding.Mode = mode;
+ binding.Source = source;
+ binding.Path = new PropertyPath(sourceDP);
+ binding.Converter = converter;
+ BindingOperations.SetBinding(target, targetDP, binding);
+ return binding;
+ }
+
+ /// <summary>
+ /// Binds the specified dependency property to a another object property.
+ /// </summary>
+ /// <param name="target">The target dependency object.</param>
+ /// <param name="targetDP">The target dependency property.</param>
+ /// <param name="source">The source object.</param>
+ /// <param name="sourceDP">The source dependency property.</param>
+ /// <param name="mode">Binding mode.</param>
+ /// <returns></returns>
+ public static Binding Bind(this DependencyObject target, DependencyProperty targetDP, DependencyObject source, DependencyProperty sourceDP, BindingMode mode = BindingMode.Default)
+ {
+ Binding binding = new Binding();
+ binding.Mode = mode;
+ binding.Source = source;
+ binding.Path = new PropertyPath(sourceDP);
+ BindingOperations.SetBinding(target, targetDP, binding);
+ return binding;
+ }
+
+ /// <summary>
+ /// Create asynchronous binding between target and source.
+ /// </summary>
+ /// <param name="target">The target dependency object.</param>
+ /// <param name="targetDP">The target dependency property.</param>
+ /// <param name="source">The source object.</param>
+ /// <param name="sourceDP">The source dependency property.</param>
+ /// <param name="mode">Binding mode.</param>
+ /// <returns></returns>
+ public static Binding BindAsync(this DependencyObject target, DependencyProperty targetDP, DependencyObject source, DependencyProperty sourceDP, BindingMode mode = BindingMode.Default)
+ {
+ Binding binding = new Binding();
+ binding.Mode = mode;
+ binding.Source = source;
+ binding.Path = new PropertyPath(sourceDP);
+ binding.IsAsync = true;
+ binding.BindsDirectlyToSource = true;
+ BindingOperations.SetBinding(target, targetDP, binding);
+ return binding;
+ }
+
+ /// <summary>
+ /// Binds the specified dependency property to a another object property.
+ /// </summary>
+ /// <param name="target">The target dependency object.</param>
+ /// <param name="targetDP">The target dependency property.</param>
+ /// <param name="source">The source object.</param>
+ /// <param name="sourceDP">The source dependency property name.</param>
+ /// <param name="mode">Binding mode.</param>
+ /// <returns></returns>
+ public static Binding Bind(this DependencyObject target, DependencyProperty targetDP, DependencyObject source, String sourceDP, BindingMode mode = BindingMode.Default)
+ {
+ Binding binding = new Binding();
+ binding.Mode = mode;
+ binding.Source = source;
+ binding.Path = new PropertyPath(sourceDP);
+ BindingOperations.SetBinding(target, targetDP, binding);
+ return binding;
+ }
+
+ /// <summary>
+ /// Clears bindings from the specified dependency property.
+ /// </summary>
+ /// <param name="target">The target dependency object.</param>
+ /// <param name="dependencyProperty">The dependency property.</param>
+ public static void Unbind(this DependencyObject target, DependencyProperty dependencyProperty)
+ {
+ BindingOperations.ClearBinding(target, dependencyProperty);
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/EnumExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/EnumExtensions.cs
new file mode 100644
index 000000000..106dd4f44
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/EnumExtensions.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+public static class EnumExtensions
+{
+ /// <summary>
+ /// Gets the Enum value description.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ /// <returns></returns>
+ public static String ToDescription(this Enum value)
+ {
+ FieldInfo fi = value.GetType().GetField(value.ToString());
+
+ DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
+
+ if (attributes != null &&
+ attributes.Length > 0)
+ return attributes[0].Description;
+ else
+ return value.ToString();
+ }
+
+ public static int ToInt32(this Enum value)
+ {
+ return (int)((object)value);
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/IMessageExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/IMessageExtensions.cs
new file mode 100644
index 000000000..53522780a
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/IMessageExtensions.cs
@@ -0,0 +1,25 @@
+using Google.Protobuf;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+public static class IMessageExtensions
+{
+ /// <summary>
+ /// Serializes this PMR message to byte array.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="message">The message.</param>
+ /// <returns></returns>
+ public static byte[] ToBytes<T>(this T message) where T : IMessage<T>
+ {
+ using (MemoryStream ms = new MemoryStream())
+ {
+ message.WriteTo(ms);
+ return ms.ToArray();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/IParameterizedExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/IParameterizedExtensions.cs
new file mode 100644
index 000000000..5ee853f35
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/IParameterizedExtensions.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.Core;
+
+/// <summary>
+/// Contains extension methods for <see cref="IParameterized"/>.
+/// </summary>
+public static class IParameterizedExtensions
+{
+ /// <summary>
+ /// Creates an observable collection of the parameterized object.
+ /// </summary>
+ /// <param name="instance">The instance.</param>
+ /// <param name="mode">The parameters update mode.</param>
+ /// <returns></returns>
+ public static ObservableCollection<ParameterItem> CreateParametersCollection(this IParameterized instance, ParameterItemMode mode)
+ {
+ var ps = new ObservableCollection<ParameterItem>();
+
+ int index = 0;
+
+ List<Type> types = new List<Type>();
+ Type currentType = instance.GetType();
+
+ while (true)
+ {
+ if (typeof(IParameterized).IsAssignableFrom(currentType) && currentType != typeof(IParameterized))
+ {
+ types.Add(currentType);
+ currentType = currentType.BaseType;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ List<PropertyInfo> properties = new List<PropertyInfo>();
+
+ foreach (var type in types)
+ {
+ foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
+ {
+ var paramAtt = prop.GetCustomAttributes(typeof(ParameterItemAttribute), false).Cast<ParameterItemAttribute>().FirstOrDefault();
+ var ignore = prop.GetCustomAttributes(typeof(ParameterIgnoreAttribute), false).Cast<ParameterIgnoreAttribute>().FirstOrDefault();
+
+ if (ignore == null && !properties.Exists(x => x.Name == prop.Name))
+ {
+ var item = instance.CreateParameterItem(prop, paramAtt, index++, mode);
+ ps.Add(item);
+ properties.Add(prop);
+ }
+ }
+ }
+
+ return ps;
+ }
+
+ /// <summary>
+ /// Creates the parameter item.
+ /// </summary>
+ /// <param name="instance">The instance.</param>
+ /// <param name="propertyInfo">The property information.</param>
+ /// <param name="attribute">The attribute.</param>
+ /// <param name="index">The index.</param>
+ /// <param name="mode">The mode.</param>
+ /// <returns></returns>
+ public static ParameterItem CreateParameterItem(this IParameterized instance, PropertyInfo propertyInfo, ParameterItemAttribute attribute, int index, ParameterItemMode mode)
+ {
+ ParameterItem item = new ParameterItem();
+ item.Name = propertyInfo.Name.ToTitle();
+ item.Index = index;
+ item.Type = propertyInfo.PropertyType;
+ item.Value = propertyInfo.GetValue(instance, null);
+
+ if (attribute != null)
+ {
+ item.Minimum = attribute.Minimum;
+ item.Maximum = attribute.Maximum;
+ item.CustomEditorTypeName = attribute.CustomEditorTypeName;
+ item.ExtraObject = attribute.ExtraObject;
+
+ if (attribute.Name != null)
+ {
+ item.Name = attribute.Name;
+ }
+ }
+
+ if (mode == ParameterItemMode.Event)
+ {
+ item.ParameterValueChanged += (sender, e) =>
+ {
+ propertyInfo.SetValue(instance, e.Value);
+ };
+ }
+ else if (mode == ParameterItemMode.Binding)
+ {
+ item.Bind(ParameterItem.ValueProperty, instance as DependencyObject, propertyInfo.Name, System.Windows.Data.BindingMode.TwoWay);
+ }
+
+ return item;
+ }
+
+ /// <summary>
+ /// Creates the parameter item.
+ /// </summary>
+ /// <param name="instance">The instance.</param>
+ /// <param name="propertyName">Name of the property.</param>
+ /// <param name="attribute">The attribute.</param>
+ /// <param name="index">The index.</param>
+ /// <param name="mode">The mode.</param>
+ /// <returns></returns>
+ public static ParameterItem CreateParameterItem(this IParameterized instance, String propertyName, ParameterItemAttribute attribute, int index, ParameterItemMode mode)
+ {
+ return instance.CreateParameterItem(instance.GetType().GetProperty(propertyName), attribute, index, mode);
+ }
+}
+
diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/StringExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/StringExtensions.cs
new file mode 100644
index 000000000..5699d27a0
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/StringExtensions.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+public static class StringExtensions
+{
+ private static Regex titleRegEx;
+
+ /// <summary>
+ /// Initializes the <see cref="StringExtensions"/> class.
+ /// </summary>
+ static StringExtensions()
+ {
+ titleRegEx = new Regex(@"
+ (?<=[A-Z])(?=[A-Z][a-z]) |
+ (?<=[^A-Z])(?=[A-Z]) |
+ (?<=[A-Za-z])(?=[^A-Za-z])", RegexOptions.IgnorePatternWhitespace);
+ }
+
+ /// <summary>
+ /// Normal ToString conversion with null checking.
+ /// </summary>
+ /// <param name="obj">The object.</param>
+ /// <returns></returns>
+ public static String ToStringSafe(this object obj)
+ {
+ return obj != null ? obj.ToString() : String.Empty;
+ }
+
+ /// <summary>
+ /// Splits the string to lines.
+ /// </summary>
+ /// <param name="str">The string.</param>
+ /// <returns></returns>
+ public static List<String> ToLines(this String str)
+ {
+ return str.Split(new[] { '\r', '\n' }).ToList();
+ }
+
+ /// <summary>
+ /// Formats the string to title style.
+ /// </summary>
+ /// <param name="str">The string.</param>
+ /// <returns></returns>
+ public static String ToTitle(this String str)
+ {
+ return titleRegEx.Replace(str, " ");
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Core/Helpers/AssemblyHelper.cs b/Software/Visual_Studio/Tango.Core/Helpers/AssemblyHelper.cs
new file mode 100644
index 000000000..405020e66
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/Helpers/AssemblyHelper.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Core.Helpers
+{
+ public static class AssemblyHelper
+ {
+ public static String GetCurrentAssemblyFolder()
+ {
+ string codeBase = Assembly.GetExecutingAssembly().CodeBase;
+ UriBuilder uri = new UriBuilder(codeBase);
+ string path = Uri.UnescapeDataString(uri.Path);
+ return Path.GetDirectoryName(path);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs b/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs
new file mode 100644
index 000000000..fa52eb42b
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Core.Helpers
+{
+ public static class PathHelper
+ {
+ public static String GetTempFolderPath()
+ {
+ String tempDirectory = Path.Combine(Path.GetTempPath(), "Twine", Path.GetRandomFileName());
+ Directory.CreateDirectory(tempDirectory);
+ return tempDirectory;
+ }
+
+ public static bool TryDeleteFolder(String path)
+ {
+ try
+ {
+ Directory.Delete(path, true);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Core/IParameterized.cs b/Software/Visual_Studio/Tango.Core/IParameterized.cs
new file mode 100644
index 000000000..e6f36b4c6
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/IParameterized.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Core
+{
+ /// <summary>
+ /// Represents a component that exposes some of it's properties as an observable collection of <see cref="ParameterItem"/> which can be bound to UI controls.
+ /// </summary>
+ public interface IParameterized
+ {
+ /// <summary>
+ /// Gets a bind-able observable collection of the component properties.
+ /// </summary>
+ [ParameterIgnore]
+ ReadOnlyObservableCollection<ParameterItem> Parameters { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Core/ParameterIgnoreAttribute.cs b/Software/Visual_Studio/Tango.Core/ParameterIgnoreAttribute.cs
new file mode 100644
index 000000000..0bbca6a06
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/ParameterIgnoreAttribute.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Core
+{
+ /// <summary>
+ /// Represents an attribute for specifying properties to ignore as parameters.
+ /// </summary>
+ /// <seealso cref="System.Attribute" />
+ public class ParameterIgnoreAttribute : Attribute
+ {
+
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Core/ParameterItem.cs b/Software/Visual_Studio/Tango.Core/ParameterItem.cs
new file mode 100644
index 000000000..53a3df269
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/ParameterItem.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace Tango.Core
+{
+ /// <summary>
+ /// Represents a component parameter name and value which can be bound to UI elements.
+ /// </summary>
+ /// <seealso cref="System.Windows.DependencyObject" />
+ public class ParameterItem : DependencyObject
+ {
+ internal bool disableParamEvent;
+
+ /// <summary>
+ /// Occurs when the parameter value has changed.
+ /// </summary>
+ public event EventHandler<ParameterItem> ParameterValueChanged;
+
+ /// <summary>
+ /// Gets or sets the parameter index.
+ /// </summary>
+ public int Index
+ {
+ get { return (int)GetValue(IndexProperty); }
+ set { SetValue(IndexProperty, value); }
+ }
+ public static readonly DependencyProperty IndexProperty =
+ DependencyProperty.Register("Index", typeof(int), typeof(ParameterItem), new PropertyMetadata(0));
+
+ /// <summary>
+ /// Gets or sets the parameter value type.
+ /// </summary>
+ public Type Type
+ {
+ get { return (Type)GetValue(TypeProperty); }
+ set { SetValue(TypeProperty, value); }
+ }
+ public static readonly DependencyProperty TypeProperty =
+ DependencyProperty.Register("Type", typeof(Type), typeof(ParameterItem), new PropertyMetadata(typeof(double)));
+
+
+ /// <summary>
+ /// Gets or sets the parameter name.
+ /// </summary>
+ public String Name
+ {
+ get { return (String)GetValue(NameProperty); }
+ set { SetValue(NameProperty, value); }
+ }
+ public static readonly DependencyProperty NameProperty =
+ DependencyProperty.Register("Name", typeof(String), typeof(ParameterItem), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the current parameter value.
+ /// </summary>
+ public object Value
+ {
+ get { return (object)GetValue(ValueProperty); }
+ set { SetValue(ValueProperty, value); }
+ }
+ public static readonly DependencyProperty ValueProperty =
+ DependencyProperty.Register("Value", typeof(object), typeof(ParameterItem), new PropertyMetadata(null, new PropertyChangedCallback(OnValueChanged)));
+
+
+ /// <summary>
+ /// Gets or sets the minimum parameter value.
+ /// </summary>
+ public object Minimum
+ {
+ get { return (object)GetValue(MinimumProperty); }
+ set { SetValue(MinimumProperty, value); }
+ }
+ public static readonly DependencyProperty MinimumProperty =
+ DependencyProperty.Register("Minimum", typeof(object), typeof(ParameterItem), new PropertyMetadata(0.0d));
+
+
+ /// <summary>
+ /// Gets or sets the maximum parameter value.
+ /// </summary>
+ public object Maximum
+ {
+ get { return (object)GetValue(MaximumProperty); }
+ set { SetValue(MaximumProperty, value); }
+ }
+ public static readonly DependencyProperty MaximumProperty =
+ DependencyProperty.Register("Maximum", typeof(object), typeof(ParameterItem), new PropertyMetadata(1.0d));
+
+
+ /// <summary>
+ /// Gets or sets an optional extra object.
+ /// </summary>
+ public object ExtraObject
+ {
+ get { return (object)GetValue(ExtraObjectProperty); }
+ set { SetValue(ExtraObjectProperty, value); }
+ }
+ public static readonly DependencyProperty ExtraObjectProperty =
+ DependencyProperty.Register("ExtraObject", typeof(object), typeof(ParameterItem), new PropertyMetadata(null));
+
+
+ /// <summary>
+ /// Gets or sets an optional custom editor.
+ /// </summary>
+ public String CustomEditorTypeName
+ {
+ get { return (String)GetValue(CustomEditorTypeNameProperty); }
+ set { SetValue(CustomEditorTypeNameProperty, value); }
+ }
+ public static readonly DependencyProperty CustomEditorTypeNameProperty =
+ DependencyProperty.Register("CustomEditorType", typeof(String), typeof(ParameterItem), new PropertyMetadata(null));
+
+
+ /// <summary>
+ /// Gets a value indicating whether this instance requires custom editor.
+ /// </summary>
+ public bool HasCustomEditor
+ {
+ get { return CustomEditorTypeName != null; }
+ }
+
+ /// <summary>
+ /// Called when value has changed.
+ /// </summary>
+ /// <param name="d">The d.</param>
+ /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
+ private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ (d as ParameterItem).OnParameterChanged();
+ }
+
+ /// <summary>
+ /// Called when the parameter value has changed.
+ /// </summary>
+ protected virtual void OnParameterChanged()
+ {
+ if (!disableParamEvent)
+ {
+ if (ParameterValueChanged != null) ParameterValueChanged(this, this);
+ }
+ }
+
+ /// <summary>
+ /// Returns a <see cref="System.String" /> that represents this instance.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="System.String" /> that represents this instance.
+ /// </returns>
+ public override string ToString()
+ {
+ return Name;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Core/ParameterItemAttribute.cs b/Software/Visual_Studio/Tango.Core/ParameterItemAttribute.cs
new file mode 100644
index 000000000..68405fe64
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/ParameterItemAttribute.cs
@@ -0,0 +1,140 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Core
+{
+ /// <summary>
+ /// Represents a parameter item attribute for used for default, min and max values definition of properties.
+ /// </summary>
+ /// <seealso cref="System.Attribute" />
+ public class ParameterItemAttribute : Attribute
+ {
+ /// <summary>
+ /// Gets or sets the custom parameter name.
+ /// </summary>
+ public String Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets the default value.
+ /// </summary>
+ public object Default { get; set; }
+
+ /// <summary>
+ /// Gets or sets the minimum value.
+ /// </summary>
+ public object Minimum { get; set; }
+
+ /// <summary>
+ /// Gets or sets the maximum value.
+ /// </summary>
+ public object Maximum { get; set; }
+
+ /// <summary>
+ /// Gets or sets an optional extra object.
+ /// </summary>
+ public object ExtraObject { get; set; }
+
+ /// <summary>
+ /// Gets or sets an optional custom editor type name.
+ /// </summary>
+ public String CustomEditorTypeName { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ public ParameterItemAttribute()
+ {
+ Default = null;
+ Minimum = 0.0d;
+ Maximum = 1.0d;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="minimumValue">The minimum value.</param>
+ /// <param name="maximumValue">The maximum value.</param>
+ /// <param name="defaultValue">The default value.</param>
+ public ParameterItemAttribute(String name, object minimumValue, object maximumValue, object defaultValue) : this()
+ {
+ Name = name;
+ Default = defaultValue;
+ Minimum = minimumValue;
+ Maximum = maximumValue;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="minimumValue">The minimum value.</param>
+ /// <param name="maximumValue">The maximum value.</param>
+ public ParameterItemAttribute(String name, object minimumValue, double maximumValue) : this(name, minimumValue, maximumValue, null)
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ /// <param name="minimumValue">The minimum value.</param>
+ /// <param name="maximumValue">The maximum value.</param>
+ public ParameterItemAttribute(object minimumValue, object maximumValue) : this()
+ {
+ Minimum = minimumValue;
+ Maximum = maximumValue;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ /// <param name="customParameterEditorTypeName">Type of the custom parameter editor type name.</param>
+ public ParameterItemAttribute(String customParameterEditorTypeName) : this()
+ {
+ CustomEditorTypeName = customParameterEditorTypeName;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="customParameterEditorTypeName">Name of the custom parameter editor type.</param>
+ /// <param name="minimumValue">The minimum value.</param>
+ /// <param name="maximumValue">The maximum value.</param>
+ /// <param name="defaultValue">The default value.</param>
+ /// <param name="extraObject">The extra object.</param>
+ public ParameterItemAttribute(String name, String customParameterEditorTypeName, object minimumValue, object maximumValue, object defaultValue, object extraObject) : this()
+ {
+ Name = name;
+ Minimum = minimumValue;
+ Maximum = maximumValue;
+ Default = defaultValue;
+ CustomEditorTypeName = customParameterEditorTypeName;
+ ExtraObject = extraObject;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemAttribute"/> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="customParameterEditorTypeName">Custom parameter editor type.</param>
+ /// <param name="minimumValue">The minimum value.</param>
+ /// <param name="maximumValue">The maximum value.</param>
+ /// <param name="defaultValue">The default value.</param>
+ /// <param name="extraObject">The extra object.</param>
+ public ParameterItemAttribute(String name, Type customParameterEditorType, object minimumValue, object maximumValue, object defaultValue, object extraObject)
+ : this()
+ {
+ Name = name;
+ Minimum = minimumValue;
+ Maximum = maximumValue;
+ Default = defaultValue;
+ CustomEditorTypeName = customParameterEditorType.AssemblyQualifiedName;
+ ExtraObject = extraObject;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Core/ParameterItemMode.cs b/Software/Visual_Studio/Tango.Core/ParameterItemMode.cs
new file mode 100644
index 000000000..71cb0f139
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/ParameterItemMode.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Core
+{
+ /// <summary>
+ /// Represents a <see cref="ParameterItem"/> update mode.
+ /// </summary>
+ public enum ParameterItemMode
+ {
+ /// <summary>
+ /// Update by binding.
+ /// </summary>
+ Binding,
+ /// <summary>
+ /// Update by event.
+ /// </summary>
+ Event
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Core/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.Core/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..577126b91
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Core Components")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Core/Tango.Core.csproj b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj
new file mode 100644
index 000000000..4954868d3
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj
@@ -0,0 +1,72 @@
+<?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>{A34EE0F0-649D-41C8-8489-B6F1CC6924EE}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tango.Core</RootNamespace>
+ <AssemblyName>Tango.Core</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="PresentationCore" />
+ <Reference Include="PresentationFramework" />
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Windows" />
+ <Reference Include="System.Xaml" />
+ <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="ExtensionMethods\DependencyObjectExtensions.cs" />
+ <Compile Include="ExtensionMethods\EnumExtensions.cs" />
+ <Compile Include="ExtensionMethods\IMessageExtensions.cs" />
+ <Compile Include="ExtensionMethods\IParameterizedExtensions.cs" />
+ <Compile Include="ExtensionMethods\StringExtensions.cs" />
+ <Compile Include="Helpers\AssemblyHelper.cs" />
+ <Compile Include="Helpers\PathHelper.cs" />
+ <Compile Include="IParameterized.cs" />
+ <Compile Include="ParameterIgnoreAttribute.cs" />
+ <Compile Include="ParameterItem.cs" />
+ <Compile Include="ParameterItemAttribute.cs" />
+ <Compile Include="ParameterItemMode.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Core/packages.config b/Software/Visual_Studio/Tango.Core/packages.config
new file mode 100644
index 000000000..e7e6cbade
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Core/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.Protobuf" version="3.4.1" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Emulations/EmulatorBase.cs b/Software/Visual_Studio/Tango.Emulations/EmulatorBase.cs
new file mode 100644
index 000000000..7309499ba
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Emulations/EmulatorBase.cs
@@ -0,0 +1,172 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Logging;
+using Tango.PMR.Common;
+using Tango.SharedUI;
+using Tango.SharedUI.Commands;
+using Tango.Transport;
+
+namespace Tango.Emulations
+{
+ /// <summary>
+ /// Represents an <see cref="IEmulator"/> base class.
+ /// </summary>
+ /// <seealso cref="Tango.SharedUI.ExtendedObject" />
+ /// <seealso cref="Tango.Emulations.IEmulator" />
+ public abstract class EmulatorBase : ExtendedObject, IEmulator
+ {
+ #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(); }
+ }
+
+ private ITransporter _transporter;
+ /// <summary>
+ /// Gets or sets the transporter.
+ /// </summary>
+ public ITransporter Transporter
+ {
+ get { return _transporter; }
+ set
+ {
+ _transporter = value;
+ SetTransporter(_transporter);
+ }
+ }
+
+ #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="EmulatorBase"/> class.
+ /// </summary>
+ public EmulatorBase()
+ {
+ StartCommand = new RelayCommand(async () => { await Start(); }, (x) => !IsStarted);
+ StopCommand = new RelayCommand(async () => { await Stop(); }, (x) => IsStarted);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="EmulatorBase"/> class.
+ /// </summary>
+ /// <param name="transporter">The transporter.</param>
+ public EmulatorBase(ITransporter transporter) : this()
+ {
+ Transporter = transporter;
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ /// <summary>
+ /// Sets the transporter.
+ /// </summary>
+ /// <param name="transporter">The transporter.</param>
+ private void SetTransporter(ITransporter transporter)
+ {
+ if (_transporter != null)
+ {
+ _transporter.StateChanged -= OnTransporterStateChanged;
+ }
+
+ _transporter = transporter;
+ _transporter.RequestReceived += OnTransporterRequestReceived;
+
+ _transporter.StateChanged += OnTransporterStateChanged;
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Stops this instance.
+ /// </summary>
+ public async Task Stop()
+ {
+ if (IsStarted)
+ {
+ await _transporter.Disconnect();
+ IsStarted = false;
+ }
+ }
+
+ /// <summary>
+ /// Starts this instance.
+ /// </summary>
+ public async Task Start()
+ {
+ if (!IsStarted)
+ {
+ await _transporter.Connect();
+ IsStarted = true;
+ }
+ }
+
+ #endregion
+
+ #region Virtual Methods
+
+ /// <summary>
+ /// Called when transporter state has changed.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="e">The e.</param>
+ protected virtual void OnTransporterStateChanged(object sender, TransportComponentState e)
+ {
+ LogManager.Log("Transporter state changed: " + e.ToString());
+ }
+
+ #endregion
+
+ #region Abstract Methods
+
+ /// <summary>
+ /// Called on new request message.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="container">The container.</param>
+ protected abstract void OnTransporterRequestReceived(object sender, MessageContainer container);
+
+ #endregion
+
+ #region Dispose
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ Stop().Wait();
+ if (Transporter != null) Transporter.Dispose();
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs
new file mode 100644
index 000000000..b41fd1804
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs
@@ -0,0 +1,87 @@
+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.Transport.Servers;
+using Tango.Logging;
+using Tango.PMR;
+using Tango.PMR.Common;
+using Tango.PMR.Stubs;
+using Tango.SharedUI;
+using Tango.SharedUI.Commands;
+using Tango.Transport;
+
+namespace Tango.Emulations.Emulators
+{
+ public class MachineEmulator : EmulatorBase
+ {
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MachineEmulator"/> class.
+ /// </summary>
+ public MachineEmulator() : base()
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MachineEmulator"/> class.
+ /// </summary>
+ /// <param name="transporter">The transporter.</param>
+ public MachineEmulator(ITransporter transporter) : base(transporter)
+ {
+
+ }
+
+ #endregion
+
+ #region Override Methods
+
+ /// <summary>
+ /// Called on new request message.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="container">The container.</param>
+ protected override void OnTransporterRequestReceived(object sender, MessageContainer container)
+ {
+ switch (container.Type)
+ {
+ case MessageType.CalculateRequest:
+ Task.Factory.StartNew(() =>
+ {
+ var request = MessageFactory.ParseMessageFromContainer<CalculateRequest>(container);
+ var response = MessageFactory.CreateTangoMessage<CalculateResponse>(container.Token);
+ response.Message.Sum = request.A + request.B;
+ Transporter.SendResponse(response);
+ });
+ break;
+ case MessageType.ProgressRequest:
+
+ var r = MessageFactory.ParseMessageFromContainer<ProgressRequest>(container);
+
+ Task.Factory.StartNew(() =>
+ {
+ for (int i = 0; i < 10; i++)
+ {
+ Thread.Sleep(500);
+ var res = MessageFactory.CreateTangoMessage<ProgressResponse>(container.Token);
+ res.Message.Progress = i;
+
+ if (i == 9) res.Container.Completed = true;
+
+ Transporter.SendResponse(res);
+ }
+ });
+
+ break;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Emulations/Emulators/MobileEmulator.cs b/Software/Visual_Studio/Tango.Emulations/Emulators/MobileEmulator.cs
new file mode 100644
index 000000000..ed2f50db6
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Emulations/Emulators/MobileEmulator.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.PMR;
+using Tango.PMR.Common;
+using Tango.PMR.Stubs;
+using Tango.Transport;
+
+namespace Tango.Emulations.Emulators
+{
+ public class MobileEmulator : EmulatorBase
+ {
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MobileEmulator "/> class.
+ /// </summary>
+ public MobileEmulator() : base()
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MobileEmulator "/> class.
+ /// </summary>
+ /// <param name="transporter">The transporter.</param>
+ public MobileEmulator(ITransporter transporter) : base(transporter)
+ {
+
+ }
+
+ #endregion
+
+ #region Override Methods
+
+ /// <summary>
+ /// Called on new request message.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="container">The container.</param>
+ protected override void OnTransporterRequestReceived(object sender, MessageContainer container)
+ {
+ switch (container.Type)
+ {
+ case MessageType.CalculateRequest:
+
+ Thread.Sleep(1000);
+ var request = MessageFactory.ParseMessageFromContainer<CalculateRequest>(container);
+ Transporter.SendResponse<CalculateResponse>(new CalculateResponse()
+ {
+ Sum = request.A + request.B,
+ }, container.Token);
+ break;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Emulations/IEmulator.cs b/Software/Visual_Studio/Tango.Emulations/IEmulator.cs
new file mode 100644
index 000000000..360087f96
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Emulations/IEmulator.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.SharedUI.Commands;
+using Tango.Transport;
+
+namespace Tango.Emulations
+{
+ public interface IEmulator : IDisposable
+ {
+ /// <summary>
+ /// Starts this emulator.
+ /// </summary>
+ Task Stop();
+
+ /// <summary>
+ /// Starts this instance.
+ /// </summary>
+ Task Start();
+
+ /// <summary>
+ /// Gets or sets the transporter.
+ /// </summary>
+ ITransporter Transporter { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance is started.
+ /// </summary>
+ bool IsStarted { get; set; }
+
+ /// <summary>
+ /// Gets or sets the start command.
+ /// </summary>
+ RelayCommand StartCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the stop command.
+ /// </summary>
+ RelayCommand StopCommand { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Emulations/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.Emulations/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..0882138f5
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Emulations/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Emulation Components")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Emulations/Tango.Emulations.csproj b/Software/Visual_Studio/Tango.Emulations/Tango.Emulations.csproj
new file mode 100644
index 000000000..aae43bf96
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Emulations/Tango.Emulations.csproj
@@ -0,0 +1,81 @@
+<?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>{63561E19-FF5A-414B-A5EF-E30711543E1D}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tango.Emulations</RootNamespace>
+ <AssemblyName>Tango.Emulations</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.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Versioning\GlobalVersionInfo.cs">
+ <Link>GlobalVersionInfo.cs</Link>
+ </Compile>
+ <Compile Include="EmulatorBase.cs" />
+ <Compile Include="Emulators\MachineEmulator.cs" />
+ <Compile Include="Emulators\MobileEmulator.cs" />
+ <Compile Include="IEmulator.cs" />
+ <Compile Include="Properties\AssemblyInfo.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.SharedUI\Tango.SharedUI.csproj">
+ <Project>{ac489889-6e50-4f16-9dba-ff4c6f9ec72b}</Project>
+ <Name>Tango.SharedUI</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.Transport\Tango.Transport.csproj">
+ <Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
+ <Name>Tango.Transport</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Emulations/packages.config b/Software/Visual_Studio/Tango.Emulations/packages.config
new file mode 100644
index 000000000..e7e6cbade
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Emulations/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.Protobuf" version="3.4.1" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Logging/ApplicationCrashedEventArgs.cs b/Software/Visual_Studio/Tango.Logging/ApplicationCrashedEventArgs.cs
new file mode 100644
index 000000000..9a6e03351
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/ApplicationCrashedEventArgs.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Logging
+{
+ /// <summary>
+ /// Represents an application crash event arguments
+ /// </summary>
+ /// <seealso cref="System.EventArgs" />
+ public class ApplicationCrashedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets or sets the error.
+ /// </summary>
+ public String Error { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to attempt recovering from this crash and ignoring the exception.
+ /// </summary>
+ public bool TryRecover { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ApplicationCrashedEventArgs"/> class.
+ /// </summary>
+ /// <param name="error">The error.</param>
+ public ApplicationCrashedEventArgs(String error)
+ {
+ Error = error;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Logging/ConsoleLogger.cs b/Software/Visual_Studio/Tango.Logging/ConsoleLogger.cs
new file mode 100644
index 000000000..d066d89e8
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/ConsoleLogger.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Tango.Logging
+{
+ public class ConsoleLogger : ILogger
+ {
+ private bool _consoleOpened;
+ private String _consoleTitle;
+ private ConsoleWindow console;
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="ILogger" /> is enabled.
+ /// </summary>
+ public bool Enabled { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="ILogger" /> will be notified about logs without waiting for the logs queue.
+ /// </summary>
+ public bool Immediate { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ConsoleLogger"/> class.
+ /// </summary>
+ public ConsoleLogger(String consoleTitle)
+ {
+ _consoleTitle = consoleTitle;
+ Enabled = true;
+ Immediate = true;
+ }
+
+ /// <summary>
+ /// Called when a new library exception is available.
+ /// </summary>
+ /// <param name="output">The output.</param>
+ public void OnError(LogItemBase output)
+ {
+ EnsureConsoleOpen(() =>
+ {
+ console.SetColor(ConsoleColor.Red);
+ console.WriteLine(output.ToString());
+ });
+ }
+
+ /// <summary>
+ /// Called when a new library trace is available.
+ /// </summary>
+ /// <param name="output">The output.</param>
+ public void OnTrace(LogItemBase output)
+ {
+ EnsureConsoleOpen(() =>
+ {
+ console.SetColor(ConsoleColor.White);
+ console.WriteLine(output.ToString());
+ });
+ }
+
+ /// <summary>
+ /// Waits until user closes the console.
+ /// </summary>
+ /// <returns></returns>
+ public async Task WaitForConsoleExit()
+ {
+ if (console != null)
+ {
+ await console.WaitForUserClose();
+ }
+ }
+
+ /// <summary>
+ /// Ensures the console is open.
+ /// </summary>
+ private void EnsureConsoleOpen(Action post)
+ {
+ if (!_consoleOpened)
+ {
+ Thread t = new Thread(() =>
+ {
+ console = new ConsoleWindow();
+ console.Title += " - " + _consoleTitle;
+ _consoleOpened = true;
+ console.Show();
+ console.Closed += (sender2, e2) => console.Dispatcher.InvokeShutdown();
+ System.Windows.Threading.Dispatcher.Run();
+ });
+
+ t.IsBackground = true;
+ t.SetApartmentState(ApartmentState.STA);
+ t.Start();
+ }
+
+ while (!_consoleOpened)
+ {
+ Thread.Sleep(10);
+ }
+
+ post();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml b/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml
new file mode 100644
index 000000000..e73ccf415
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml
@@ -0,0 +1,12 @@
+<Window x:Class="Tango.Logging.ConsoleWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Tango.Logging"
+ mc:Ignorable="d"
+ Height="500" Width="800" Background="Black" FontSize="13" Topmost="True" Foreground="Gainsboro" FontFamily="Lucida Console" Title="Console Emulator" RenderOptions.EdgeMode="Aliased">
+ <Grid>
+ <RichTextBox x:Name="txtLog" Background="Black" BorderThickness="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Visible"></RichTextBox>
+ </Grid>
+</Window>
diff --git a/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml.cs b/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml.cs
new file mode 100644
index 000000000..e95284cf8
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/ConsoleWindow.xaml.cs
@@ -0,0 +1,150 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+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 System.Windows.Threading;
+
+namespace Tango.Logging
+{
+ /// <summary>
+ /// Represents a debugging (write-only) console emulator.
+ /// </summary>
+ public partial class ConsoleWindow : Window
+ {
+ private bool _closing;
+ private SolidColorBrush _currentBrush;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ConsoleWindow"/> class.
+ /// </summary>
+ public ConsoleWindow()
+ {
+ InitializeComponent();
+
+ txtLog.Document.LineHeight = 15;
+ txtLog.Document.PageWidth = 4000;
+ _currentBrush = Brushes.Gainsboro;
+
+ AppendLog("--------------------- Twine Console Emulator ---------------------" + Environment.NewLine + Environment.NewLine);
+
+ Closing += ConsoleWindow_Closing;
+ }
+
+ /// <summary>
+ /// Handles the Closing event of the ConsoleWindow control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
+ private void ConsoleWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
+ {
+ _closing = true;
+ }
+
+ /// <summary>
+ /// Appends the specified .
+ /// </summary>
+ /// <param name="obj">The object.</param>
+ public void WriteLine(object obj)
+ {
+ AppendLog(obj.ToString() + Environment.NewLine);
+ }
+
+ /// <summary>
+ /// Writes the specified object.
+ /// </summary>
+ /// <param name="obj">The object.</param>
+ public void Write(object obj)
+ {
+ AppendLog(obj.ToString());
+ }
+
+ /// <summary>
+ /// Sets the console foreground color.
+ /// </summary>
+ /// <param name="color">The color.</param>
+ public void SetColor(ConsoleColor color)
+ {
+ InvokeUI(() => _currentBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString(color.ToString())));
+ }
+
+ private void AppendLog(String log)
+ {
+ InvokeUI(() =>
+ {
+ TextRange tr = new TextRange(txtLog.Document.ContentEnd, txtLog.Document.ContentEnd);
+ tr.Text = log;
+ tr.ApplyPropertyValue(TextElement.ForegroundProperty, _currentBrush);
+ Rect r = txtLog.Document.ContentEnd.GetCharacterRect(LogicalDirection.Forward);
+ txtLog.ScrollToVerticalOffset(r.Y);
+ });
+ }
+
+ /// <summary>
+ /// Opens the console.
+ /// </summary>
+ public void Open()
+ {
+ Show();
+ }
+
+ /// <summary>
+ /// Closes the console.
+ /// </summary>
+ public new void Close()
+ {
+ Close();
+ }
+
+ /// <summary>
+ /// Waits until user closes the window.
+ /// </summary>
+ /// <returns></returns>
+ public async Task WaitForUserClose()
+ {
+ WriteLine("");
+ WriteLine("Close this window to exit...");
+
+ await Task.Factory.StartNew(() =>
+ {
+ while (!_closing)
+ {
+ Thread.Sleep(10);
+ }
+ });
+ }
+
+ /// <summary>
+ /// Invokes the UI.
+ /// </summary>
+ /// <param name="action">The action.</param>
+ private void InvokeUI(Action action)
+ {
+ Dispatcher.Invoke(action);
+ DoEvents();
+ }
+
+ /// <summary>
+ /// Forces the next rendering thread frame.
+ /// </summary>
+ private void DoEvents()
+ {
+ if (Application.Current == null) //Using this to enable processing outside a WPF application.
+ {
+ new Application { ShutdownMode = ShutdownMode.OnExplicitShutdown };
+ }
+
+ Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { }));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Logging/ExceptionLogItem.cs b/Software/Visual_Studio/Tango.Logging/ExceptionLogItem.cs
new file mode 100644
index 000000000..de526f954
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/ExceptionLogItem.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Logging
+{
+ /// <summary>
+ /// Represents an exception log item.
+ /// </summary>
+ public class ExceptionLogItem : LogItemBase
+ {
+ /// <summary>
+ /// Gets or sets the log item exception.
+ /// </summary>
+ public Exception InnerException { get; set; }
+
+ /// <summary>
+ /// Gets or sets the error description.
+ /// </summary>
+ public String Description { get; set; }
+
+ /// <summary>
+ /// Returns a formatted string of the log item.
+ /// </summary>
+ public override string ToString()
+ {
+ return String.Format("[{0}] [{1}] [{2}] [Line {3}]: {4}{5}", TimeStamp.ToString("HH:mm:ss.ff"), Path.GetFileNameWithoutExtension(CallerFile), CallerMethodName, CallerLineNumber, Description, Environment.NewLine + InnerException.Message);
+ }
+
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Logging/FileLogger.cs b/Software/Visual_Studio/Tango.Logging/FileLogger.cs
new file mode 100644
index 000000000..ca17aa367
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/FileLogger.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Logging
+{
+ /// <summary>
+ /// Represents an <see cref="ILogger"/> file logger.
+ /// </summary>
+ /// <seealso cref="Tango.Logging.ILogger" />
+ public class FileLogger : ILogger
+ {
+
+ /// <summary>
+ /// Gets or sets the log file.
+ /// </summary>
+ public String LogFile { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FileLogger"/> class.
+ /// </summary>
+ public FileLogger()
+ {
+ _isEnabled = true;
+ String logsFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "logs");
+ Directory.CreateDirectory(logsFolder);
+ LogFile = Path.Combine(logsFolder, string.Format("{1}-{0:yyyy-MM-dd_hh-mm-ss}.log", DateTime.Now, Path.GetFileNameWithoutExtension(System.AppDomain.CurrentDomain.FriendlyName)));
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FileLogger"/> class.
+ /// </summary>
+ /// <param name="logFile">The log file.</param>
+ public FileLogger(String logFile)
+ : this()
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(logFile));
+ LogFile = logFile;
+ }
+
+ /// <summary>
+ /// Called when a new library trace is available.
+ /// </summary>
+ /// <param name="output">The output.</param>
+ public void OnTrace(LogItemBase output)
+ {
+ OnError(output);
+ }
+
+ /// <summary>
+ /// Called when a new library exception is available.
+ /// </summary>
+ /// <param name="output">The output.</param>
+ public void OnError(LogItemBase output)
+ {
+ File.AppendAllText(LogFile, output.ToString() + Environment.NewLine);
+ }
+
+ private bool _isEnabled;
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="ILogger" /> is enabled.
+ /// </summary>
+ public bool Enabled
+ {
+ get
+ {
+ return _isEnabled;
+ }
+ set
+ {
+ _isEnabled = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="ILogger" /> will be notified about logs without waiting for the logs queue.
+ /// </summary>
+ public bool Immediate { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Logging/GlobalExceptionTrapper.cs b/Software/Visual_Studio/Tango.Logging/GlobalExceptionTrapper.cs
new file mode 100644
index 000000000..a0b52b077
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/GlobalExceptionTrapper.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Threading;
+using Tango.Logging;
+
+namespace Tango.Logging
+{
+ /// <summary>
+ /// Represents an optimized WPF global exception trapper.
+ /// </summary>
+ /// <seealso cref="Tango.Logging.IGlobalExceptionTrapper" />
+ public class WpfGlobalExceptionTrapper : IGlobalExceptionTrapper
+ {
+ private DateTime _lastGlobalExceptionTime = DateTime.Now;
+
+ /// <summary>
+ /// Occurs when the global exception trapper has detected an unhandled exception.
+ /// </summary>
+ public event EventHandler<ApplicationCrashedEventArgs> ApplicationCrashed;
+
+ /// <summary>
+ /// Initializes the specified application.
+ /// </summary>
+ /// <param name="app">The application.</param>
+ public void Initialize(Application app)
+ {
+ AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
+ app.Dispatcher.UnhandledException += Dispatcher_UnhandledException;
+ Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
+ TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
+ }
+
+ /// <summary>
+ /// Handles the UnobservedTaskException event of the TaskScheduler control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="UnobservedTaskExceptionEventArgs"/> instance containing the event data.</param>
+ private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
+ {
+ OnApplicationCrash(e.Exception.ToStringSafe());
+ }
+
+ /// <summary>
+ /// Handles the DispatcherUnhandledException event of the Current control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="System.Windows.Threading.DispatcherUnhandledExceptionEventArgs"/> instance containing the event data.</param>
+ private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
+ {
+ e.Handled = OnApplicationCrash(e.Exception.ToStringSafe());
+ }
+
+ /// <summary>
+ /// Handles the UnhandledException event of the Dispatcher control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="System.Windows.Threading.DispatcherUnhandledExceptionEventArgs"/> instance containing the event data.</param>
+ private void Dispatcher_UnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
+ {
+ e.Handled = OnApplicationCrash(e.Exception.ToStringSafe());
+ }
+
+ /// <summary>
+ /// Handles the UnhandledException event of the CurrentDomain control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="UnhandledExceptionEventArgs"/> instance containing the event data.</param>
+ private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
+ {
+ OnApplicationCrash(e.ExceptionObject.ToStringSafe());
+ }
+
+ /// <summary>
+ /// Called when any unhandled application exception has occurred and write to log.
+ /// </summary>
+ /// <param name="error">The error.</param>
+ private bool OnApplicationCrash(String error)
+ {
+ if (DateTime.Now - _lastGlobalExceptionTime > TimeSpan.FromSeconds(1))
+ {
+ _lastGlobalExceptionTime = DateTime.Now;
+ return true;
+ }
+
+ _lastGlobalExceptionTime = DateTime.Now;
+ LogManager.OverrideQueue = true;
+ LogManager.Log("Application Crash!" + Environment.NewLine + error);
+
+ ApplicationCrashedEventArgs e = new ApplicationCrashedEventArgs(error);
+
+ ApplicationCrashed?.Invoke(this, e);
+
+ if (e.TryRecover)
+ {
+ LogManager.Log("Trying application recovery. Ignoring exception...");
+ }
+
+ LogManager.OverrideQueue = false;
+ return e.TryRecover;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Logging/IGlobalExceptionTrapper.cs b/Software/Visual_Studio/Tango.Logging/IGlobalExceptionTrapper.cs
new file mode 100644
index 000000000..6ef59ec4d
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/IGlobalExceptionTrapper.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Logging
+{
+ /// <summary>
+ /// Represents a global exception trapper.
+ /// </summary>
+ public interface IGlobalExceptionTrapper
+ {
+ /// <summary>
+ /// Occurs when the global exception trapper has detected an unhandled exception.
+ /// </summary>
+ event EventHandler<ApplicationCrashedEventArgs> ApplicationCrashed;
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Logging/ILogger.cs b/Software/Visual_Studio/Tango.Logging/ILogger.cs
new file mode 100644
index 000000000..61108962a
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/ILogger.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Logging
+{
+ /// <summary>
+ /// Represents a logging mechanism capable of being registered as a logger on the library <see cref="LogManager"/>.
+ /// </summary>
+ public interface ILogger
+ {
+ /// <summary>
+ /// Called when a new library trace is available.
+ /// </summary>
+ /// <param name="output">The output.</param>
+ void OnTrace(LogItemBase output);
+
+ /// <summary>
+ /// Called when a new library exception is available.
+ /// </summary>
+ /// <param name="output">The output.</param>
+ void OnError(LogItemBase output);
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="ILogger"/> is enabled.
+ /// </summary>
+ bool Enabled { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="ILogger"/> will be notified about logs without waiting for the logs queue.
+ /// </summary>
+ bool Immediate { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Logging/LogItemBase.cs b/Software/Visual_Studio/Tango.Logging/LogItemBase.cs
new file mode 100644
index 000000000..38e78d3ac
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/LogItemBase.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Logging
+{
+ /// <summary>
+ /// Represents a base class for log items.
+ /// </summary>
+ public abstract class LogItemBase
+ {
+ /// <summary>
+ /// Gets or sets the caller method adding the exception.
+ /// </summary>
+ public String CallerMethodName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the caller file.
+ /// </summary>
+ public String CallerFile { get; set; }
+
+ /// <summary>
+ /// Gets or sets the caller line number.
+ /// </summary>
+ public int CallerLineNumber { get; set; }
+
+ /// <summary>
+ /// Gets or sets the DateTime for the log.
+ /// </summary>
+ public DateTime TimeStamp { get; set; }
+
+ /// <summary>
+ /// Returns a formatted string of the log item.
+ /// </summary>
+ public abstract override String ToString();
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Logging/LogManager.cs b/Software/Visual_Studio/Tango.Logging/LogManager.cs
new file mode 100644
index 000000000..3ada76104
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/LogManager.cs
@@ -0,0 +1,220 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Tango.Logging
+{
+ /// <summary>
+ /// Represents a helper class for logging information and errors.
+ /// </summary>
+ public static class LogManager
+ {
+ private static List<ILogger> _loggers;
+ private static ConcurrentQueue<LogItemBase> _logs;
+ private static Thread _loggingThread;
+ private static bool _isStarted;
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to propagate logs instantly (Warning - not thread safe).
+ /// </summary>
+ public static bool OverrideQueue { get; set; }
+
+ /// <summary>
+ /// Initializes the <see cref="LogManager"/> class.
+ /// </summary>
+ static LogManager()
+ {
+ _loggers = new List<ILogger>();
+ _logs = new ConcurrentQueue<LogItemBase>();
+ }
+
+ /// <summary>
+ /// Registers a logger.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
+ public static void RegisterLogger(ILogger logger)
+ {
+ if (logger != null && !_loggers.Contains(logger))
+ {
+ _loggers.Add(logger);
+ }
+ }
+
+ /// <summary>
+ /// Unregisters a logger.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
+ public static void UnregisterLogger(ILogger logger)
+ {
+ if (logger != null && _loggers.Contains(logger))
+ {
+ _loggers.Remove(logger);
+ }
+ }
+
+ /// <summary>
+ /// Add new exception log item.
+ /// </summary>
+ /// <param name="e">Exception.</param>
+ /// <param name="description">Error description.</param>
+ public static Exception Log(Exception e, String description = null, [CallerMemberName] string caller = null, [CallerFilePath] string file = null, [CallerLineNumber] int lineNumber = 0)
+ {
+ ExceptionLogItem log = new ExceptionLogItem();
+ log.CallerMethodName = caller;
+ log.CallerFile = file;
+ log.CallerLineNumber = lineNumber;
+ log.TimeStamp = DateTime.Now;
+ log.InnerException = e;
+ log.Description = description != null ? description : e.ToString();
+
+ if (!OverrideQueue)
+ {
+ AppendLog(log);
+ }
+ else
+ {
+ AppendLogInstantly(log);
+ }
+
+ return e;
+ }
+
+ /// <summary>
+ /// Add new message log item.
+ /// </summary>
+ /// <param name="message">Message.</param>
+ public static void Log(String message, [CallerMemberName] string caller = null, [CallerFilePath] string file = null, [CallerLineNumber] int lineNumber = 0)
+ {
+ MessageLogItem log = new MessageLogItem();
+ log.CallerMethodName = caller;
+ log.CallerFile = file;
+ log.CallerLineNumber = lineNumber;
+ log.TimeStamp = DateTime.Now;
+ log.Message = message;
+
+ if (!OverrideQueue)
+ {
+ AppendLog(log);
+ }
+ else
+ {
+ AppendLogInstantly(log);
+ }
+ }
+
+ /// <summary>
+ /// Appends the log.
+ /// </summary>
+ /// <param name="log">The log.</param>
+ private static void AppendLog(LogItemBase log)
+ {
+ if (log != null)
+ {
+ if (log.GetType() == typeof(ExceptionLogItem))
+ {
+ _loggers.Where(x => x.Enabled && x.Immediate).ToList().ForEach(x => x.OnError(log));
+ }
+ else
+ {
+ _loggers.Where(x => x.Enabled && x.Immediate).ToList().ForEach(x => x.OnTrace(log));
+ }
+ }
+
+ _logs.Enqueue(log);
+ StartLoggingThread();
+ }
+
+ /// <summary>
+ /// Starts the logging thread.
+ /// </summary>
+ private static void StartLoggingThread()
+ {
+ if (!_isStarted)
+ {
+ _isStarted = true;
+ _loggingThread = new Thread(LoggingThreadMethod);
+ _loggingThread.IsBackground = true;
+ _loggingThread.Start();
+ }
+ }
+
+ /// <summary>
+ /// Loggings thread method.
+ /// </summary>
+ [DebuggerStepThrough]
+ [DebuggerHidden]
+ private static void LoggingThreadMethod()
+ {
+ while (_logs.Count > 0)
+ {
+ LogItemBase log;
+
+ if (_logs.TryDequeue(out log))
+ {
+ if (log != null)
+ {
+ if (log.GetType() == typeof(ExceptionLogItem))
+ {
+ _loggers.Where(x => x.Enabled && !x.Immediate).ToList().ForEach(x => x.OnError(log));
+ }
+ else
+ {
+ _loggers.Where(x => x.Enabled && !x.Immediate).ToList().ForEach(x => x.OnTrace(log));
+ }
+ }
+ }
+
+ Thread.Sleep(10);
+ }
+
+ Thread.Sleep(400);
+
+ if (_logs.Count > 0)
+ {
+ LoggingThreadMethod();
+ return;
+ }
+
+ _isStarted = false;
+ }
+
+ /// <summary>
+ /// Appends the log instantly.
+ /// </summary>
+ /// <param name="log">The log.</param>
+ [DebuggerStepThrough]
+ [DebuggerHidden]
+ private static void AppendLogInstantly(LogItemBase log)
+ {
+ bool wroteLog = false;
+
+ while (!wroteLog)
+ {
+ try
+ {
+ if (log.GetType() == typeof(ExceptionLogItem))
+ {
+ _loggers.Where(x => x.Enabled).ToList().ForEach(x => x.OnError(log));
+ }
+ else
+ {
+ _loggers.Where(x => x.Enabled).ToList().ForEach(x => x.OnTrace(log));
+ }
+
+ wroteLog = true;
+ }
+ catch
+ {
+ Thread.Sleep(5);
+ }
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Logging/MessageLogItem.cs b/Software/Visual_Studio/Tango.Logging/MessageLogItem.cs
new file mode 100644
index 000000000..44cb2c575
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/MessageLogItem.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Logging
+{
+ /// <summary>
+ /// Represents an exception log item.
+ /// </summary>
+ public class MessageLogItem : LogItemBase
+ {
+ /// <summary>
+ /// Gets or sets the log message.
+ /// </summary>
+ public String Message { get; set; }
+
+ /// <summary>
+ /// Returns a formatted string of the log item.
+ /// </summary>
+ public override string ToString()
+ {
+ return String.Format("[{0}] [{1}] [{2}] [Line {3}]: {4}", TimeStamp.ToString("HH:mm:ss.ff"), Path.GetFileNameWithoutExtension(CallerFile), CallerMethodName, CallerLineNumber, Message);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Logging/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.Logging/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..161c5a04e
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Logging Library")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Logging/Tango.Logging.csproj b/Software/Visual_Studio/Tango.Logging/Tango.Logging.csproj
new file mode 100644
index 000000000..0ddac836f
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/Tango.Logging.csproj
@@ -0,0 +1,80 @@
+<?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>{BC932DBD-7CDB-488C-99E4-F02CF441F55E}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tango.Logging</RootNamespace>
+ <AssemblyName>Tango.Logging</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="PresentationCore" />
+ <Reference Include="PresentationFramework" />
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Windows" />
+ <Reference Include="System.Xaml" />
+ <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="ApplicationCrashedEventArgs.cs" />
+ <Compile Include="ConsoleLogger.cs" />
+ <Compile Include="ConsoleWindow.xaml.cs">
+ <DependentUpon>ConsoleWindow.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="ExceptionLogItem.cs" />
+ <Compile Include="FileLogger.cs" />
+ <Compile Include="GlobalExceptionTrapper.cs" />
+ <Compile Include="IGlobalExceptionTrapper.cs" />
+ <Compile Include="ILogger.cs" />
+ <Compile Include="LogItemBase.cs" />
+ <Compile Include="LogManager.cs" />
+ <Compile Include="MessageLogItem.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="VSOutputLogger.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Page Include="ConsoleWindow.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Logging/VSOutputLogger.cs b/Software/Visual_Studio/Tango.Logging/VSOutputLogger.cs
new file mode 100644
index 000000000..80de5292f
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Logging/VSOutputLogger.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Logging
+{
+ /// <summary>
+ /// Represents a library logger for routing logs to the Visual Studio output window.
+ /// </summary>
+ public class VSOutputLogger : ILogger
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="VSOutputLogger"/> class.
+ /// </summary>
+ public VSOutputLogger()
+ {
+ Immediate = true;
+ Enabled = true;
+ }
+
+ /// <summary>
+ /// Called when a new library trace is available.
+ /// </summary>
+ /// <param name="output">The output.</param>
+ public void OnTrace(LogItemBase output)
+ {
+ Debug.WriteLine(output.ToString());
+ }
+
+ /// <summary>
+ /// Called when a new library exception is available.
+ /// </summary>
+ /// <param name="output">The output.</param>
+ public void OnError(LogItemBase output)
+ {
+ Debug.WriteLine(output.ToString());
+ }
+
+
+ private bool _isEnabled;
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="ILogger" /> is enabled.
+ /// </summary>
+ public bool Enabled
+ {
+ get
+ {
+ return _isEnabled;
+ }
+ set
+ {
+ _isEnabled = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="ILogger" /> will be notified about logs without waiting for the logs queue.
+ /// </summary>
+ public bool Immediate { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.PMR/Common/MessageContainer.cs b/Software/Visual_Studio/Tango.PMR/Common/MessageContainer.cs
new file mode 100644
index 000000000..3939e53c7
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Common/MessageContainer.cs
@@ -0,0 +1,274 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: MessageContainer.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.Common {
+
+ /// <summary>Holder for reflection information generated from MessageContainer.proto</summary>
+ public static partial class MessageContainerReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for MessageContainer.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static MessageContainerReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "ChZNZXNzYWdlQ29udGFpbmVyLnByb3RvEhBUYW5nby5QTVIuQ29tbW9uGhFN",
+ "ZXNzYWdlVHlwZS5wcm90byKDAQoQTWVzc2FnZUNvbnRhaW5lchIrCgRUeXBl",
+ "GAEgASgOMh0uVGFuZ28uUE1SLkNvbW1vbi5NZXNzYWdlVHlwZRINCgVUb2tl",
+ "bhgCIAEoCRISCgpDb250aW51b3VzGAMgASgIEhEKCUNvbXBsZXRlZBgEIAEo",
+ "CBIMCgREYXRhGAUgASgMQhwKGmNvbS50d2luZS50YW5nby5wbXIuY29tbW9u",
+ "YgZwcm90bzM="));
+ 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", "Token", "Continuous", "Completed", "Data" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class MessageContainer : pb::IMessage<MessageContainer> {
+ private static readonly pb::MessageParser<MessageContainer> _parser = new pb::MessageParser<MessageContainer>(() => new MessageContainer());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<MessageContainer> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Common.MessageContainerReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public MessageContainer() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public MessageContainer(MessageContainer other) : this() {
+ type_ = other.type_;
+ token_ = other.token_;
+ continuous_ = other.continuous_;
+ completed_ = other.completed_;
+ data_ = other.data_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public MessageContainer Clone() {
+ return new MessageContainer(this);
+ }
+
+ /// <summary>Field number for the "Type" field.</summary>
+ public const int TypeFieldNumber = 1;
+ private global::Tango.PMR.Common.MessageType type_ = 0;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Tango.PMR.Common.MessageType Type {
+ get { return type_; }
+ set {
+ type_ = value;
+ }
+ }
+
+ /// <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 "Continuous" field.</summary>
+ public const int ContinuousFieldNumber = 3;
+ private bool continuous_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Continuous {
+ get { return continuous_; }
+ set {
+ continuous_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "Completed" field.</summary>
+ public const int CompletedFieldNumber = 4;
+ private bool completed_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Completed {
+ get { return completed_; }
+ set {
+ completed_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "Data" field.</summary>
+ public const int DataFieldNumber = 5;
+ private pb::ByteString data_ = pb::ByteString.Empty;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pb::ByteString Data {
+ get { return data_; }
+ set {
+ data_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as MessageContainer);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(MessageContainer other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Type != other.Type) return false;
+ if (Token != other.Token) return false;
+ if (Continuous != other.Continuous) return false;
+ if (Completed != other.Completed) return false;
+ if (Data != other.Data) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Type != 0) hash ^= Type.GetHashCode();
+ if (Token.Length != 0) hash ^= Token.GetHashCode();
+ if (Continuous != false) hash ^= Continuous.GetHashCode();
+ if (Completed != false) hash ^= Completed.GetHashCode();
+ if (Data.Length != 0) hash ^= Data.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 (Type != 0) {
+ output.WriteRawTag(8);
+ output.WriteEnum((int) Type);
+ }
+ if (Token.Length != 0) {
+ output.WriteRawTag(18);
+ output.WriteString(Token);
+ }
+ if (Continuous != false) {
+ output.WriteRawTag(24);
+ output.WriteBool(Continuous);
+ }
+ if (Completed != false) {
+ output.WriteRawTag(32);
+ output.WriteBool(Completed);
+ }
+ if (Data.Length != 0) {
+ output.WriteRawTag(42);
+ output.WriteBytes(Data);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Type != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type);
+ }
+ if (Token.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Token);
+ }
+ if (Continuous != false) {
+ size += 1 + 1;
+ }
+ if (Completed != false) {
+ size += 1 + 1;
+ }
+ if (Data.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeBytesSize(Data);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(MessageContainer other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Type != 0) {
+ Type = other.Type;
+ }
+ if (other.Token.Length != 0) {
+ Token = other.Token;
+ }
+ if (other.Continuous != false) {
+ Continuous = other.Continuous;
+ }
+ if (other.Completed != false) {
+ Completed = other.Completed;
+ }
+ if (other.Data.Length != 0) {
+ Data = other.Data;
+ }
+ }
+
+ [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: {
+ type_ = (global::Tango.PMR.Common.MessageType) input.ReadEnum();
+ break;
+ }
+ case 18: {
+ Token = input.ReadString();
+ break;
+ }
+ case 24: {
+ Continuous = input.ReadBool();
+ break;
+ }
+ case 32: {
+ Completed = input.ReadBool();
+ break;
+ }
+ case 42: {
+ Data = input.ReadBytes();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs b/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs
new file mode 100644
index 000000000..0012627bb
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs
@@ -0,0 +1,52 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: MessageType.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.Common {
+
+ /// <summary>Holder for reflection information generated from MessageType.proto</summary>
+ public static partial class MessageTypeReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for MessageType.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static MessageTypeReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "ChFNZXNzYWdlVHlwZS5wcm90bxIQVGFuZ28uUE1SLkNvbW1vbiqEAQoLTWVz",
+ "c2FnZVR5cGUSBwoDUkdCEAASBwoDSm9iEAESCwoHU2VnbWVudBACEhQKEENh",
+ "bGN1bGF0ZVJlcXVlc3QQAxIVChFDYWxjdWxhdGVSZXNwb25zZRAEEhMKD1By",
+ "b2dyZXNzUmVxdWVzdBAFEhQKEFByb2dyZXNzUmVzcG9uc2UQBkIcChpjb20u",
+ "dHdpbmUudGFuZ28ucG1yLmNvbW1vbmIGcHJvdG8z"));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Tango.PMR.Common.MessageType), }, null));
+ }
+ #endregion
+
+ }
+ #region Enums
+ public enum MessageType {
+ [pbr::OriginalName("RGB")] Rgb = 0,
+ [pbr::OriginalName("Job")] Job = 1,
+ [pbr::OriginalName("Segment")] Segment = 2,
+ [pbr::OriginalName("CalculateRequest")] CalculateRequest = 3,
+ [pbr::OriginalName("CalculateResponse")] CalculateResponse = 4,
+ [pbr::OriginalName("ProgressRequest")] ProgressRequest = 5,
+ [pbr::OriginalName("ProgressResponse")] ProgressResponse = 6,
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual_Studio/Tango.PMR/Common/RGB.cs b/Software/Visual_Studio/Tango.PMR/Common/RGB.cs
new file mode 100644
index 000000000..23f335254
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Common/RGB.cs
@@ -0,0 +1,215 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: RGB.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.Common {
+
+ /// <summary>Holder for reflection information generated from RGB.proto</summary>
+ public static partial class RGBReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for RGB.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static RGBReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "CglSR0IucHJvdG8SEFRhbmdvLlBNUi5Db21tb24iJgoDUkdCEgkKAVIYASAB",
+ "KAUSCQoBRxgCIAEoBRIJCgFCGAMgASgFQhwKGmNvbS50d2luZS50YW5nby5w",
+ "bXIuY29tbW9uYgZwcm90bzM="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Common.RGB), global::Tango.PMR.Common.RGB.Parser, new[]{ "R", "G", "B" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class RGB : pb::IMessage<RGB> {
+ private static readonly pb::MessageParser<RGB> _parser = new pb::MessageParser<RGB>(() => new RGB());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<RGB> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Common.RGBReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public RGB() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public RGB(RGB other) : this() {
+ r_ = other.r_;
+ g_ = other.g_;
+ b_ = other.b_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public RGB Clone() {
+ return new RGB(this);
+ }
+
+ /// <summary>Field number for the "R" field.</summary>
+ public const int RFieldNumber = 1;
+ private int r_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int R {
+ get { return r_; }
+ set {
+ r_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "G" field.</summary>
+ public const int GFieldNumber = 2;
+ private int g_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int G {
+ get { return g_; }
+ set {
+ g_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "B" field.</summary>
+ public const int BFieldNumber = 3;
+ 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 RGB);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(RGB other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (R != other.R) return false;
+ if (G != other.G) return false;
+ if (B != other.B) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (R != 0) hash ^= R.GetHashCode();
+ if (G != 0) hash ^= G.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 (R != 0) {
+ output.WriteRawTag(8);
+ output.WriteInt32(R);
+ }
+ if (G != 0) {
+ output.WriteRawTag(16);
+ output.WriteInt32(G);
+ }
+ if (B != 0) {
+ output.WriteRawTag(24);
+ output.WriteInt32(B);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (R != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(R);
+ }
+ if (G != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(G);
+ }
+ if (B != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(B);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(RGB other) {
+ if (other == null) {
+ return;
+ }
+ if (other.R != 0) {
+ R = other.R;
+ }
+ if (other.G != 0) {
+ G = other.G;
+ }
+ 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: {
+ R = input.ReadInt32();
+ break;
+ }
+ case 16: {
+ G = input.ReadInt32();
+ break;
+ }
+ case 24: {
+ B = input.ReadInt32();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual_Studio/Tango.PMR/Jobs/Job.cs b/Software/Visual_Studio/Tango.PMR/Jobs/Job.cs
new file mode 100644
index 000000000..d505436d4
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Jobs/Job.cs
@@ -0,0 +1,180 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: Job.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.Jobs {
+
+ /// <summary>Holder for reflection information generated from Job.proto</summary>
+ public static partial class JobReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for Job.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static JobReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "CglKb2IucHJvdG8SDlRhbmdvLlBNUi5Kb2JzGg1TZWdtZW50LnByb3RvIj4K",
+ "A0pvYhIMCgROYW1lGAEgASgJEikKCFNlZ21lbnRzGAIgAygLMhcuVGFuZ28u",
+ "UE1SLkpvYnMuU2VnbWVudEIaChhjb20udHdpbmUudGFuZ28ucG1yLmpvYnNi",
+ "BnByb3RvMw=="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { global::Tango.PMR.Jobs.SegmentReflection.Descriptor, },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Jobs.Job), global::Tango.PMR.Jobs.Job.Parser, new[]{ "Name", "Segments" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class Job : pb::IMessage<Job> {
+ private static readonly pb::MessageParser<Job> _parser = new pb::MessageParser<Job>(() => new Job());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<Job> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Jobs.JobReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Job() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Job(Job other) : this() {
+ name_ = other.name_;
+ segments_ = other.segments_.Clone();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Job Clone() {
+ return new Job(this);
+ }
+
+ /// <summary>Field number for the "Name" field.</summary>
+ public const int NameFieldNumber = 1;
+ private string name_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Name {
+ get { return name_; }
+ set {
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "Segments" field.</summary>
+ public const int SegmentsFieldNumber = 2;
+ private static readonly pb::FieldCodec<global::Tango.PMR.Jobs.Segment> _repeated_segments_codec
+ = pb::FieldCodec.ForMessage(18, global::Tango.PMR.Jobs.Segment.Parser);
+ private readonly pbc::RepeatedField<global::Tango.PMR.Jobs.Segment> segments_ = new pbc::RepeatedField<global::Tango.PMR.Jobs.Segment>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<global::Tango.PMR.Jobs.Segment> Segments {
+ get { return segments_; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as Job);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(Job other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Name != other.Name) return false;
+ if(!segments_.Equals(other.segments_)) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Name.Length != 0) hash ^= Name.GetHashCode();
+ hash ^= segments_.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 (Name.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Name);
+ }
+ segments_.WriteTo(output, _repeated_segments_codec);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Name.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
+ }
+ size += segments_.CalculateSize(_repeated_segments_codec);
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(Job other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Name.Length != 0) {
+ Name = other.Name;
+ }
+ segments_.Add(other.segments_);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Name = input.ReadString();
+ break;
+ }
+ case 18: {
+ segments_.AddEntriesFrom(input, _repeated_segments_codec);
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual_Studio/Tango.PMR/Jobs/Segment.cs b/Software/Visual_Studio/Tango.PMR/Jobs/Segment.cs
new file mode 100644
index 000000000..440650812
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Jobs/Segment.cs
@@ -0,0 +1,222 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: Segment.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.Jobs {
+
+ /// <summary>Holder for reflection information generated from Segment.proto</summary>
+ public static partial class SegmentReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for Segment.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static SegmentReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "Cg1TZWdtZW50LnByb3RvEg5UYW5nby5QTVIuSm9icxoJUkdCLnByb3RvIk0K",
+ "B1NlZ21lbnQSDAoETmFtZRgBIAEoCRIOCgZMZW5ndGgYAiABKAUSJAoFQ29s",
+ "b3IYAyABKAsyFS5UYW5nby5QTVIuQ29tbW9uLlJHQkIaChhjb20udHdpbmUu",
+ "dGFuZ28ucG1yLmpvYnNiBnByb3RvMw=="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { global::Tango.PMR.Common.RGBReflection.Descriptor, },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Jobs.Segment), global::Tango.PMR.Jobs.Segment.Parser, new[]{ "Name", "Length", "Color" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class Segment : pb::IMessage<Segment> {
+ private static readonly pb::MessageParser<Segment> _parser = new pb::MessageParser<Segment>(() => new Segment());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<Segment> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Jobs.SegmentReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Segment() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Segment(Segment other) : this() {
+ name_ = other.name_;
+ length_ = other.length_;
+ Color = other.color_ != null ? other.Color.Clone() : null;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Segment Clone() {
+ return new Segment(this);
+ }
+
+ /// <summary>Field number for the "Name" field.</summary>
+ public const int NameFieldNumber = 1;
+ private string name_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Name {
+ get { return name_; }
+ set {
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "Length" field.</summary>
+ public const int LengthFieldNumber = 2;
+ private int length_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int Length {
+ get { return length_; }
+ set {
+ length_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "Color" field.</summary>
+ public const int ColorFieldNumber = 3;
+ private global::Tango.PMR.Common.RGB color_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Tango.PMR.Common.RGB Color {
+ get { return color_; }
+ set {
+ color_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as Segment);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(Segment other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Name != other.Name) return false;
+ if (Length != other.Length) return false;
+ if (!object.Equals(Color, other.Color)) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Name.Length != 0) hash ^= Name.GetHashCode();
+ if (Length != 0) hash ^= Length.GetHashCode();
+ if (color_ != null) hash ^= Color.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 (Name.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Name);
+ }
+ if (Length != 0) {
+ output.WriteRawTag(16);
+ output.WriteInt32(Length);
+ }
+ if (color_ != null) {
+ output.WriteRawTag(26);
+ output.WriteMessage(Color);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Name.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
+ }
+ if (Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(Length);
+ }
+ if (color_ != null) {
+ size += 1 + pb::CodedOutputStream.ComputeMessageSize(Color);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(Segment other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Name.Length != 0) {
+ Name = other.Name;
+ }
+ if (other.Length != 0) {
+ Length = other.Length;
+ }
+ if (other.color_ != null) {
+ if (color_ == null) {
+ color_ = new global::Tango.PMR.Common.RGB();
+ }
+ Color.MergeFrom(other.Color);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Name = input.ReadString();
+ break;
+ }
+ case 16: {
+ Length = input.ReadInt32();
+ break;
+ }
+ case 26: {
+ if (color_ == null) {
+ color_ = new global::Tango.PMR.Common.RGB();
+ }
+ input.ReadMessage(color_);
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual_Studio/Tango.PMR/MessageFactory.cs b/Software/Visual_Studio/Tango.PMR/MessageFactory.cs
new file mode 100644
index 000000000..cc36cbf73
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/MessageFactory.cs
@@ -0,0 +1,125 @@
+using Google.Protobuf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.PMR.Common;
+
+namespace Tango.PMR
+{
+ /// <summary>
+ /// Contains helper class for encoding and decoding PMR messages.
+ /// </summary>
+ public static class MessageFactory
+ {
+ /// <summary>
+ /// Creates a new <see cref="TangoMessage{T}"/>.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public static TangoMessage<T> CreateTangoMessage<T>() where T : IMessage<T>
+ {
+ TangoMessage<T> tango = new TangoMessage<T>(Activator.CreateInstance<T>(), (MessageType)Enum.Parse(typeof(MessageType), typeof(T).Name));
+ return tango;
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="TangoMessage{T}"/>.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public static TangoMessage<T> CreateTangoMessage<T>(T message) where T : IMessage<T>
+ {
+ TangoMessage<T> tango = CreateTangoMessage<T>();
+ tango.Message = message;
+ return tango;
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="TangoMessage{T}"/>.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public static TangoMessage<T> CreateTangoMessage<T>(String token) where T : IMessage<T>
+ {
+ TangoMessage<T> tango = CreateTangoMessage<T>();
+ tango.Container.Token = token;
+ return tango;
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="TangoMessage{T}"/>.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public static TangoMessage<T> CreateTangoMessage<T>(T message, String token) where T : IMessage<T>
+ {
+ TangoMessage<T> tango = CreateTangoMessage<T>(token);
+ tango.Message = message;
+ return tango;
+ }
+
+ /// <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 TangoMessage<T> ParseTangoMessage<T>(byte[] data) where T : IMessage<T>
+ {
+ MessageContainer container = MessageContainer.Parser.ParseFrom(data);
+ MessageParser<T> parser = new MessageParser<T>(() => Activator.CreateInstance<T>());
+ TangoMessage<T> tango = new TangoMessage<T>(parser.ParseFrom(container.Data), container.Type);
+ return tango;
+ }
+
+ /// <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 ParseMessageFromContainer<T>(MessageContainer container) where T : IMessage<T>
+ {
+ MessageParser<T> parser = new MessageParser<T>(() => Activator.CreateInstance<T>());
+ return parser.ParseFrom(container.Data);
+ }
+
+ /// <summary>
+ /// Parses the container.
+ /// </summary>
+ /// <param name="container">The container.</param>
+ /// <returns></returns>
+ public static IMessage ParseMessageFromContainer(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 ParseContainer(byte[] data)
+ {
+ MessageContainer container = MessageContainer.Parser.ParseFrom(data);
+ return container;
+ }
+
+ /// <summary>
+ /// Parses the container partial.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="data">The data.</param>
+ /// <returns></returns>
+ public static MessageContainer ParseContainerJson(byte[] data)
+ {
+ MessageContainer container = MessageContainer.Parser.ParseJson(Encoding.UTF8.GetString(data));
+ return container;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.PMR/NativePMR.cs b/Software/Visual_Studio/Tango.PMR/NativePMR.cs
new file mode 100644
index 000000000..a2788b605
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/NativePMR.cs
@@ -0,0 +1,79 @@
+using Google.Protobuf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+
+namespace Tango.PMR
+{
+ /// <summary>
+ /// Represents a PMR wrapper for invoking native protobuf supported methods.
+ /// </summary>
+ /// <typeparam name="Request">The type of the Request.</typeparam>
+ /// <typeparam name="Response">The type of the Response.</typeparam>
+ public class NativePMR<Request, Response> where Request : IMessage<Request> where Response : IMessage<Response>
+ {
+ private NativeMethodDelegate _nativeMethod;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="NativePMR{Request, Response}"/> class.
+ /// </summary>
+ /// <param name="nativeMethod">The native method.</param>
+ public NativePMR(NativeMethodDelegate nativeMethod)
+ {
+ _nativeMethod = nativeMethod;
+ }
+
+ /// <summary>
+ /// Represents a standard C++ protobuf method delegate.
+ /// </summary>
+ /// <param name="requestArray">The request array.</param>
+ /// <param name="requestArraySize">Size of the request array.</param>
+ /// <param name="resultArray">The result array.</param>
+ /// <returns>The size of the result array.</returns>
+ public delegate int NativeMethodDelegate(IntPtr requestArray, int requestArraySize, ref IntPtr resultArray);
+
+ /// <summary>
+ /// Invokes the native method with the specified request.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <param name="nativeMethod">The native method.</param>
+ /// <returns></returns>
+ public Response Invoke(Request request)
+ {
+ //Serialize the request to byte array.
+ byte[] messageData = request.ToByteArray();
+
+ //Allocate unmanaged array on memory.
+ IntPtr unmanagedArr = Marshal.AllocHGlobal(messageData.Length);
+
+ //Copy the request data to the unmanaged array.
+ Marshal.Copy(messageData, 0, unmanagedArr, messageData.Length);
+
+ //Initialize pointer for pointing to the result array.
+ IntPtr output = IntPtr.Zero;
+
+ //Invoke the native method.
+ int size = _nativeMethod(unmanagedArr, messageData.Length, ref output);
+
+ //Initialize a new byte array for holding the native result.
+ byte[] responseData = new byte[size];
+
+ //Copy the unmanaged byte array result to the managed result array.
+ Marshal.Copy(output, responseData, 0, size);
+
+ //Generate response parser.
+ MessageParser<Response> parser = new MessageParser<Response>(() => Activator.CreateInstance<Response>());
+
+ //Parse the response
+ Response response = parser.ParseFrom(responseData);
+
+ //Free unmanaged memory.
+ Marshal.FreeHGlobal(unmanagedArr);
+
+ return response;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.PMR/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.PMR/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..03126049b
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Protobuf Message Repository")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.PMR/Stubs/CalculateRequest.cs b/Software/Visual_Studio/Tango.PMR/Stubs/CalculateRequest.cs
new file mode 100644
index 000000000..36003965f
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Stubs/CalculateRequest.cs
@@ -0,0 +1,187 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: CalculateRequest.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 CalculateRequest.proto</summary>
+ public static partial class CalculateRequestReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for CalculateRequest.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static CalculateRequestReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "ChZDYWxjdWxhdGVSZXF1ZXN0LnByb3RvEg9UYW5nby5QTVIuU3R1YnMiKAoQ",
+ "Q2FsY3VsYXRlUmVxdWVzdBIJCgFBGAEgASgBEgkKAUIYAiABKAFCGwoZY29t",
+ "LnR3aW5lLnRhbmdvLnBtci5zdHVic2IGcHJvdG8z"));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.CalculateRequest), global::Tango.PMR.Stubs.CalculateRequest.Parser, new[]{ "A", "B" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class CalculateRequest : pb::IMessage<CalculateRequest> {
+ private static readonly pb::MessageParser<CalculateRequest> _parser = new pb::MessageParser<CalculateRequest>(() => new CalculateRequest());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<CalculateRequest> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Stubs.CalculateRequestReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public CalculateRequest() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public CalculateRequest(CalculateRequest other) : this() {
+ a_ = other.a_;
+ b_ = other.b_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public CalculateRequest Clone() {
+ return new CalculateRequest(this);
+ }
+
+ /// <summary>Field number for the "A" field.</summary>
+ public const int AFieldNumber = 1;
+ private double a_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public double A {
+ get { return a_; }
+ set {
+ a_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "B" field.</summary>
+ public const int BFieldNumber = 2;
+ private double b_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public double B {
+ get { return b_; }
+ set {
+ b_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as CalculateRequest);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(CalculateRequest 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 != 0D) hash ^= A.GetHashCode();
+ if (B != 0D) 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 != 0D) {
+ output.WriteRawTag(9);
+ output.WriteDouble(A);
+ }
+ if (B != 0D) {
+ output.WriteRawTag(17);
+ output.WriteDouble(B);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (A != 0D) {
+ size += 1 + 8;
+ }
+ if (B != 0D) {
+ size += 1 + 8;
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(CalculateRequest other) {
+ if (other == null) {
+ return;
+ }
+ if (other.A != 0D) {
+ A = other.A;
+ }
+ if (other.B != 0D) {
+ 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 9: {
+ A = input.ReadDouble();
+ break;
+ }
+ case 17: {
+ B = input.ReadDouble();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual_Studio/Tango.PMR/Stubs/CalculateResponse.cs b/Software/Visual_Studio/Tango.PMR/Stubs/CalculateResponse.cs
new file mode 100644
index 000000000..8d8ca7c44
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Stubs/CalculateResponse.cs
@@ -0,0 +1,159 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: CalculateResponse.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 CalculateResponse.proto</summary>
+ public static partial class CalculateResponseReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for CalculateResponse.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static CalculateResponseReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "ChdDYWxjdWxhdGVSZXNwb25zZS5wcm90bxIPVGFuZ28uUE1SLlN0dWJzIiAK",
+ "EUNhbGN1bGF0ZVJlc3BvbnNlEgsKA1N1bRgBIAEoAUIbChljb20udHdpbmUu",
+ "dGFuZ28ucG1yLnN0dWJzYgZwcm90bzM="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.CalculateResponse), global::Tango.PMR.Stubs.CalculateResponse.Parser, new[]{ "Sum" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class CalculateResponse : pb::IMessage<CalculateResponse> {
+ private static readonly pb::MessageParser<CalculateResponse> _parser = new pb::MessageParser<CalculateResponse>(() => new CalculateResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<CalculateResponse> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Stubs.CalculateResponseReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public CalculateResponse() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public CalculateResponse(CalculateResponse other) : this() {
+ sum_ = other.sum_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public CalculateResponse Clone() {
+ return new CalculateResponse(this);
+ }
+
+ /// <summary>Field number for the "Sum" field.</summary>
+ public const int SumFieldNumber = 1;
+ private double sum_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public double Sum {
+ get { return sum_; }
+ set {
+ sum_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as CalculateResponse);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(CalculateResponse 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 != 0D) 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 != 0D) {
+ output.WriteRawTag(9);
+ output.WriteDouble(Sum);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Sum != 0D) {
+ size += 1 + 8;
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(CalculateResponse other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Sum != 0D) {
+ 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 9: {
+ Sum = input.ReadDouble();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual_Studio/Tango.PMR/Stubs/ProgressRequest.cs b/Software/Visual_Studio/Tango.PMR/Stubs/ProgressRequest.cs
new file mode 100644
index 000000000..1eda06217
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Stubs/ProgressRequest.cs
@@ -0,0 +1,131 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: ProgressRequest.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 ProgressRequest.proto</summary>
+ public static partial class ProgressRequestReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for ProgressRequest.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static ProgressRequestReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "ChVQcm9ncmVzc1JlcXVlc3QucHJvdG8SD1RhbmdvLlBNUi5TdHVicyIRCg9Q",
+ "cm9ncmVzc1JlcXVlc3RCGwoZY29tLnR3aW5lLnRhbmdvLnBtci5zdHVic2IG",
+ "cHJvdG8z"));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.ProgressRequest), global::Tango.PMR.Stubs.ProgressRequest.Parser, null, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class ProgressRequest : pb::IMessage<ProgressRequest> {
+ private static readonly pb::MessageParser<ProgressRequest> _parser = new pb::MessageParser<ProgressRequest>(() => new ProgressRequest());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<ProgressRequest> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Stubs.ProgressRequestReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ProgressRequest() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ProgressRequest(ProgressRequest other) : this() {
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ProgressRequest Clone() {
+ return new ProgressRequest(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as ProgressRequest);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(ProgressRequest other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ 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) {
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(ProgressRequest other) {
+ if (other == null) {
+ return;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual_Studio/Tango.PMR/Stubs/ProgressResponse.cs b/Software/Visual_Studio/Tango.PMR/Stubs/ProgressResponse.cs
new file mode 100644
index 000000000..7ffc4a41d
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Stubs/ProgressResponse.cs
@@ -0,0 +1,159 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: ProgressResponse.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 ProgressResponse.proto</summary>
+ public static partial class ProgressResponseReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for ProgressResponse.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static ProgressResponseReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "ChZQcm9ncmVzc1Jlc3BvbnNlLnByb3RvEg9UYW5nby5QTVIuU3R1YnMiJAoQ",
+ "UHJvZ3Jlc3NSZXNwb25zZRIQCghQcm9ncmVzcxgBIAEoAUIbChljb20udHdp",
+ "bmUudGFuZ28ucG1yLnN0dWJzYgZwcm90bzM="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Stubs.ProgressResponse), global::Tango.PMR.Stubs.ProgressResponse.Parser, new[]{ "Progress" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class ProgressResponse : pb::IMessage<ProgressResponse> {
+ private static readonly pb::MessageParser<ProgressResponse> _parser = new pb::MessageParser<ProgressResponse>(() => new ProgressResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<ProgressResponse> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Stubs.ProgressResponseReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ProgressResponse() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ProgressResponse(ProgressResponse other) : this() {
+ progress_ = other.progress_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ProgressResponse Clone() {
+ return new ProgressResponse(this);
+ }
+
+ /// <summary>Field number for the "Progress" field.</summary>
+ public const int ProgressFieldNumber = 1;
+ private double progress_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public double Progress {
+ get { return progress_; }
+ set {
+ progress_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as ProgressResponse);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(ProgressResponse other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Progress != other.Progress) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Progress != 0D) hash ^= Progress.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 (Progress != 0D) {
+ output.WriteRawTag(9);
+ output.WriteDouble(Progress);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Progress != 0D) {
+ size += 1 + 8;
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(ProgressResponse other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Progress != 0D) {
+ Progress = other.Progress;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 9: {
+ Progress = input.ReadDouble();
+ 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
new file mode 100644
index 000000000..ce84d3877
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj
@@ -0,0 +1,70 @@
+<?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>{E4927038-348D-4295-AAF4-861C58CB3943}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tango.PMR</RootNamespace>
+ <AssemblyName>Tango.PMR</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.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Versioning\GlobalVersionInfo.cs">
+ <Link>GlobalVersionInfo.cs</Link>
+ </Compile>
+ <Compile Include="Common\MessageContainer.cs" />
+ <Compile Include="Common\MessageType.cs" />
+ <Compile Include="Common\RGB.cs" />
+ <Compile Include="Jobs\Job.cs" />
+ <Compile Include="Jobs\Segment.cs" />
+ <Compile Include="MessageFactory.cs" />
+ <Compile Include="NativePMR.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Stubs\CalculateRequest.cs" />
+ <Compile Include="Stubs\CalculateResponse.cs" />
+ <Compile Include="Stubs\ProgressRequest.cs" />
+ <Compile Include="Stubs\ProgressResponse.cs" />
+ <Compile Include="TangoMessage.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>"$(TargetDir)proto-tc.exe" -i "$(SolutionDir)..\PMR\Messages" -o "$(SolutionDir)Tango.PMR" -l CSharp</PreBuildEvent>
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.PMR/TangoMessage.cs b/Software/Visual_Studio/Tango.PMR/TangoMessage.cs
new file mode 100644
index 000000000..dec963e36
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/TangoMessage.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.PMR.Common;
+using Google.Protobuf;
+using System.IO;
+
+namespace Tango.PMR
+{
+ /// <summary>
+ /// Represents a wrapper class for PRM messages.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ 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; }
+
+ /// <summary>
+ /// Gets or sets the message type.
+ /// </summary>
+ public MessageType Type { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TangoMessage{T}"/> class.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <param name="type">The type.</param>
+ public TangoMessage(T message, MessageType type)
+ {
+ Message = message;
+ Type = type;
+
+ Container = new MessageContainer();
+ Container.Token = Guid.NewGuid().ToString();
+ Container.Type = Type;
+ }
+
+ /// <summary>
+ /// Generates a new <see cref="MessageContainer"/> containing the message of type <see cref="T"/> and returns a byte array.
+ /// </summary>
+ /// <returns></returns>
+ public byte[] ToBytes()
+ {
+ Container.Data = Message.ToByteString();
+
+ using (MemoryStream ms = new MemoryStream())
+ {
+ Container.WriteTo(ms);
+ return ms.ToArray();
+ }
+ }
+
+ /// <summary>
+ /// Generates a new <see cref="MessageContainer"/> containing the message of type <see cref="T"/> and returns a byte array.
+ /// </summary>
+ /// <returns></returns>
+ public byte[] ToJsonBytes()
+ {
+ Container.Data = Message.ToByteString();
+ return Encoding.UTF8.GetBytes(Container.ToString());
+ }
+
+ /// <summary>
+ /// Performs an implicit conversion from <see cref="T"/> to <see cref="TangoMessage{T}"/>.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <returns>
+ /// The result of the conversion.
+ /// </returns>
+ public static implicit operator TangoMessage<T>(T message)
+ {
+ var tangoMessage = MessageFactory.CreateTangoMessage<T>();
+ tangoMessage.Message = message;
+ return tangoMessage;
+ }
+
+ /// <summary>
+ /// Performs an implicit conversion from <see cref="TangoMessage{T}"/> to <see cref="T"/>.
+ /// </summary>
+ /// <param name="instance">The instance.</param>
+ /// <returns>
+ /// The result of the conversion.
+ /// </returns>
+ public static implicit operator T (TangoMessage<T> instance)
+ {
+ return instance.Message;
+ }
+
+ /// <summary>
+ /// Performs an implicit conversion from <see cref="System.Byte[]"/> to <see cref="TangoMessage{T}"/>.
+ /// </summary>
+ /// <param name="data">The data.</param>
+ /// <returns>
+ /// The result of the conversion.
+ /// </returns>
+ public static implicit operator TangoMessage<T>(byte[] data)
+ {
+ return MessageFactory.ParseTangoMessage<T>(data);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.PMR/packages.config b/Software/Visual_Studio/Tango.PMR/packages.config
new file mode 100644
index 000000000..e7e6cbade
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.Protobuf" version="3.4.1" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Protobuf/CompilerException.cs b/Software/Visual_Studio/Tango.Protobuf/CompilerException.cs
new file mode 100644
index 000000000..8e50e405e
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/CompilerException.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf
+{
+ /// <summary>
+ /// Represents an <see cref="IProtoCompiler"/> compilation exception.
+ /// </summary>
+ /// <seealso cref="System.Exception" />
+ public class CompilerException : Exception
+ {
+ /// <summary>
+ /// Gets the collection of compilation errors.
+ /// </summary>
+ public List<String> Issues { get; internal set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompilerException"/> class.
+ /// </summary>
+ public CompilerException()
+ {
+ Issues = new List<string>();
+ }
+
+ public override string Message => this.ToString();
+
+ /// <summary>
+ /// Returns a <see cref="System.String" /> that represents this instance.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="System.String" /> that represents this instance.
+ /// </returns>
+ public override string ToString()
+ {
+ return String.Join(Environment.NewLine, Issues);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Protobuf/CompilerFactory.cs b/Software/Visual_Studio/Tango.Protobuf/CompilerFactory.cs
new file mode 100644
index 000000000..7c0ee54a4
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/CompilerFactory.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Logging;
+
+namespace Tango.Protobuf
+{
+ /// <summary>
+ /// Factory class for protobuf compilers.
+ /// </summary>
+ public static class CompilerFactory
+ {
+ /// <summary>
+ /// Creates a protobuf compiler instance by the specified language.
+ /// </summary>
+ /// <param name="language">The language.</param>
+ /// <returns></returns>
+ /// <exception cref="ArgumentException">Could not locate protobuf compiler for language " + language.ToString()</exception>
+ public static IProtoCompiler CreateCompiler(CompilerLanguage language)
+ {
+ LogManager.Log("Generating protobuf compiler for " + language.ToString() + "...");
+
+ foreach (var cType in typeof(CompilerFactory).Assembly.GetTypes().Where(x => x.IsClass && !x.IsAbstract && typeof(IProtoCompiler).IsAssignableFrom(x)))
+ {
+ var instance = Activator.CreateInstance(cType) as IProtoCompiler;
+ if (instance.Language == language) return instance;
+ }
+
+ throw LogManager.Log(new ArgumentException("Could not locate protobuf compiler for language " + language.ToString()));
+ }
+
+ /// <summary>
+ /// Gets a collection of available compilers instance.
+ /// </summary>
+ /// <returns></returns>
+ public static IEnumerable<IProtoCompiler> GetAvailableCompilers()
+ {
+ List<IProtoCompiler> compilers = new List<IProtoCompiler>();
+
+ foreach (var cType in typeof(CompilerFactory).Assembly.GetTypes().Where(x => x.IsClass && !x.IsAbstract && typeof(IProtoCompiler).IsAssignableFrom(x)))
+ {
+ var instance = Activator.CreateInstance(cType) as IProtoCompiler;
+ compilers.Add(instance);
+ }
+
+ return compilers;
+ }
+
+ /// <summary>
+ /// Creates a protobuf compiler instance by the specified language string.
+ /// </summary>
+ /// <param name="language">The language.</param>
+ /// <returns></returns>
+ /// <exception cref="ArgumentException">Could not locate protobuf compiler for language " + language.ToString()</exception>
+ public static IProtoCompiler CreateCompiler(String language)
+ {
+ LogManager.Log("Generating protobuf compiler for " + language.ToString() + "...");
+
+ CompilerLanguage lan = (CompilerLanguage)Enum.Parse(typeof(CompilerLanguage), language, true);
+
+ foreach (var cType in typeof(CompilerFactory).Assembly.GetTypes().Where(x => x.IsClass && !x.IsAbstract && typeof(IProtoCompiler).IsAssignableFrom(x)))
+ {
+ var instance = Activator.CreateInstance(cType) as IProtoCompiler;
+ if (instance.Language == lan) return instance;
+ }
+
+ throw LogManager.Log(new ArgumentException("Could not locate protobuf compiler for language " + language.ToString()));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Protobuf/CompilerFileResult.cs b/Software/Visual_Studio/Tango.Protobuf/CompilerFileResult.cs
new file mode 100644
index 000000000..244ee3857
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/CompilerFileResult.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Logging;
+
+namespace Tango.Protobuf
+{
+ /// <summary>
+ /// Represents an <see cref="IProtoCompiler"/> file compilation result.
+ /// </summary>
+ /// <seealso cref="Tango.Protobuf.ICompilerResult" />
+ public class CompilerFileResult : ICompilerResult
+ {
+ /// <summary>
+ /// Gets the result language.
+ /// </summary>
+ public CompilerLanguage Language { get; private set; }
+
+ /// <summary>
+ /// Gets the result name.
+ /// </summary>
+ public String Name { get; private set; }
+
+ /// <summary>
+ /// Gets the result source path.
+ /// </summary>
+ public String SourcePath { get; private set; }
+
+ /// <summary>
+ /// Gets the file content.
+ /// </summary>
+ public String Content { get; private set; }
+
+ /// <summary>
+ /// Gets or sets the relative file path.
+ /// </summary>
+ internal String RelativePath { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompilerFileResult"/> class.
+ /// </summary>
+ /// <param name="language">The language.</param>
+ /// <param name="sourcePath">The source path.</param>
+ /// <param name="fileName">Name of the file.</param>
+ /// <param name="content">File contents.</param>
+ public CompilerFileResult(CompilerLanguage language, String sourcePath, String fileName, String relativePath, String content)
+ {
+ Language = language;
+ SourcePath = sourcePath;
+ Name = fileName;
+ RelativePath = relativePath;
+ Content = content;
+ }
+
+ /// <summary>
+ /// Saves the result to the specified folder.
+ /// </summary>
+ /// <param name="folder">The folder.</param>
+ public void Save(String folder)
+ {
+ LogManager.Log("Saving " + Path.Combine(folder, Name) + "...");
+
+ Directory.CreateDirectory(folder);
+ File.WriteAllText(Path.Combine(folder, Name), Content);
+ }
+
+ /// <summary>
+ /// Returns a <see cref="System.String" /> that represents this instance.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="System.String" /> that represents this instance.
+ /// </returns>
+ public override string ToString()
+ {
+ return Name;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Protobuf/CompilerFolderResult.cs b/Software/Visual_Studio/Tango.Protobuf/CompilerFolderResult.cs
new file mode 100644
index 000000000..9fa7e7d95
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/CompilerFolderResult.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Logging;
+
+namespace Tango.Protobuf
+{
+ /// <summary>
+ /// Represents an <see cref="IProtoCompiler"/> folder compilation result.
+ /// </summary>
+ /// <seealso cref="Tango.Protobuf.ICompilerResult" />
+ public class CompilerFolderResult : ICompilerResult
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompilerFolderResult"/> class.
+ /// </summary>
+ /// <param name="results">The results.</param>
+ /// <param name="language">The language.</param>
+ /// <param name="sourcePath">The source path.</param>
+ /// <param name="relativePath">The relative path.</param>
+ public CompilerFolderResult(IEnumerable<ICompilerResult> results, CompilerLanguage language, String sourcePath, String relativePath)
+ {
+ Results = results;
+ Language = language;
+ SourcePath = sourcePath;
+ RelativePath = relativePath;
+ Name = Path.GetFileName(sourcePath);
+ }
+
+ /// <summary>
+ /// Gets the compiler results.
+ /// </summary>
+ public IEnumerable<ICompilerResult> Results { get; private set; }
+
+ /// <summary>
+ /// Gets the result language.
+ /// </summary>
+ public CompilerLanguage Language { get; private set; }
+
+ /// <summary>
+ /// Gets the result source path.
+ /// </summary>
+ public String SourcePath { get; private set; }
+
+ /// <summary>
+ /// Gets the result name.
+ /// </summary>
+ public String Name { get; private set; }
+
+ /// <summary>
+ /// Gets the result relative path.
+ /// </summary>
+ public String RelativePath { get; private set; }
+
+ /// <summary>
+ /// Saves the result to the specified folder.
+ /// </summary>
+ /// <param name="folder">The folder.</param>
+ public void Save(string folder)
+ {
+ LogManager.Log("Saving " + folder + "...");
+
+ foreach (var fileResult in Results.OfType<CompilerFileResult>())
+ {
+ fileResult.Save(folder);
+ }
+
+ foreach (var folderResult in Results.OfType<CompilerFolderResult>())
+ {
+ folderResult.Save(Path.Combine(folder, folderResult.RelativePath.TrimStart('\\','\\')));
+ }
+ }
+
+ /// <summary>
+ /// Returns a <see cref="System.String" /> that represents this instance.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="System.String" /> that represents this instance.
+ /// </returns>
+ public override string ToString()
+ {
+ String output = Name + Environment.NewLine + ":";
+
+ foreach (var fileResult in Results.OfType<CompilerFileResult>())
+ {
+ output += fileResult.ToString() + Environment.NewLine;
+ }
+
+ foreach (var folderResult in Results.OfType<CompilerFolderResult>())
+ {
+ output += folderResult.ToString() + Environment.NewLine;
+ }
+
+ return output;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Protobuf/CompilerLanguage.cs b/Software/Visual_Studio/Tango.Protobuf/CompilerLanguage.cs
new file mode 100644
index 000000000..3b4329d38
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/CompilerLanguage.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf
+{
+ /// <summary>
+ /// Represents an enumeration for available protobuf compiler languages.
+ /// </summary>
+ public enum CompilerLanguage
+ {
+ [Description("C#")]
+ CSharp,
+ [Description("Java")]
+ Java,
+ [Description("Java Nano")]
+ JavaNano,
+ [Description("C++")]
+ CPP,
+ [Description("C")]
+ C,
+ [Description("Embedded C")]
+ EmbeddedC,
+ [Description("JavaScript")]
+ JS,
+ [Description("Python")]
+ Python,
+ [Description("PHP")]
+ PHP,
+ [Description("Ruby")]
+ Ruby,
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Protobuf/Compilers/CCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/Compilers/CCompiler.cs
new file mode 100644
index 000000000..18aab84c6
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/Compilers/CCompiler.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf.Compilers
+{
+ /// <summary>
+ /// Represents a protobuf C Compiler.
+ /// </summary>
+ /// <seealso cref="Tango.Protobuf.ProtoCompiler" />
+ public class CCompiler : ProtoCompiler
+ {
+ /// <summary>
+ /// Gets the compiler language.
+ /// </summary>
+ public override CompilerLanguage Language => CompilerLanguage.C;
+
+ /// <summary>
+ /// Gets the protobuf compiler CLI arguments (without input/output files!).
+ /// </summary>
+ /// <returns></returns>
+ protected override string GetProtoArguments()
+ {
+ return "--c_out";
+ }
+
+ /// <summary>
+ /// Gets the protobuf compiler CLI file name (override when using a compiler other than the default 'protoc.exe').
+ /// </summary>
+ /// <returns></returns>
+ /// <remarks>
+ /// The compiler program must be located in the compilers folder.
+ /// </remarks>
+ protected override string GetProtoCompilerName()
+ {
+ return "protoc-c";
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Protobuf/Compilers/CSharpCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/Compilers/CSharpCompiler.cs
new file mode 100644
index 000000000..682dda60c
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/Compilers/CSharpCompiler.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf.Compilers
+{
+ /// <summary>
+ /// Represents a protobuf C# Compiler.
+ /// </summary>
+ /// <seealso cref="Tango.Protobuf.ProtoCompiler" />
+ public class CSharpCompiler : ProtoCompiler
+ {
+ /// <summary>
+ /// Gets the compiler language.
+ /// </summary>
+ public override CompilerLanguage Language => CompilerLanguage.CSharp;
+
+ /// <summary>
+ /// Gets the protobuf compiler CLI arguments (without input/output files!).
+ /// </summary>
+ /// <returns></returns>
+ protected override string GetProtoArguments()
+ {
+ return "--csharp_out";
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Protobuf/Compilers/CppCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/Compilers/CppCompiler.cs
new file mode 100644
index 000000000..e8ea998d5
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/Compilers/CppCompiler.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf.Compilers
+{
+ /// <summary>
+ /// Represents a protobuf C# Compiler.
+ /// </summary>
+ /// <seealso cref="Tango.Protobuf.ProtoCompiler" />
+ public class CppCompiler : ProtoCompiler
+ {
+ /// <summary>
+ /// Gets the compiler language.
+ /// </summary>
+ public override CompilerLanguage Language => CompilerLanguage.CPP;
+
+ /// <summary>
+ /// Gets the protobuf compiler CLI arguments (without input/output files!).
+ /// </summary>
+ /// <returns></returns>
+ protected override string GetProtoArguments()
+ {
+ return "--cpp_out";
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether this compiler uses the default folder structure when generating code.
+ /// </summary>
+ public override bool UsesDefaultStructure => true;
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Protobuf/Compilers/JavaCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/Compilers/JavaCompiler.cs
new file mode 100644
index 000000000..55f0cf77f
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/Compilers/JavaCompiler.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core.Helpers;
+using Tango.Logging;
+
+namespace Tango.Protobuf.Compilers
+{
+ /// <summary>
+ /// Represents a protobuf Java Compiler.
+ /// </summary>
+ /// <seealso cref="Tango.Protobuf.ProtoCompiler" />
+ public class JavaCompiler : ProtoCompiler
+ {
+ /// <summary>
+ /// Gets the compiler language.
+ /// </summary>
+ public override CompilerLanguage Language => CompilerLanguage.Java;
+
+ /// <summary>
+ /// Gets the protobuf compiler CLI arguments (without input/output files!).
+ /// </summary>
+ /// <returns></returns>
+ protected override string GetProtoArguments()
+ {
+ return "--java_out";
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether this compiler uses the default folder structure when generating code.
+ /// </summary>
+ public override bool UsesDefaultStructure => true;
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Protobuf/Compilers/PythonCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/Compilers/PythonCompiler.cs
new file mode 100644
index 000000000..e3c3ebbd7
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/Compilers/PythonCompiler.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf.Compilers
+{
+ /// <summary>
+ /// Represents a protobuf Python Compiler.
+ /// </summary>
+ /// <seealso cref="Tango.Protobuf.ProtoCompiler" />
+ public class PythonCompiler : ProtoCompiler
+ {
+ /// <summary>
+ /// Gets the compiler language.
+ /// </summary>
+ public override CompilerLanguage Language => CompilerLanguage.Python;
+
+ /// <summary>
+ /// Gets the protobuf compiler CLI arguments (without input/output files!).
+ /// </summary>
+ /// <returns></returns>
+ protected override string GetProtoArguments()
+ {
+ return "--python_out";
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Protobuf/ICompilerResult.cs b/Software/Visual_Studio/Tango.Protobuf/ICompilerResult.cs
new file mode 100644
index 000000000..866ce64d0
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/ICompilerResult.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf
+{
+ /// <summary>
+ /// Represents a protobuf compiler result.
+ /// </summary>
+ public interface ICompilerResult
+ {
+ /// <summary>
+ /// Saves the result to the specified folder.
+ /// </summary>
+ /// <param name="folder">The folder.</param>
+ void Save(String folder);
+
+ /// <summary>
+ /// Gets the result language.
+ /// </summary>
+ CompilerLanguage Language { get; }
+
+ /// <summary>
+ /// Gets the result name.
+ /// </summary>
+ String Name { get ; }
+
+ /// <summary>
+ /// Gets the result source path.
+ /// </summary>
+ String SourcePath { get; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Protobuf/IProtoCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/IProtoCompiler.cs
new file mode 100644
index 000000000..db5303515
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/IProtoCompiler.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf
+{
+ /// <summary>
+ /// Represents a protobuf messages compiler.
+ /// </summary>
+ public interface IProtoCompiler : IDisposable
+ {
+ /// <summary>
+ /// Compiles the specified .proto message file.
+ /// </summary>
+ /// <param name="inputFile">.proto file to compile</param>
+ /// <returns>A list of compiled results.</returns>
+ IEnumerable<CompilerFileResult> CompileFile(String inputFile);
+
+ /// <summary>
+ /// Compiles the specified .proto message file asynchronously.
+ /// </summary>
+ /// <param name="inputFile">.proto file to compile</param>
+ /// <returns>A list of compiled results.</returns>
+ Task<IEnumerable<CompilerFileResult>> CompileFileAsync(String inputFile);
+
+ /// <summary>
+ /// Compiles all files in the specified folder recursively.
+ /// </summary>
+ /// <param name="sourceFolder">The source folder</param>
+ /// <returns>Compilation result.</returns>
+ CompilerFolderResult CompileFolder(String sourceFolder);
+
+ /// <summary>
+ /// Compiles all files in the specified folder recursively and asynchronously.
+ /// </summary>
+ /// <param name="sourceFolder">The source folder</param>
+ /// <returns>Compilation result.</returns>
+ Task<CompilerFolderResult> CompileFolderAsync(String sourceFolder);
+
+ /// <summary>
+ /// Gets the compiler language.
+ /// </summary>
+ CompilerLanguage Language { get; }
+
+ /// <summary>
+ /// Gets the proto imports folders.
+ /// </summary>
+ List<String> ImportsFolders { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether this compiler uses the default folder structure when generating code.
+ /// </summary>
+ bool UsesDefaultStructure { get; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Protobuf/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.Protobuf/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..2296973b8
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Protobuf Components")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Protobuf/ProtoCompiler.cs b/Software/Visual_Studio/Tango.Protobuf/ProtoCompiler.cs
new file mode 100644
index 000000000..d2bfde75c
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/ProtoCompiler.cs
@@ -0,0 +1,317 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core.Helpers;
+using Tango.Logging;
+
+namespace Tango.Protobuf
+{
+ /// <summary>
+ /// Represents a protobuf compiler base class.
+ /// </summary>
+ /// <seealso cref="Tango.Protobuf.IProtoCompiler" />
+ public abstract class ProtoCompiler : IProtoCompiler
+ {
+ private const String COMPILERS_FOLDER_NAME = "ProtoCompilers"; //Compilers folder name.
+ protected String _compilersPath; //Compilers folder path.
+
+ /// <summary>
+ /// Gets the compiler language.
+ /// </summary>
+ public abstract CompilerLanguage Language { get; }
+
+ /// <summary>
+ /// Gets the proto imports folders.
+ /// </summary>
+ public List<String> ImportsFolders { get; private set; }
+
+ /// <summary>
+ /// Gets a value indicating whether this compiler uses the default folder structure when generating code.
+ /// </summary>
+ public virtual bool UsesDefaultStructure { get; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ProtoCompiler"/> class.
+ /// </summary>
+ public ProtoCompiler()
+ {
+ ImportsFolders = new List<string>();
+ _compilersPath = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), COMPILERS_FOLDER_NAME);
+ }
+
+ /// <summary>
+ /// Compiles the specified .proto message file.
+ /// </summary>
+ /// <param name="inputFile">.proto file to compile</param>
+ /// <returns>
+ /// A list of compiled results.
+ /// </returns>
+ public virtual IEnumerable<CompilerFileResult> CompileFile(string inputFile)
+ {
+ LogManager.Log("Compiling file " + inputFile);
+
+ String tmpPath = PathHelper.GetTempFolderPath();
+
+ LogManager.Log("Temp path: " + tmpPath);
+
+ String importsString = "--proto_path \"" + Path.GetDirectoryName(inputFile) + "\" ";
+
+ LogManager.Log("Added import string: " + importsString);
+
+ foreach (var path in ImportsFolders)
+ {
+ String importStr = "--proto_path \"" + path + "\" ";
+ importsString += importStr;
+ LogManager.Log("Added import string: " + importStr);
+ }
+
+ Process p = new Process();
+
+ LogManager.Log("Compilers folder path: " + _compilersPath);
+
+ p.StartInfo.WorkingDirectory = _compilersPath;
+ String oldCurrentDirectory = Environment.CurrentDirectory;
+ Environment.CurrentDirectory = _compilersPath;
+ p.StartInfo.FileName = GetProtoCompilerName();
+
+ LogManager.Log("Protobuf executable path: " + p.StartInfo.FileName);
+
+ p.StartInfo.Arguments = String.Format(
+ "{0} {1}=\"{2}\" \"{3}\"",
+ importsString,
+ GetProtoArguments(),
+ tmpPath,
+ inputFile);
+
+ LogManager.Log("Final arguments:\n" + p.StartInfo.Arguments);
+
+ p.StartInfo.CreateNoWindow = true;
+ p.StartInfo.UseShellExecute = false;
+ p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
+
+ p.StartInfo.RedirectStandardError = true;
+ p.StartInfo.RedirectStandardOutput = true;
+
+
+ LogManager.Log("Executing compilation...");
+
+ p.Start();
+ p.WaitForExit(5000);
+
+ Environment.CurrentDirectory = oldCurrentDirectory;
+
+ String error = p.StandardError.ReadToEnd();
+
+ if (!String.IsNullOrWhiteSpace(error))
+ {
+ var lines = error.Split(new[] { '\r', '\n' });
+ throw LogManager.Log(new CompilerException() { Issues = lines.Where(x => x.Length > 0).ToList() });
+ }
+
+ List<CompilerFileResult> results = new List<CompilerFileResult>();
+
+ foreach (var file in Directory.GetFiles(tmpPath, "*.*", SearchOption.AllDirectories))
+ {
+ CompilerFileResult result = new CompilerFileResult(Language, inputFile, Path.GetFileName(file), Path.GetDirectoryName(file).Replace(tmpPath, "").TrimStart('\\', '\\'), File.ReadAllText(file));
+ results.Add(result);
+ }
+
+
+ if (PathHelper.TryDeleteFolder(tmpPath))
+ {
+ LogManager.Log("Removed temp path: " + tmpPath);
+ }
+ else
+ {
+ LogManager.Log("Could not remove temp path: " + tmpPath);
+ }
+
+ LogManager.Log(Path.GetFileName(inputFile) + "compiled!");
+
+ return results;
+ }
+
+ /// <summary>
+ /// Compiles the specified .proto message file asynchronously.
+ /// </summary>
+ /// <param name="inputFile">.proto file to compile</param>
+ /// <returns>
+ /// A list of compiled results.
+ /// </returns>
+ public async Task<IEnumerable<CompilerFileResult>> CompileFileAsync(string inputFile)
+ {
+ return await new Task<IEnumerable<CompilerFileResult>>(() => { return CompileFile(inputFile); });
+ }
+
+ /// <summary>
+ /// Compiles all files in the specified folder recursively.
+ /// </summary>
+ /// <param name="sourceFolder">The source folder</param>
+ /// <returns>
+ /// Compilation result.
+ /// </returns>
+ public virtual CompilerFolderResult CompileFolder(string sourceFolder)
+ {
+ if (!UsesDefaultStructure)
+ {
+ LogManager.Log("Compiling folder: " + sourceFolder);
+
+ ImportsFolders.Clear();
+ ImportsFolders.AddRange(Directory.GetDirectories(sourceFolder, "*.*", SearchOption.AllDirectories));
+ var result = CompileFolder(sourceFolder, sourceFolder);
+
+ LogManager.Log(Path.GetFileName(sourceFolder) + "compiled!");
+
+ return OnPostProcessFolderCompilation(result);
+ }
+ else
+ {
+ return CompileFolderDefault(sourceFolder);
+ }
+ }
+
+ /// <summary>
+ /// Compiles all files in the specified folder recursively.
+ /// </summary>
+ /// <param name="sourceFolder">The source folder</param>
+ /// <returns>
+ /// Compilation result.
+ /// </returns>
+ protected virtual CompilerFolderResult CompileFolder(string rootFolder, string sourceFolder)
+ {
+ List<ICompilerResult> currentFolderResults = new List<ICompilerResult>();
+ CompilerFolderResult currentFolder = new CompilerFolderResult(currentFolderResults, Language, sourceFolder, sourceFolder.Replace(rootFolder, ""));
+
+ foreach (String file in Directory.GetFiles(sourceFolder, "*.proto"))
+ {
+ currentFolderResults.AddRange(CompileFile(file));
+ }
+ foreach (string folder in Directory.GetDirectories(sourceFolder))
+ {
+ if (Directory.GetFiles(folder, "*.proto").Length > 0)
+ {
+ currentFolderResults.Add(CompileFolder(rootFolder, folder));
+ }
+ }
+
+ return currentFolder;
+ }
+
+ /// <summary>
+ /// Compiles all files in the specified folder recursively and asynchronously.
+ /// </summary>
+ /// <param name="sourceFolder">The source folder</param>
+ /// <returns>
+ /// Compilation result.
+ /// </returns>
+ public async Task<CompilerFolderResult> CompileFolderAsync(string sourceFolder)
+ {
+ return await new Task<CompilerFolderResult>(() => { return CompileFolder(sourceFolder); });
+ }
+
+ /// <summary>
+ /// Compiles all files in the specified folder recursively using the default structure.
+ /// </summary>
+ /// <param name="sourceFolder">The source folder</param>
+ /// <returns>
+ /// Compilation result.
+ /// </returns>
+ private CompilerFolderResult CompileFolderDefault(string sourceFolder)
+ {
+ LogManager.Log("Compiling folder: " + sourceFolder);
+
+ Dictionary<string, CompilerFileResult> fileResults = new Dictionary<string, CompilerFileResult>();
+ ImportsFolders.Clear();
+ ImportsFolders.AddRange(Directory.GetDirectories(sourceFolder, "*.*", SearchOption.AllDirectories));
+
+ String tempPath = PathHelper.GetTempFolderPath();
+
+ foreach (var file in Directory.GetFiles(sourceFolder, "*.proto", SearchOption.AllDirectories))
+ {
+ foreach (var fileResult in CompileFile(file))
+ {
+ String targetFolder = Path.Combine(tempPath, fileResult.RelativePath);
+ String targetFile = Path.Combine(targetFolder, fileResult.Name);
+ Directory.CreateDirectory(targetFolder);
+ File.WriteAllText(targetFile, fileResult.Content);
+
+ fileResults.Add(targetFile, fileResult);
+ }
+ }
+
+ var result = CompileFolderDefault(tempPath, tempPath, fileResults);
+
+ PathHelper.TryDeleteFolder(tempPath);
+
+ LogManager.Log(Path.GetFileName(sourceFolder) + "compiled!");
+
+ return OnPostProcessFolderCompilation(result);
+ }
+
+ /// <summary>
+ /// Compiles all files in the specified folder recursively using the default structure.
+ /// </summary>
+ /// <param name="rootFolder"></param>
+ /// <param name="sourceFolder">The source folder</param>
+ /// <returns>
+ /// Compilation result.
+ /// </returns>
+ private CompilerFolderResult CompileFolderDefault(string rootFolder, string sourceFolder, Dictionary<string, CompilerFileResult> fileResults)
+ {
+ List<ICompilerResult> currentFolderResults = new List<ICompilerResult>();
+ CompilerFolderResult currentFolder = new CompilerFolderResult(currentFolderResults, Language, sourceFolder, Path.GetFileName(sourceFolder));
+
+ foreach (String file in Directory.GetFiles(sourceFolder, "*.*"))
+ {
+ currentFolderResults.Add(fileResults[file]);
+ }
+ foreach (string folder in Directory.GetDirectories(sourceFolder))
+ {
+ currentFolderResults.Add(CompileFolderDefault(rootFolder, folder, fileResults));
+ }
+
+ return currentFolder;
+ }
+
+ /// <summary>
+ /// Override in order to manipulate the folder compilation result.
+ /// </summary>
+ /// <param name="result">The result.</param>
+ /// <returns></returns>
+ protected virtual CompilerFolderResult OnPostProcessFolderCompilation(CompilerFolderResult result)
+ {
+ return result;
+ }
+
+ /// <summary>
+ /// Gets the protobuf compiler CLI arguments (without input/output files!).
+ /// </summary>
+ /// <returns></returns>
+ protected abstract String GetProtoArguments();
+
+ /// <summary>
+ /// Gets the protobuf compiler CLI file name (override when using a compiler other than the default 'protoc.exe').
+ /// </summary>
+ /// <remarks>
+ /// The compiler program must be located in the compilers folder.
+ /// </remarks>
+ /// <returns></returns>
+ protected virtual String GetProtoCompilerName()
+ {
+ return "protoc.exe";
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ //TODO: Dispose...
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-1.0M4.jar b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-1.0M4.jar
new file mode 100644
index 000000000..a55611eac
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-1.0M4.jar
Binary files differ
diff --git a/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-c.exe b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-c.exe
new file mode 100644
index 000000000..6c015b17a
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc-c.exe
Binary files differ
diff --git a/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc.exe b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc.exe
new file mode 100644
index 000000000..e69179c0a
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/ProtoCompilers/protoc.exe
Binary files differ
diff --git a/Software/Visual_Studio/Tango.Protobuf/Tango.Protobuf.csproj b/Software/Visual_Studio/Tango.Protobuf/Tango.Protobuf.csproj
new file mode 100644
index 000000000..d2a98eb1a
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Protobuf/Tango.Protobuf.csproj
@@ -0,0 +1,83 @@
+<?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>{40073806-914E-4E78-97AB-FA9639308EBE}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tango.Protobuf</RootNamespace>
+ <AssemblyName>Tango.Protobuf</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="System" />
+ <Reference Include="System.Core" />
+ <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" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Versioning\GlobalVersionInfo.cs">
+ <Link>GlobalVersionInfo.cs</Link>
+ </Compile>
+ <Compile Include="CompilerException.cs" />
+ <Compile Include="CompilerFactory.cs" />
+ <Compile Include="CompilerFolderResult.cs" />
+ <Compile Include="Compilers\CCompiler.cs" />
+ <Compile Include="Compilers\CppCompiler.cs" />
+ <Compile Include="Compilers\CSharpCompiler.cs" />
+ <Compile Include="Compilers\JavaCompiler.cs" />
+ <Compile Include="Compilers\PythonCompiler.cs" />
+ <Compile Include="ICompilerResult.cs" />
+ <Compile Include="ProtoCompiler.cs" />
+ <Compile Include="IProtoCompiler.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="CompilerLanguage.cs" />
+ <Compile Include="CompilerFileResult.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>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="ProtoCompilers\protoc-1.0M4.jar">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="ProtoCompilers\protoc-c.exe">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="ProtoCompilers\protoc.exe">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.SharedUI/Commands/RelayCommand.cs b/Software/Visual_Studio/Tango.SharedUI/Commands/RelayCommand.cs
new file mode 100644
index 000000000..39fe78352
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Commands/RelayCommand.cs
@@ -0,0 +1,128 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Input;
+
+namespace Tango.SharedUI.Commands
+{
+ /// <summary>
+ /// RelayCommand is a very easy-to-use implementation of ICommand. You can use a RelayCommand to expose viewmodel functionality as a command, and
+ /// supply the condition that determines the command's availability. A control in the view bound to a command can execute an available command will</summary>
+ /// update its enabled state in response to the availability of the command.
+ /// <seealso cref="System.Windows.Input.ICommand" />
+ public sealed class RelayCommand : ICommand
+ {
+ #region fields
+ readonly Predicate<object> canExecute;
+ readonly Action<object> execute;
+ #endregion fields
+
+ #region constructors
+ public RelayCommand(Action<object> execute) : this(execute, null) { }
+
+ public RelayCommand(Action<object> execute, Predicate<object> canExecute)
+ {
+ this.execute = execute;
+ this.canExecute = canExecute;
+ }
+
+ public RelayCommand(Action execute)
+ : this((x) => execute())
+ {
+
+ }
+
+ public RelayCommand(Action execute, Predicate<object> canExecute)
+ : this((x) => execute(), canExecute)
+ {
+
+ }
+
+ #endregion constructors
+
+ #region methods
+ public void RaiseCanExecuteChanged()
+ {
+ if (this.CanExecuteChanged != null)
+ {
+ this.CanExecuteChanged(this, EventArgs.Empty);
+ }
+ }
+ #endregion methods
+
+ #region ICommand events
+ public event EventHandler CanExecuteChanged;
+ #endregion ICommand events
+
+ #region ICommand methods
+ public bool CanExecute(object parameter)
+ {
+ return this.canExecute != null ? this.canExecute(parameter) : true;
+ }
+
+ public void Execute(object parameter)
+ {
+ if (this.execute != null)
+ {
+ this.execute(parameter);
+ }
+ }
+ #endregion ICommand methods
+ }
+
+ public sealed class RelayCommand<T> : ICommand
+ {
+ #region fields
+ readonly Predicate<object> canExecute;
+ readonly Action<T> execute;
+ #endregion fields
+
+ #region constructors
+
+ public RelayCommand(Action<T> execute) : this(execute, null) { }
+
+ public RelayCommand(Action<T> execute, Predicate<object> canExecute)
+ {
+ this.execute = execute;
+ this.canExecute = canExecute;
+ }
+
+ public RelayCommand(Action execute)
+ : this((x) => execute())
+ {
+
+ }
+ #endregion constructors
+
+ #region methods
+ public void RaiseCanExecuteChanged()
+ {
+ if (this.CanExecuteChanged != null)
+ {
+ this.CanExecuteChanged(this, EventArgs.Empty);
+ }
+ }
+ #endregion methods
+
+ #region ICommand events
+ public event EventHandler CanExecuteChanged;
+ #endregion ICommand events
+
+ #region ICommand methods
+ public bool CanExecute(object parameter)
+ {
+ return this.canExecute != null ? this.canExecute(parameter) : true;
+ }
+
+ public void Execute(object parameter)
+ {
+ if (this.execute != null)
+ {
+ this.execute((T)parameter);
+ }
+ }
+ #endregion ICommand methods
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml b/Software/Visual_Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml
new file mode 100644
index 000000000..33e3758a5
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml
@@ -0,0 +1,11 @@
+<UserControl x:Class="Tango.SharedUI.Controls.MultiTransitionControl"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ mc:Ignorable="d"
+ d:DesignHeight="300" d:DesignWidth="300" ClipToBounds="True">
+ <Grid x:Name="mainGrid">
+
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml.cs
new file mode 100644
index 000000000..83cb49de2
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Controls/MultiTransitionControl.xaml.cs
@@ -0,0 +1,473 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+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.Animation;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Tango.SharedUI.Controls
+{
+ /// <summary>
+ /// Represents a control for holding a list of content controls and creates transition effects between them.
+ /// </summary>
+ public partial class MultiTransitionControl : UserControl
+ {
+ private int index;
+ private bool freezeAnimation;
+ private ContentControl element1 = null;
+ private ContentControl element2 = null;
+ private ContentControl fromElement;
+ private ContentControl toElement;
+ private Action navigationCompleteAction;
+ private bool _loaded;
+
+ #region Events
+ /// <summary>
+ /// Occurs when the transition has completed.
+ /// </summary>
+ public event Action<MultiTransitionControl> TransitionComplete;
+
+ #endregion
+
+ #region Constructors
+
+ /// <summary>
+ /// Initialize a new instance of MultiTransitionControl.
+ /// </summary>
+ public MultiTransitionControl()
+ {
+ Controls = new List<ContentControl>();
+
+ index = 0;
+ InitializeComponent();
+ this.Loaded += MultiTransitionControl_Loaded;
+ }
+
+ #endregion
+
+ #region Event Handlers
+
+ private void MultiTransitionControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ if (!_loaded)
+ {
+ foreach (ContentControl control in Controls)
+ {
+ control.Visibility = System.Windows.Visibility.Hidden;
+ mainGrid.Children.Add(control);
+ }
+
+ if (Controls.Count > 0)
+ {
+ Controls[0].Visibility = System.Windows.Visibility.Visible;
+ SelectedControl = Controls[0];
+ fromElement = SelectedControl;
+ }
+
+ _loaded = true;
+ }
+ }
+
+ private void ani_BackCompleted(object sender, EventArgs e)
+ {
+ fromElement = toElement;
+ toElement = null;
+ freezeAnimation = true;
+ this.ApplyAnimationClock(MultiTransitionControl.MixProperty, null);
+ Mix = 0;
+ index++;
+ freezeAnimation = false;
+ IsAnimating = false;
+
+ OnTransitionCompleted();
+ }
+
+ private void ani_NextCompleted(object sender, EventArgs e)
+ {
+ fromElement = toElement;
+ toElement = null;
+ freezeAnimation = true;
+ this.ApplyAnimationClock(MultiTransitionControl.MixProperty, null);
+ Mix = 0;
+ index++;
+ freezeAnimation = false;
+ IsAnimating = false;
+
+ OnTransitionCompleted();
+ }
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets the available content controls nested in the MultiTransitionControl.
+ /// </summary>
+ public List<ContentControl> Controls { get; set; }
+
+ /// <summary>
+ /// Gets or sets the transition style.
+ /// </summary>
+ public TransitionTypeEnum TransitionType
+ {
+ get { return (TransitionTypeEnum)GetValue(TransitionTypeProperty); }
+ set { SetValue(TransitionTypeProperty, value); }
+ }
+ public static readonly DependencyProperty TransitionTypeProperty =
+ DependencyProperty.Register("TransitionType", typeof(TransitionTypeEnum), typeof(MultiTransitionControl), new PropertyMetadata(TransitionTypeEnum.Fade) { PropertyChangedCallback = new PropertyChangedCallback(TransitionTypeChanged) });
+ private static void TransitionTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ (d as MultiTransitionControl).ResetTransformation();
+ }
+
+ /// <summary>
+ /// This is where the actual transition occurs.
+ /// </summary>
+ private double Mix
+ {
+ get { return (double)GetValue(MixProperty); }
+ set
+ {
+ SetValue(MixProperty, value);
+ if (!freezeAnimation)
+ {
+ UpdateMix(value);
+ }
+ }
+ }
+ private static readonly DependencyProperty MixProperty =
+ DependencyProperty.Register("Mix", typeof(double), typeof(MultiTransitionControl), new PropertyMetadata(new PropertyChangedCallback(MixChanged)));
+ private static void MixChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ MultiTransitionControl tr = d as MultiTransitionControl;
+ double value = (double)e.NewValue;
+ tr.UpdateMix(value);
+ }
+
+
+ /// <summary>
+ /// Gets or sets whether to always include a cross fade transition along with the selected transition style.
+ /// </summary>
+ public bool AlwaysFade
+ {
+ get { return (bool)GetValue(AlwaysFadeProperty); }
+ set { SetValue(AlwaysFadeProperty, value); }
+ }
+ public static readonly DependencyProperty AlwaysFadeProperty =
+ DependencyProperty.Register("AlwaysFade", typeof(bool), typeof(MultiTransitionControl), new PropertyMetadata(false));
+
+
+ /// <summary>
+ /// Gets or sets the interval in milliseconds for the transition to complete.
+ /// </summary>
+ public int AnimationTime
+ {
+ get { return (int)GetValue(AnimationTimeProperty); }
+ set { SetValue(AnimationTimeProperty, value); }
+ }
+ public static readonly DependencyProperty AnimationTimeProperty =
+ DependencyProperty.Register("AnimationTime", typeof(int), typeof(MultiTransitionControl), new PropertyMetadata(1000));
+
+
+ /// <summary>
+ /// Gets or sets the transition 'ease in' time.
+ /// </summary>
+ public double AnimationAcceleration
+ {
+ get { return (double)GetValue(AnimationAccelerationProperty); }
+ set { SetValue(AnimationAccelerationProperty, value); }
+ }
+ public static readonly DependencyProperty AnimationAccelerationProperty =
+ DependencyProperty.Register("AnimationAcceleration", typeof(double), typeof(MultiTransitionControl), new PropertyMetadata(0.5));
+
+
+ /// <summary>
+ /// Gets or sets the transition 'ease out' time.
+ /// </summary>
+ public double AnimationDeceleration
+ {
+ get { return (double)GetValue(AnimationDecelerationProperty); }
+ set { SetValue(AnimationDecelerationProperty, value); }
+ }
+ public static readonly DependencyProperty AnimationDecelerationProperty =
+ DependencyProperty.Register("AnimationDeceleration", typeof(double), typeof(MultiTransitionControl), new PropertyMetadata(0.5));
+
+
+ /// <summary>
+ /// Gets or sets whether a transition is taking place at the moment.
+ /// </summary>
+ public bool IsAnimating
+ {
+ get { return (bool)GetValue(IsAnimatingProperty); }
+ private set { SetValue(IsAnimatingProperty, value); }
+ }
+ public static readonly DependencyProperty IsAnimatingProperty =
+ DependencyProperty.Register("IsAnimating", typeof(bool), typeof(MultiTransitionControl), new PropertyMetadata(false));
+
+
+ /// <summary>
+ /// Gets or sets currently visible content control.
+ /// </summary>
+ public ContentControl SelectedControl
+ {
+ get { return (ContentControl)GetValue(SelectedControlProperty); }
+ set { SetValue(SelectedControlProperty, value); }
+ }
+ public static readonly DependencyProperty SelectedControlProperty =
+ DependencyProperty.Register("SelectedControl", typeof(ContentControl), typeof(MultiTransitionControl), new PropertyMetadata(null));
+
+ #endregion
+
+ #region Methods
+
+ /// <summary>
+ /// Updates the mix.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ private void UpdateMix(double value)
+ {
+ if (freezeAnimation) return;
+
+ if (element1 == null || element2 == null)
+ {
+ return;
+ }
+
+ element1.Visibility = System.Windows.Visibility.Visible;
+ element2.Visibility = System.Windows.Visibility.Visible;
+
+ if (TransitionType == TransitionTypeEnum.Fade)
+ {
+ element1.RenderTransform = null;
+ element2.RenderTransform = null;
+ element1.Opacity = value;
+ element2.Opacity = 1 - value;
+ return;
+ }
+ else if (TransitionType == TransitionTypeEnum.Slide)
+ {
+ double v = value * 100;
+ v = (v * this.ActualWidth) / 100;
+ element2.RenderTransform = new TranslateTransform(v, 0);
+ element1.RenderTransform = new TranslateTransform(v - this.ActualWidth, 0);
+ }
+ else if (TransitionType == TransitionTypeEnum.Zoom)
+ {
+ element1.RenderTransformOrigin = new Point(0.5, 0.5);
+ element2.RenderTransformOrigin = new Point(0.5, 0.5);
+ element1.RenderTransform = new ScaleTransform(value, value);
+ element2.RenderTransform = new ScaleTransform(1 - value, 1 - value);
+ }
+ else if (TransitionType == TransitionTypeEnum.Spin)
+ {
+ double v = value * 100;
+ v = (v * 360) / 100;
+
+ var group1 = new TransformGroup();
+ group1.Children.Add(new RotateTransform(v));
+ group1.Children.Add(new ScaleTransform(value, value));
+
+ var group2 = new TransformGroup();
+ group2.Children.Add(new RotateTransform(360 - v));
+ group2.Children.Add(new ScaleTransform(1 - value, 1 - value));
+
+ element1.RenderTransform = group1;
+ element2.RenderTransform = group2;
+ }
+ else if (TransitionType == TransitionTypeEnum.Carousel)
+ {
+ double v = value * 100;
+ v = (v * this.ActualWidth) / 100;
+
+ var group1 = new TransformGroup();
+ group1.Children.Add(new ScaleTransform(value, value));
+ group1.Children.Add(new TranslateTransform(v - this.ActualWidth, 0));
+
+ var group2 = new TransformGroup();
+ group2.Children.Add(new TranslateTransform(v * 2, 0));
+ group2.Children.Add(new ScaleTransform(1 - value, 1 - value));
+
+ element1.RenderTransform = group1;
+ element2.RenderTransform = group2;
+ }
+ else if (TransitionType == TransitionTypeEnum.Skew)
+ {
+ double v = value * 100;
+ v = (v * 180) / 100;
+ element2.RenderTransform = new SkewTransform(v, 0);
+ element1.RenderTransform = new SkewTransform(v - 180, 0);
+ }
+ else if (TransitionType == TransitionTypeEnum.Push)
+ {
+ element1.RenderTransformOrigin = new Point(1, 0.5);
+ element2.RenderTransformOrigin = new Point(0, 0.5);
+ element1.RenderTransform = new ScaleTransform(value, 1);
+ element2.RenderTransform = new ScaleTransform(1 - value, 1);
+ }
+ if (AlwaysFade)
+ {
+ element1.Opacity = value;
+ element2.Opacity = 1 - value;
+ }
+ }
+
+ /// <summary>
+ /// Resets the transformation.
+ /// </summary>
+ private void ResetTransformation()
+ {
+ foreach (ContentControl control in Controls)
+ {
+ control.RenderTransformOrigin = new Point(0.5, 0.5);
+ }
+ }
+
+ /// <summary>
+ /// Execute a transition between the current selected control and the specified content control tag.
+ /// </summary>
+ /// <param name="tag">Tag of content control to navigate to.</param>
+ /// <param name="dataContext">DataContext to assign to the specified content control.</param>
+ /// <param name="navigationComplete">Navigation completed callback delegate.</param>
+ public void AutoNavigate(object tag, object dataContext = null, Action navigationComplete = null)
+ {
+ if (IsAnimating)
+ {
+ return;
+ }
+
+ ContentControl control = Controls.SingleOrDefault(x => x.Tag != null && x.Tag.ToString() == tag.ToString());
+
+ if (control == SelectedControl)
+ {
+ return;
+ }
+
+ if (control == null)
+ {
+ throw new Exception("Control with tag '" + tag.ToString() + "' not found! (Transition Control)");
+ }
+
+ if (dataContext != null)
+ {
+ control.DataContext = dataContext;
+ }
+
+ if (Controls.IndexOf(control) > Controls.IndexOf(fromElement))
+ {
+ navigationCompleteAction = navigationComplete;
+ toElement = control;
+ SelectedControl = control;
+ Next();
+ }
+ else if (Controls.IndexOf(control) < Controls.IndexOf(fromElement))
+ {
+ navigationCompleteAction = navigationComplete;
+ toElement = control;
+ SelectedControl = control;
+ Back();
+ }
+ }
+
+ private void Next()
+ {
+ if (IsAnimating)
+ {
+ return;
+ }
+
+ IsAnimating = true;
+
+ if (Controls.IndexOf(toElement) > Controls.IndexOf(fromElement))
+ {
+ element1 = toElement;
+ element2 = fromElement;
+ }
+ else
+ {
+ element1 = fromElement;
+ element2 = toElement;
+ }
+
+ if (element2 == null)
+ {
+ SelectedControl = Controls[0];
+ fromElement = SelectedControl;
+ element2 = fromElement;
+ }
+
+ freezeAnimation = true;
+ this.ApplyAnimationClock(MultiTransitionControl.MixProperty, null);
+ Mix = 0;
+ freezeAnimation = false;
+
+ DoubleAnimation ani = new DoubleAnimation(1, new Duration(TimeSpan.FromMilliseconds(AnimationTime)), FillBehavior.HoldEnd);
+ ani.AccelerationRatio = AnimationAcceleration;
+ ani.DecelerationRatio = AnimationDeceleration;
+ ani.Completed += ani_NextCompleted;
+ this.BeginAnimation(MultiTransitionControl.MixProperty, ani);
+ }
+
+ private void Back()
+ {
+ if (IsAnimating) return;
+
+ IsAnimating = true;
+
+ if (Controls.IndexOf(toElement) > Controls.IndexOf(fromElement))
+ {
+ element1 = toElement;
+ element2 = fromElement;
+ }
+ else
+ {
+ element1 = fromElement;
+ element2 = toElement;
+ }
+
+ freezeAnimation = true;
+ this.ApplyAnimationClock(MultiTransitionControl.MixProperty, null);
+ Mix = 1;
+ freezeAnimation = false;
+
+ DoubleAnimation ani = new DoubleAnimation(0, new Duration(TimeSpan.FromMilliseconds(AnimationTime)), FillBehavior.HoldEnd);
+ ani.Completed += ani_BackCompleted;
+ ani.AccelerationRatio = AnimationAcceleration;
+ ani.DecelerationRatio = AnimationDeceleration;
+ this.BeginAnimation(MultiTransitionControl.MixProperty, ani);
+ }
+
+ #endregion
+
+ #region Virtuals
+
+ /// <summary>
+ /// Called when [transition completed].
+ /// </summary>
+ protected virtual void OnTransitionCompleted()
+ {
+ if (TransitionComplete != null) TransitionComplete(this);
+
+ if (SelectedControl != null)
+ {
+ Panel.SetZIndex(SelectedControl, Controls.Max(x => Panel.GetZIndex(x)) + 1);
+ }
+
+ if (navigationCompleteAction != null)
+ {
+ navigationCompleteAction();
+ navigationCompleteAction = null;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/TransitionTypeEnum.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/TransitionTypeEnum.cs
new file mode 100644
index 000000000..1a57c9d56
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Controls/TransitionTypeEnum.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Tango.SharedUI.Controls
+{
+ /// <summary>
+ /// Represents a MultiTransitionControl transition style.
+ /// </summary>
+ public enum TransitionTypeEnum
+ {
+ /// <summary>
+ /// Generate a cross fade between controls.
+ /// </summary>
+ Fade,
+ /// <summary>
+ /// Generate slide effect from left to right.
+ /// </summary>
+ Slide,
+ /// <summary>
+ /// Generate zoom in/out effect.
+ /// </summary>
+ Zoom,
+ /// <summary>
+ /// Generate twirl effect.
+ /// </summary>
+ Spin,
+ /// <summary>
+ /// Generate a carousel like slide effect.
+ /// </summary>
+ Carousel,
+ /// <summary>
+ /// Skew the controls to place.
+ /// </summary>
+ Skew,
+ /// <summary>
+ /// Generate an effect similar to slide but instead squeeze the controls.
+ /// </summary>
+ Push
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/BooleanInverseConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/BooleanInverseConverter.cs
new file mode 100644
index 000000000..be0d9ed48
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/BooleanInverseConverter.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ /// <summary>
+ /// Represents a binding converter for reversing a boolean value.
+ /// </summary>
+ /// <seealso cref="System.Windows.Data.IValueConverter" />
+ public class BooleanInverseConverter : IValueConverter
+ {
+ /// <summary>
+ /// Converts a value.
+ /// </summary>
+ /// <param name="value">The value produced by the binding source.</param>
+ /// <param name="targetType">The type of the binding target property.</param>
+ /// <param name="parameter">The converter parameter to use.</param>
+ /// <param name="culture">The culture to use in the converter.</param>
+ /// <returns>
+ /// A converted value. If the method returns null, the valid null value is used.
+ /// </returns>
+ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ return !(bool)value;
+ }
+
+ /// <summary>
+ /// Converts a value.
+ /// </summary>
+ /// <param name="value">The value that is produced by the binding target.</param>
+ /// <param name="targetType">The type to convert to.</param>
+ /// <param name="parameter">The converter parameter to use.</param>
+ /// <param name="culture">The culture to use in the converter.</param>
+ /// <returns>
+ /// A converted value. If the method returns null, the valid null value is used.
+ /// </returns>
+ public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ return !(bool)value;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/BooleanToVisibilityConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/BooleanToVisibilityConverter.cs
new file mode 100644
index 000000000..e3b43e7f2
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/BooleanToVisibilityConverter.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ /// <summary>
+ /// Binding converter for standard boolean to visibility and back.
+ /// </summary>
+ public class BooleanToVisibilityConverter : IValueConverter
+ {
+ /// <summary>
+ /// Converts a boolean value to visibility enumeration.
+ /// </summary>
+ /// <param name="value">Boolean value.</param>
+ /// <param name="targetType"></param>
+ /// <param name="parameter"></param>
+ /// <param name="culture"></param>
+ /// <returns></returns>
+ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ if ((bool)value) return Visibility.Visible;
+ return Visibility.Collapsed;
+ }
+
+ /// <summary>
+ /// Converts a visibility enumeration to boolean value.
+ /// </summary>
+ /// <param name="value">Visibility enumeration.</param>
+ /// <param name="targetType"></param>
+ /// <param name="parameter"></param>
+ /// <param name="culture"></param>
+ /// <returns></returns>
+ public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ if ((Visibility)value == Visibility.Visible) return true;
+ else return false;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/BooleanToVisibilityInverseConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/BooleanToVisibilityInverseConverter.cs
new file mode 100644
index 000000000..475d2fca7
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/BooleanToVisibilityInverseConverter.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ /// <summary>
+ /// Inversed binding converter for standard boolean to visibility and back.
+ /// </summary>
+ public class BooleanToVisibilityInverseConverter : IValueConverter
+ {
+ /// <summary>
+ /// Converts a boolean value to visibility enumeration.
+ /// </summary>
+ /// <param name="value">Boolean value.</param>
+ /// <param name="targetType"></param>
+ /// <param name="parameter"></param>
+ /// <param name="culture"></param>
+ /// <returns></returns>
+ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ if ((bool)value) return Visibility.Collapsed;
+ return Visibility.Visible;
+ }
+
+ /// <summary>
+ /// Converts a visibility enumeration to boolean value.
+ /// </summary>
+ /// <param name="value">Visibility enumeration</param>
+ /// <param name="targetType"></param>
+ /// <param name="parameter"></param>
+ /// <param name="culture"></param>
+ /// <returns></returns>
+ public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ if ((Visibility)value == Visibility.Visible) return false;
+ else return true;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/DoubleToIntConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/DoubleToIntConverter.cs
new file mode 100644
index 000000000..15ef23292
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/DoubleToIntConverter.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ internal class DoubleToIntConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return System.Convert.ToDouble(value);
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return System.Convert.ToInt32(value);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/EnumToDescriptionConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/EnumToDescriptionConverter.cs
new file mode 100644
index 000000000..797d5c2e4
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/EnumToDescriptionConverter.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ /// <summary>
+ /// Represents a binding converter for converting enum value to the associated description attribute if found.
+ /// </summary>
+ /// <seealso cref="System.Windows.Data.IValueConverter" />
+ public class EnumToDescriptionConverter : IValueConverter
+ {
+ /// <summary>
+ /// Converts a value.
+ /// </summary>
+ /// <param name="value">The value produced by the binding source.</param>
+ /// <param name="targetType">The type of the binding target property.</param>
+ /// <param name="parameter">The converter parameter to use.</param>
+ /// <param name="culture">The culture to use in the converter.</param>
+ /// <returns>
+ /// A converted value. If the method returns null, the valid null value is used.
+ /// </returns>
+ /// <exception cref="System.NotImplementedException"></exception>
+ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ return GetDescription(value, value.ToString());
+ }
+
+ public static string GetDescription(object enumValue, string defDesc)
+ {
+ FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString());
+
+ if (null != fi)
+ {
+ object[] attrs = fi.GetCustomAttributes(typeof(DescriptionAttribute), true);
+ if (attrs != null && attrs.Length > 0)
+ return ((DescriptionAttribute)attrs[0]).Description;
+ }
+
+ return defDesc;
+ }
+
+ /// <summary>
+ /// Converts a value.
+ /// </summary>
+ /// <param name="value">The value that is produced by the binding target.</param>
+ /// <param name="targetType">The type to convert to.</param>
+ /// <param name="parameter">The converter parameter to use.</param>
+ /// <param name="culture">The culture to use in the converter.</param>
+ /// <returns>
+ /// A converted value. If the method returns null, the valid null value is used.
+ /// </returns>
+ /// <exception cref="System.NotImplementedException"></exception>
+ public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ return value;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/EnumToItemsSourceConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/EnumToItemsSourceConverter.cs
new file mode 100644
index 000000000..1699647bb
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/EnumToItemsSourceConverter.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ internal class EnumToItemsSourceConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ Type result = value as Type;
+ return Enum.GetValues(result).Cast<object>().Select(e => new { Value = e, DisplayName = (e as Enum).ToDescription() });
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/IsEnumConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/IsEnumConverter.cs
new file mode 100644
index 000000000..3404d3ea4
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/IsEnumConverter.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ internal class IsEnumConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ Type t = value as Type;
+ return t.IsEnum;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/IsNullConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/IsNullConverter.cs
new file mode 100644
index 000000000..7c2b3494d
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/IsNullConverter.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ internal class IsNullConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return value == null;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/NullObjectToBooleanConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/NullObjectToBooleanConverter.cs
new file mode 100644
index 000000000..5046ee127
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/NullObjectToBooleanConverter.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ /// <summary>
+ /// Represents a binding converter for returning true for valid object instances and false for null object reference.
+ /// </summary>
+ public class NullObjectToBooleanConverter : IValueConverter
+ {
+ /// <summary>
+ /// Converts a value.
+ /// </summary>
+ /// <param name="value">The value produced by the binding source.</param>
+ /// <param name="targetType">The type of the binding target property.</param>
+ /// <param name="parameter">The converter parameter to use.</param>
+ /// <param name="culture">The culture to use in the converter.</param>
+ /// <returns>
+ /// A converted value. If the method returns null, the valid null value is used.
+ /// </returns>
+ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ if (value != null) return true;
+ return false;
+ }
+
+ /// <summary>
+ /// Converts a value.
+ /// </summary>
+ /// <param name="value">The value that is produced by the binding target.</param>
+ /// <param name="targetType">The type to convert to.</param>
+ /// <param name="parameter">The converter parameter to use.</param>
+ /// <param name="culture">The culture to use in the converter.</param>
+ /// <returns>
+ /// A converted value. If the method returns null, the valid null value is used.
+ /// </returns>
+ public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ return value;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/ParameterItemEditorTypeToEditorConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/ParameterItemEditorTypeToEditorConverter.cs
new file mode 100644
index 000000000..3022ee07e
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/ParameterItemEditorTypeToEditorConverter.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+using Tango.Core;
+using Tango.SharedUI.Editors;
+
+namespace Tango.SharedUI.Converters
+{
+ internal class ParameterItemEditorTypeToEditorConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ try
+ {
+ ParameterItem item = values[0] as ParameterItem;
+
+ if (item != null)
+ {
+ Type editorType = Type.GetType(item.CustomEditorTypeName);
+
+ if (editorType != null)
+ {
+ IParameterItemEditor editor = Activator.CreateInstance(editorType) as IParameterItemEditor;
+ editor.ParameterItem = item;
+ editor.ParameterizedObject = values[1] as IParameterized;
+ return editor;
+ }
+ }
+
+ return null;
+ }
+ catch
+ {
+ return null;
+ }
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/PathToShortPathConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/PathToShortPathConverter.cs
new file mode 100644
index 000000000..f6ef0152a
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/PathToShortPathConverter.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ public class PathToShortPathConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ if (value != null)
+ {
+ String path = value.ToString();
+
+ if (!String.IsNullOrWhiteSpace(path) && path.Length > 10)
+ {
+ return "..\\" + Path.GetFileName(path);
+ }
+ else
+ {
+ return path;
+ }
+ }
+
+ return null;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/StringFormatConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/StringFormatConverter.cs
new file mode 100644
index 000000000..19815f903
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Converters/StringFormatConverter.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace Tango.SharedUI.Converters
+{
+ internal class StringFormatConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ String stringValue = values[0].ToString();
+ String format = values[1] != null ? values[1].ToString() : null;
+ var resultString = Regex.Match(stringValue, @"^-?[0-9]\d*(\.\d+)?$").Value;
+
+ if (String.IsNullOrWhiteSpace(resultString)) return "";
+
+ if (resultString == "-") return resultString;
+
+ return System.Convert.ToDouble(resultString).ToString(format != null ? format : "");
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+ {
+ String resultString;
+
+ if (value.ToString() == "-" || value.ToString() == ".")
+ {
+ resultString = value.ToString() + 0;
+ }
+ else
+ {
+ resultString = Regex.Match(value.ToString(), @"^-?[0-9]\d*(\.\d+)?$").Value;
+ }
+ return new object[] { System.Convert.ToDouble(String.IsNullOrWhiteSpace(resultString) ? "0" : resultString) };
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Editors/IParameterItemEditor.cs b/Software/Visual_Studio/Tango.SharedUI/Editors/IParameterItemEditor.cs
new file mode 100644
index 000000000..2cc117bfd
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Editors/IParameterItemEditor.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+
+namespace Tango.SharedUI.Editors
+{
+ /// <summary>
+ /// Represents a custom <see cref="ParameterItem"/> editor.
+ /// </summary>
+ /// <example>
+ /// <para class="example-title">
+ /// <img class="exampleIcon" src="../Icons/CodeExample.png" />
+ /// <i>
+ /// The following example demonstrates how to implement the IParameterized interface, implement a custom parameter editor and use the ParameterizedEditor to display/edit the object.
+ /// </i>
+ /// </para>
+ /// <para><img class="exampleImage" src="../Media/ParameterizedEditorExample.png" /></para>
+ /// <i>Implement IParameterized.</i>
+ /// <code lang="C#" source="../FullAPIExamples/Examples/Core/IParameterizedExample.cs" title="Implement IParameterized interface." />
+ /// <i>Custom editor.</i>
+ /// <code lang="XAML" source="../FullAPIExamples/Examples/Core/CustomEditor.xaml" title="Implement custom editor." />
+ /// <i>Custom editor code behind.</i>
+ /// <code lang="C#" source="../FullAPIExamples/Examples/Core/CustomEditor.xaml.cs" title="Implement custom editor." />
+ /// <i>Use the ParameterizedEditor to display the parameterized object.</i>
+ /// <code lang="XAML" source="../FullAPIExamples/Examples/Core/ParameterizedEditorExample.xaml" title="Use ParameterizedEditor." />
+ /// <i>Code-Behind.</i>
+ /// <code lang="C#" source="../FullAPIExamples/Examples/Core/ParameterizedEditorExample.xaml.cs" title="Use ParameterizedEditor." />
+ /// </example>
+ /// <seealso cref="IParameterized"/>
+ public interface IParameterItemEditor
+ {
+ /// <summary>
+ /// Gets or sets the parameter item.
+ /// </summary>
+ ParameterItem ParameterItem { get; set; }
+
+ /// <summary>
+ /// Gets or sets the parameterized object.
+ /// </summary>
+ IParameterized ParameterizedObject { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterItemEditor.cs b/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterItemEditor.cs
new file mode 100644
index 000000000..bb0a321f5
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterItemEditor.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using Tango.Core;
+
+namespace Tango.SharedUI.Editors
+{
+ /// <summary>
+ /// Represents a <see cref="ParameterItem"/> editor base class.
+ /// </summary>
+ public class ParameterItemEditor : UserControl, IParameterItemEditor
+ {
+ /// <summary>
+ /// Gets or sets the parameter item.
+ /// </summary>
+ public ParameterItem ParameterItem
+ {
+ get { return (ParameterItem)GetValue(ParameterItemProperty); }
+ set { SetValue(ParameterItemProperty, value); }
+ }
+ public static readonly DependencyProperty ParameterItemProperty =
+ DependencyProperty.Register("ParameterItem", typeof(ParameterItem), typeof(ParameterItemEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the parameterized object.
+ /// </summary>
+ public IParameterized ParameterizedObject
+ {
+ get { return (IParameterized)GetValue(ParameterizedObjectProperty); }
+ set { SetValue(ParameterizedObjectProperty, value); }
+ }
+ public static readonly DependencyProperty ParameterizedObjectProperty =
+ DependencyProperty.Register("ParameterizedObject", typeof(IParameterized), typeof(ParameterItemEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemEditor"/> class.
+ /// </summary>
+ public ParameterItemEditor()
+ {
+ DataContext = ParameterItem;
+ this.Loaded += ParameterItemEditor_Loaded;
+ }
+
+ /// <summary>
+ /// Handles the Loaded event of the ParameterItemEditor control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
+ private void ParameterItemEditor_Loaded(object sender, RoutedEventArgs e)
+ {
+ DataContext = ParameterItem;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml b/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml
new file mode 100644
index 000000000..57bf3f6ff
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml
@@ -0,0 +1,45 @@
+<local:ParameterItemEditor
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Tango.SharedUI.Editors"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters"
+ x:Class="Tango.SharedUI.Editors.ParameterItemNumericUpDownEditor"
+ mc:Ignorable="d" d:DesignHeight="30" d:DesignWidth="150" Background="Transparent" BorderBrush="DimGray" BorderThickness="1">
+
+ <UserControl.Resources>
+ <converters:StringFormatConverter x:Key="StringFormatConverter"/>
+ </UserControl.Resources>
+
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="113*"/>
+ <ColumnDefinition Width="37*" MinWidth="30" />
+ </Grid.ColumnDefinitions>
+
+ <Grid Grid.Column="1">
+ <Grid.RowDefinitions>
+ <RowDefinition/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+
+ <RepeatButton x:Name="btnUp" Style="{x:Null}" Background="#151515" Click="btnUp_Click" Grid.Row="0" Padding="2" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type local:ParameterItemNumericUpDownEditor}}}">
+ <fa:ImageAwesome Icon="ArrowUp" Width="5" Height="5" Foreground="Gainsboro" />
+ </RepeatButton>
+ <RepeatButton x:Name="btnDown" Style="{x:Null}" Background="#151515" Click="btnDown_Click" Grid.Row="1" Padding="2" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type local:ParameterItemNumericUpDownEditor}}}">
+ <fa:ImageAwesome Icon="ArrowDown" Width="5" Height="5" Foreground="Gainsboro" />
+ </RepeatButton>
+ </Grid>
+
+ <Grid>
+ <TextBox x:Name="txtValue" KeyDown="txtValue_KeyDown" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource AncestorType={x:Type local:ParameterItemNumericUpDownEditor}}}" VerticalContentAlignment="Center" Background="Transparent" HorizontalContentAlignment="Center" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type local:ParameterItemNumericUpDownEditor}}}">
+ <MultiBinding Converter="{StaticResource StringFormatConverter}" Mode="TwoWay">
+ <Binding RelativeSource="{RelativeSource AncestorType={x:Type local:ParameterItemNumericUpDownEditor}}" Path="Value" Mode="TwoWay" />
+ <Binding RelativeSource="{RelativeSource AncestorType={x:Type local:ParameterItemNumericUpDownEditor}}" Path="Format"/>
+ </MultiBinding>
+ </TextBox>
+ </Grid>
+ </Grid>
+</local:ParameterItemEditor>
diff --git a/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml.cs b/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml.cs
new file mode 100644
index 000000000..ddc046127
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterItemNumericUpDownEditor.xaml.cs
@@ -0,0 +1,177 @@
+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.SharedUI;
+
+namespace Tango.SharedUI.Editors
+{
+ /// <summary>
+ /// Represents a simple numeric up down editor.
+ /// </summary>
+ public partial class ParameterItemNumericUpDownEditor : ParameterItemEditor
+ {
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterItemNumericUpDownEditor"/> class.
+ /// </summary>
+ public ParameterItemNumericUpDownEditor()
+ {
+ InitializeComponent();
+
+ this.Loaded += ParameterItemNumericUpDownEditor_Loaded;
+ }
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets the value.
+ /// </summary>
+ public double Value
+ {
+ get { return (double)GetValue(ValueProperty); }
+ set { SetValue(ValueProperty, value); }
+ }
+ public static readonly DependencyProperty ValueProperty =
+ DependencyProperty.Register("Value", typeof(double), typeof(ParameterItemNumericUpDownEditor), new PropertyMetadata(0.0, null, (d, value) => { return (d as ParameterItemNumericUpDownEditor).OnCoerceValue((double)value); }));
+
+ /// <summary>
+ /// Gets or sets the minimum value.
+ /// </summary>
+ public double Minimum
+ {
+ get { return (double)GetValue(MinimumProperty); }
+ set { SetValue(MinimumProperty, value); }
+ }
+ public static readonly DependencyProperty MinimumProperty =
+ DependencyProperty.Register("Minimum", typeof(double), typeof(ParameterItemNumericUpDownEditor), new PropertyMetadata(0.0));
+
+ /// <summary>
+ /// Gets or sets the maximum value.
+ /// </summary>
+ public double Maximum
+ {
+ get { return (double)GetValue(MaximumProperty); }
+ set { SetValue(MaximumProperty, value); }
+ }
+ public static readonly DependencyProperty MaximumProperty =
+ DependencyProperty.Register("Maximum", typeof(double), typeof(ParameterItemNumericUpDownEditor), new PropertyMetadata(100.0));
+
+ /// <summary>
+ /// Gets or sets the tick frequency for the up/down buttons.
+ /// </summary>
+ public double Tick
+ {
+ get { return (double)GetValue(TickProperty); }
+ set { SetValue(TickProperty, value); }
+ }
+ public static readonly DependencyProperty TickProperty =
+ DependencyProperty.Register("Tick", typeof(double), typeof(ParameterItemNumericUpDownEditor), new PropertyMetadata(1.0));
+
+ /// <summary>
+ /// Gets or sets the value display format.
+ /// </summary>
+ public String Format
+ {
+ get { return (String)GetValue(FormatProperty); }
+ set { SetValue(FormatProperty, value); }
+ }
+ public static readonly DependencyProperty FormatProperty =
+ DependencyProperty.Register("Format", typeof(String), typeof(ParameterItemNumericUpDownEditor), new PropertyMetadata("0.0"));
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the value is editable through keyboard.
+ /// </summary>
+ public bool IsReadOnly
+ {
+ get { return (bool)GetValue(IsReadOnlyProperty); }
+ set { SetValue(IsReadOnlyProperty, value); }
+ }
+ public static readonly DependencyProperty IsReadOnlyProperty =
+ DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(ParameterItemNumericUpDownEditor), new PropertyMetadata(false));
+
+ #endregion
+
+ #region Virtual Methods
+
+ /// <summary>
+ /// Invoked before the value has changed.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ /// <returns></returns>
+ protected virtual object OnCoerceValue(double value)
+ {
+ if (value > Maximum) return Maximum;
+ if (value < Minimum) return Minimum;
+
+ return value;
+ }
+
+ #endregion
+
+ #region Event Handlers
+
+ /// <summary>
+ /// Handles the Click event of the btnUp control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
+ private void btnUp_Click(object sender, RoutedEventArgs e)
+ {
+ Value += Tick;
+ }
+
+ /// <summary>
+ /// Handles the Click event of the btnDown control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
+ private void btnDown_Click(object sender, RoutedEventArgs e)
+ {
+ Value -= Tick;
+ }
+
+ /// <summary>
+ /// Handles the KeyDown event of the txtValue control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param>
+ private void txtValue_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Enter || e.Key == Key.Escape)
+ {
+ BindingOperations.GetBindingExpressionBase((TextBox)txtValue, TextBox.TextProperty).UpdateSource();
+ }
+ }
+
+ /// <summary>
+ /// Handles the Loaded event of the ParameterItemNumericUpDownEditor control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
+ private void ParameterItemNumericUpDownEditor_Loaded(object sender, RoutedEventArgs e)
+ {
+ if (ParameterItem != null)
+ {
+ Minimum = Convert.ToDouble(ParameterItem.Minimum);
+ Maximum = Convert.ToDouble(ParameterItem.Maximum);
+ this.Bind(ValueProperty, ParameterItem, Tango.Core.ParameterItem.ValueProperty, BindingMode.TwoWay);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml b/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml
new file mode 100644
index 000000000..d80852b73
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml
@@ -0,0 +1,129 @@
+<UserControl x:Class="Tango.SharedUI.Editors.ParameterizedEditor"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Tango.SharedUI.Editors"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
+ mc:Ignorable="d"
+ d:DesignHeight="300" d:DesignWidth="200">
+
+ <UserControl.Resources>
+ <converters:EnumToItemsSourceConverter x:Key="EnumToItemsSourceConverter"></converters:EnumToItemsSourceConverter>
+ <converters:IsEnumConverter x:Key="IsEnumConverter"></converters:IsEnumConverter>
+ <converters:ParameterItemEditorTypeToEditorConverter x:Key="ParameterItemEditorTypeToEditorConverter"></converters:ParameterItemEditorTypeToEditorConverter>
+ <converters:DoubleToIntConverter x:Key="DoubleToIntConverter"></converters:DoubleToIntConverter>
+ <converters:IsNullConverter x:Key="IsNullConverter"></converters:IsNullConverter>
+ </UserControl.Resources>
+
+ <Grid>
+ <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Background="Transparent">
+ <ItemsControl Grid.Row="1" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ParameterizedObject.Parameters}" HorizontalContentAlignment="Stretch">
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <ContentControl Content="{Binding}" Padding="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemPadding}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemMargin}" MinHeight="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemMinHeight}">
+ <ContentControl.Style>
+ <Style TargetType="ContentControl">
+ <Setter Property="ContentTemplate">
+ <Setter.Value>
+ <DataTemplate>
+ <StackPanel>
+ <TextBlock Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <TextBox Text="{Binding Value,UpdateSourceTrigger=PropertyChanged}"></TextBox>
+ </StackPanel>
+ </DataTemplate>
+ </Setter.Value>
+ </Setter>
+ <Style.Resources>
+ <DataTemplate x:Key="slide">
+ <StackPanel>
+ <TextBlock Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <Slider Orientation="Horizontal" HorizontalAlignment="Stretch" Minimum="{Binding Minimum}" Maximum="{Binding Maximum}" Value="{Binding Value}" ToolTip="{Binding Value}"></Slider>
+ </StackPanel>
+ </DataTemplate>
+ <DataTemplate x:Key="slideInteger">
+ <StackPanel>
+ <TextBlock Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <Slider TickFrequency="1" IsSnapToTickEnabled="True" Orientation="Horizontal" HorizontalAlignment="Stretch" Minimum="{Binding Minimum}" Maximum="{Binding Maximum}" Value="{Binding Value,Converter={StaticResource DoubleToIntConverter}}"></Slider>
+ </StackPanel>
+ </DataTemplate>
+ <DataTemplate x:Key="numUpDown">
+ <Grid Margin="0 0 0 4" x:Name="grid">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition/>
+ <ColumnDefinition/>
+ </Grid.ColumnDefinitions>
+ <TextBlock VerticalAlignment="Center" Grid.Column="0" Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <local:ParameterItemNumericUpDownEditor Grid.Column="1" Minimum="-10000" Maximum="10000" Height="25" Value="{Binding RelativeSource={RelativeSource AncestorType=Grid},Path=DataContext.Value,Mode=TwoWay}"></local:ParameterItemNumericUpDownEditor>
+ </Grid>
+ </DataTemplate>
+ <DataTemplate x:Key="enum">
+ <StackPanel Margin="0 0 0 4">
+ <TextBlock Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <ComboBox Foreground="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=Foreground}" ItemsSource="{Binding Type,Converter={StaticResource EnumToItemsSourceConverter},Mode=OneTime}" SelectedValue="{Binding Value}" SelectedValuePath="Value" DisplayMemberPath="DisplayName"></ComboBox>
+ </StackPanel>
+ </DataTemplate>
+ <DataTemplate x:Key="chk">
+ <CheckBox Margin="0 5 0 5" IsChecked="{Binding Value}" Foreground="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=Foreground}" Content="{Binding Name}"></CheckBox>
+ </DataTemplate>
+ <DataTemplate x:Key="text">
+ <StackPanel>
+ <TextBlock Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <TextBox Text="{Binding Value,UpdateSourceTrigger=PropertyChanged}"></TextBox>
+ </StackPanel>
+ </DataTemplate>
+ <DataTemplate x:Key="custom">
+ <StackPanel>
+ <TextBlock Text="{Binding Name}" Margin="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=ItemLabelMargin}"></TextBlock>
+ <ContentPresenter>
+ <ContentPresenter.Content>
+ <MultiBinding Converter="{StaticResource ParameterItemEditorTypeToEditorConverter}">
+ <Binding Path="DataContext" RelativeSource="{RelativeSource AncestorType=StackPanel}"></Binding>
+ <Binding Path="ParameterizedObject" RelativeSource="{RelativeSource AncestorType=local:ParameterizedEditor}"></Binding>
+ </MultiBinding>
+ </ContentPresenter.Content>
+ </ContentPresenter>
+ </StackPanel>
+ </DataTemplate>
+ </Style.Resources>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Type}" Value="{x:Type sys:Double}">
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=DoubleTemplate,FallbackValue={StaticResource slide},TargetNullValue={StaticResource slide}}"></Setter>
+ </DataTrigger>
+ <MultiDataTrigger>
+ <MultiDataTrigger.Conditions>
+ <Condition Binding="{Binding Type}" Value="{x:Type sys:Double}"></Condition>
+ <Condition Binding="{Binding Maximum,Converter={StaticResource IsNullConverter}}" Value="True"></Condition>
+ <Condition Binding="{Binding Minimum,Converter={StaticResource IsNullConverter}}" Value="True"></Condition>
+ </MultiDataTrigger.Conditions>
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=DoubleUpDownTemplate,FallbackValue={StaticResource numUpDown},TargetNullValue={StaticResource numUpDown}}"></Setter>
+ </MultiDataTrigger>
+ <DataTrigger Binding="{Binding Type}" Value="{x:Type sys:Int32}">
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=Int32Template,FallbackValue={StaticResource slideInteger},TargetNullValue={StaticResource slideInteger}}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Type}" Value="{x:Type sys:Single}">
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=SingleTemplate,FallbackValue={StaticResource slide},TargetNullValue={StaticResource slide}}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Type,Converter={StaticResource IsEnumConverter}}" Value="True">
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=EnumTemplate,FallbackValue={StaticResource enum},TargetNullValue={StaticResource enum}}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Type}" Value="{x:Type sys:Boolean}">
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=BooleanTemplate,FallbackValue={StaticResource chk},TargetNullValue={StaticResource chk}}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Type}" Value="{x:Type sys:String}">
+ <Setter Property="ContentTemplate" Value="{Binding RelativeSource={RelativeSource AncestorType=local:ParameterizedEditor},Path=StringTemplate,FallbackValue={StaticResource text},TargetNullValue={StaticResource text}}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding HasCustomEditor}" Value="True">
+ <Setter Property="ContentTemplate" Value="{StaticResource custom}"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </ContentControl.Style>
+ </ContentControl>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </ScrollViewer>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml.cs b/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml.cs
new file mode 100644
index 000000000..f24cdb9af
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Editors/ParameterizedEditor.xaml.cs
@@ -0,0 +1,242 @@
+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.Core;
+using Tango.SharedUI;
+
+namespace Tango.SharedUI.Editors
+{
+ /// <summary>
+ /// <para><img class="classImage" src="../Media/ParameterizedEditor.png" /></para>
+ /// Represents a scrollable list of auto generated editable controls for objects which inherits from <see cref="IParameterized"/>.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// The following types are natively supported for display and edit:
+ /// </para>
+ /// <list type="bullet">
+ /// <item>Double</item>
+ /// <item>Single</item>
+ /// <item>Int32</item>
+ /// <item>Boolean</item>
+ /// <item>String</item>
+ /// <item>Point</item>
+ /// <item>Enum</item>
+ /// <item>Color</item>
+ /// <item>Brush</item>
+ /// </list>
+ /// <para>
+ /// See <see cref="IParameterItemEditor"/> to implement other property types using custom editors.
+ /// </para>
+ /// </remarks>
+ /// <example>
+ /// <para class="example-title">
+ /// <img class="exampleIcon" src="../Icons/CodeExample.png" />
+ /// <i>
+ /// The following example demonstrates how to implement the IParameterized interface, implement a custom parameter editor and use the ParameterizedEditor to display/edit the object.
+ /// </i>
+ /// </para>
+ /// <para><img class="exampleImage" src="../Media/ParameterizedEditorExample.png" /></para>
+ /// <i>Implement IParameterized.</i>
+ /// <code lang="C#" source="../FullAPIExamples/Examples/Core/IParameterizedExample.cs" title="Implement IParameterized interface." />
+ /// <i>Custom editor.</i>
+ /// <code lang="XAML" source="../FullAPIExamples/Examples/Core/CustomEditor.xaml" title="Implement custom editor." />
+ /// <i>Custom editor code behind.</i>
+ /// <code lang="C#" source="../FullAPIExamples/Examples/Core/CustomEditor.xaml.cs" title="Implement custom editor." />
+ /// <i>Use the ParameterizedEditor to display the parameterized object.</i>
+ /// <code lang="XAML" source="../FullAPIExamples/Examples/Core/ParameterizedEditorExample.xaml" title="Use ParameterizedEditor." />
+ /// <i>Code-Behind.</i>
+ /// <code lang="C#" source="../FullAPIExamples/Examples/Core/ParameterizedEditorExample.xaml.cs" title="Use ParameterizedEditor." />
+ /// </example>
+ /// <seealso cref="Tango.SharedUI.HybridControl" />
+ public partial class ParameterizedEditor : UserControl
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ParameterizedEditor"/> class.
+ /// </summary>
+ public ParameterizedEditor()
+ {
+ InitializeComponent();
+ }
+
+ /// <summary>
+ /// Gets or sets the parameterized object.
+ /// </summary>
+ public IParameterized ParameterizedObject
+ {
+ get { return (IParameterized)GetValue(ParameterizedObjectProperty); }
+ set { SetValue(ParameterizedObjectProperty, value); }
+ }
+ public static readonly DependencyProperty ParameterizedObjectProperty =
+ DependencyProperty.Register("ParameterizedObject", typeof(IParameterized), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets a single item padding.
+ /// </summary>
+ public Thickness ItemPadding
+ {
+ get { return (Thickness)GetValue(ItemPaddingProperty); }
+ set { SetValue(ItemPaddingProperty, value); }
+ }
+ public static readonly DependencyProperty ItemPaddingProperty =
+ DependencyProperty.Register("ItemPadding", typeof(Thickness), typeof(ParameterizedEditor), new PropertyMetadata(new Thickness()));
+
+ /// <summary>
+ /// Gets or sets a single item margin.
+ /// </summary>
+ public Thickness ItemMargin
+ {
+ get { return (Thickness)GetValue(ItemMarginProperty); }
+ set { SetValue(ItemMarginProperty, value); }
+ }
+ public static readonly DependencyProperty ItemMarginProperty =
+ DependencyProperty.Register("ItemMargin", typeof(Thickness), typeof(ParameterizedEditor), new PropertyMetadata(new Thickness()));
+
+ /// <summary>
+ /// Gets or sets a single item minimum height.
+ /// </summary>
+ public double ItemMinHeight
+ {
+ get { return (double)GetValue(ItemMinHeightProperty); }
+ set { SetValue(ItemMinHeightProperty, value); }
+ }
+ public static readonly DependencyProperty ItemMinHeightProperty =
+ DependencyProperty.Register("ItemMinHeight", typeof(double), typeof(ParameterizedEditor), new PropertyMetadata(0.0));
+
+ /// <summary>
+ /// Gets or sets a single item label margin.
+ /// </summary>
+ public Thickness ItemLabelMargin
+ {
+ get { return (Thickness)GetValue(ItemLabelMarginProperty); }
+ set { SetValue(ItemLabelMarginProperty, value); }
+ }
+ public static readonly DependencyProperty ItemLabelMarginProperty =
+ DependencyProperty.Register("ItemLabelMargin", typeof(Thickness), typeof(ParameterizedEditor), new PropertyMetadata(new Thickness()));
+
+ #region Templates
+
+ /// <summary>
+ /// Gets or sets the double template.
+ /// </summary>
+ public DataTemplate DoubleTemplate
+ {
+ get { return (DataTemplate)GetValue(DoubleTemplateProperty); }
+ set { SetValue(DoubleTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty DoubleTemplateProperty =
+ DependencyProperty.Register("DoubleTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the int32 template.
+ /// </summary>
+ public DataTemplate Int32Template
+ {
+ get { return (DataTemplate)GetValue(Int32TemplateProperty); }
+ set { SetValue(Int32TemplateProperty, value); }
+ }
+ public static readonly DependencyProperty Int32TemplateProperty =
+ DependencyProperty.Register("Int32Template", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the single template.
+ /// </summary>
+ public DataTemplate SingleTemplate
+ {
+ get { return (DataTemplate)GetValue(SingleTemplateProperty); }
+ set { SetValue(SingleTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty SingleTemplateProperty =
+ DependencyProperty.Register("SingleTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the double up down template.
+ /// </summary>
+ public DataTemplate DoubleUpDownTemplate
+ {
+ get { return (DataTemplate)GetValue(DoubleUpDownTemplateProperty); }
+ set { SetValue(DoubleUpDownTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty DoubleUpDownTemplateProperty =
+ DependencyProperty.Register("DoubleUpDownTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the boolean template.
+ /// </summary>
+ public DataTemplate BooleanTemplate
+ {
+ get { return (DataTemplate)GetValue(BooleanTemplateProperty); }
+ set { SetValue(BooleanTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty BooleanTemplateProperty =
+ DependencyProperty.Register("BooleanTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the enum template.
+ /// </summary>
+ public DataTemplate EnumTemplate
+ {
+ get { return (DataTemplate)GetValue(EnumTemplateProperty); }
+ set { SetValue(EnumTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty EnumTemplateProperty =
+ DependencyProperty.Register("EnumTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the color template.
+ /// </summary>
+ public DataTemplate ColorTemplate
+ {
+ get { return (DataTemplate)GetValue(ColorTemplateProperty); }
+ set { SetValue(ColorTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty ColorTemplateProperty =
+ DependencyProperty.Register("ColorTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the brush template.
+ /// </summary>
+ public DataTemplate BrushTemplate
+ {
+ get { return (DataTemplate)GetValue(BrushTemplateProperty); }
+ set { SetValue(BrushTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty BrushTemplateProperty =
+ DependencyProperty.Register("BrushTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the point template.
+ /// </summary>
+ public DataTemplate PointTemplate
+ {
+ get { return (DataTemplate)GetValue(PointTemplateProperty); }
+ set { SetValue(PointTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty PointTemplateProperty =
+ DependencyProperty.Register("PointTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ /// <summary>
+ /// Gets or sets the string template.
+ /// </summary>
+ public DataTemplate StringTemplate
+ {
+ get { return (DataTemplate)GetValue(StringTemplateProperty); }
+ set { SetValue(StringTemplateProperty, value); }
+ }
+ public static readonly DependencyProperty StringTemplateProperty =
+ DependencyProperty.Register("StringTemplate", typeof(DataTemplate), typeof(ParameterizedEditor), new PropertyMetadata(null));
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/ExtendedObject.cs b/Software/Visual_Studio/Tango.SharedUI/ExtendedObject.cs
new file mode 100644
index 000000000..8e00f2e61
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/ExtendedObject.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.SharedUI.Commands;
+
+namespace Tango.SharedUI
+{
+ /// <summary>
+ /// Represents an extension to the standard core object with support for property and relay commands changed event.
+ /// </summary>
+ /// <seealso cref="System.ComponentModel.INotifyPropertyChanged" />
+ [Serializable]
+ public class ExtendedObject : INotifyPropertyChanged
+ {
+ /// <summary>
+ /// Occurs when a property has changed.
+ /// </summary>
+ [field: NonSerialized]
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ /// <summary>
+ /// Raises the property changed event.
+ /// </summary>
+ /// <param name="propName">Name of the property.</param>
+ protected virtual void RaisePropertyChanged(String propName)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
+ }
+
+ /// <summary>
+ /// Raises all relay commands CanExecute methods in the current instance.
+ /// </summary>
+ protected virtual void InvalidateRelayCommands()
+ {
+ Application.Current.Dispatcher.BeginInvoke(new Action(() =>
+ {
+ foreach (var prop in this.GetType().GetProperties().Where(x => x.PropertyType == typeof(RelayCommand)))
+ {
+ var value = prop.GetValue(this) as RelayCommand;
+
+ if (value != null)
+ {
+ value.RaiseCanExecuteChanged();
+ }
+ }
+ }));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.SharedUI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.SharedUI/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..f30c525cc
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Shared UI Components")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj
new file mode 100644
index 000000000..c04c8692a
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj
@@ -0,0 +1,104 @@
+<?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>{AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tango.SharedUI</RootNamespace>
+ <AssemblyName>Tango.SharedUI</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="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="PresentationCore" />
+ <Reference Include="PresentationFramework" />
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Windows" />
+ <Reference Include="System.Xaml" />
+ <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="Commands\RelayCommand.cs" />
+ <Compile Include="Controls\MultiTransitionControl.xaml.cs">
+ <DependentUpon>MultiTransitionControl.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Controls\TransitionTypeEnum.cs" />
+ <Compile Include="Converters\BooleanInverseConverter.cs" />
+ <Compile Include="Converters\BooleanToVisibilityConverter.cs" />
+ <Compile Include="Converters\BooleanToVisibilityInverseConverter.cs" />
+ <Compile Include="Converters\DoubleToIntConverter.cs" />
+ <Compile Include="Converters\EnumToDescriptionConverter.cs" />
+ <Compile Include="Converters\EnumToItemsSourceConverter.cs" />
+ <Compile Include="Converters\IsEnumConverter.cs" />
+ <Compile Include="Converters\IsNullConverter.cs" />
+ <Compile Include="Converters\NullObjectToBooleanConverter.cs" />
+ <Compile Include="Converters\ParameterItemEditorTypeToEditorConverter.cs" />
+ <Compile Include="Converters\PathToShortPathConverter.cs" />
+ <Compile Include="Converters\StringFormatConverter.cs" />
+ <Compile Include="Editors\IParameterItemEditor.cs" />
+ <Compile Include="Editors\ParameterItemEditor.cs" />
+ <Compile Include="Editors\ParameterItemNumericUpDownEditor.xaml.cs">
+ <DependentUpon>ParameterItemNumericUpDownEditor.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Editors\ParameterizedEditor.xaml.cs">
+ <DependentUpon>ParameterizedEditor.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="ExtendedObject.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Page Include="Controls\MultiTransitionControl.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="Editors\ParameterItemNumericUpDownEditor.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="Editors\ParameterizedEditor.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.SharedUI/packages.config b/Software/Visual_Studio/Tango.SharedUI/packages.config
new file mode 100644
index 000000000..86110f9d8
--- /dev/null
+++ b/Software/Visual_Studio/Tango.SharedUI/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="FontAwesome.WPF" version="4.7.0.9" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Stubs/AvailableStub.cs b/Software/Visual_Studio/Tango.Stubs/AvailableStub.cs
new file mode 100644
index 000000000..64fbfbe9b
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Stubs/AvailableStub.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Transport;
+
+namespace Tango.Stubs
+{
+ public class AvailableStub
+ {
+ public Type Type { get; set; }
+
+ public String Name { get; set; }
+
+ public String Description { get; set; }
+
+ public AvailableStub(Type type, String name, String description)
+ {
+ Type = type;
+ Name = name;
+ Description = description;
+ }
+
+ public StubBase CreateInstance(ITransporter transporter)
+ {
+ return Activator.CreateInstance(Type, transporter) as StubBase;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Stubs/IStub.cs b/Software/Visual_Studio/Tango.Stubs/IStub.cs
new file mode 100644
index 000000000..70629ea8f
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Stubs/IStub.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+
+namespace Tango.Stubs
+{
+ public interface IStub : IParameterized
+ {
+ StubState State { get; }
+ Task<String> Run(Action<String> multiResponseCallback);
+ Task<String> Cancel();
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Stubs/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.Stubs/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..c91630b59
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Stubs/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Stubs Collection")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Stubs/StubAttribute.cs b/Software/Visual_Studio/Tango.Stubs/StubAttribute.cs
new file mode 100644
index 000000000..c7611e606
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Stubs/StubAttribute.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Stubs
+{
+ public class StubAttribute : Attribute
+ {
+ public String Name { get; set; }
+
+ public String Description { get; set; }
+
+ public StubDirection Direction { get; set; }
+
+ public StubAttribute(String name, String description, StubDirection direction)
+ {
+ Name = name;
+ Description = description;
+ Direction = direction;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Stubs/StubBase.cs b/Software/Visual_Studio/Tango.Stubs/StubBase.cs
new file mode 100644
index 000000000..cbeb6d1d3
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Stubs/StubBase.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Logging;
+using Tango.SharedUI;
+using Tango.Transport;
+
+namespace Tango.Stubs
+{
+ public abstract class StubBase : ExtendedObject, IStub
+ {
+ [ParameterIgnore]
+ public ITransporter Transporter { get; set; }
+
+ [ParameterIgnore]
+ public ReadOnlyObservableCollection<ParameterItem> Parameters { get; set; }
+
+ private StubState _state;
+ [ParameterIgnore]
+ public StubState State
+ {
+ get { return _state; }
+ protected set { _state = value; RaisePropertyChanged(nameof(State)); }
+ }
+
+
+ public StubBase(ITransporter transporter)
+ {
+ Transporter = transporter;
+ Parameters = new ReadOnlyObservableCollection<ParameterItem>(this.CreateParametersCollection(ParameterItemMode.Event));
+ }
+
+ public virtual Task<String> Cancel()
+ {
+ return Task<String>.Factory.StartNew(() =>
+ {
+ return "";
+ });
+ }
+
+ public async virtual Task<String> Run(Action<String> multiResponseCallback)
+ {
+ String response = String.Empty;
+
+ try
+ {
+ LogManager.Log("Executing stub " + this.GetType().Name + "...");
+ State = StubState.Running;
+ response = await OnRun(multiResponseCallback);
+ State = StubState.Passed;
+ LogManager.Log("Stub completed successfully.");
+ }
+ catch (Exception ex)
+ {
+ State = StubState.Failed;
+ response = LogManager.Log(ex, "Stub failed.").ToString();
+ }
+
+ return response;
+ }
+
+ protected abstract Task<String> OnRun(Action<String> multiResponseCallback);
+
+ public static List<AvailableStub> GetAvailableStubs(StubDirection direction)
+ {
+ List<AvailableStub> results = new List<AvailableStub>();
+
+ foreach (Type type in Assembly.GetAssembly(typeof(StubBase)).GetTypes().Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(StubBase))))
+ {
+ StubAttribute att = type.GetCustomAttributes(typeof(StubAttribute), true).FirstOrDefault() as StubAttribute;
+
+ if (att.Direction.HasFlag(direction))
+ {
+ AvailableStub availableStub = new AvailableStub(type, att.Name, att.Description);
+ results.Add(availableStub);
+ }
+ }
+
+ return results;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Stubs/StubDirection.cs b/Software/Visual_Studio/Tango.Stubs/StubDirection.cs
new file mode 100644
index 000000000..121818865
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Stubs/StubDirection.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Stubs
+{
+ public enum StubDirection
+ {
+ ToMachine,
+ ToMobile,
+ Both = ToMachine | ToMobile,
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Stubs/StubState.cs b/Software/Visual_Studio/Tango.Stubs/StubState.cs
new file mode 100644
index 000000000..1839bc3dc
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Stubs/StubState.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Stubs
+{
+ public enum StubState
+ {
+ Stopped,
+ Running,
+ Passed,
+ Failed,
+ Canceled,
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Stubs/Stubs/Calculate.cs b/Software/Visual_Studio/Tango.Stubs/Stubs/Calculate.cs
new file mode 100644
index 000000000..e1bea5454
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Stubs/Stubs/Calculate.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Logging;
+using Tango.PMR;
+using Tango.PMR.Stubs;
+using Tango.Transport;
+
+namespace Tango.Stubs.Stubs
+{
+ [Stub("Calculate", "Calculate two numbers and return the result.", StubDirection.Both)]
+ public class Calculate : StubBase
+ {
+ public Calculate(ITransporter transporter) : base(transporter)
+ {
+ }
+
+ [ParameterItem(Minimum = null, Maximum = null)]
+ public double NumberA { get; set; }
+
+ [ParameterItem(Minimum = null, Maximum = null)]
+ public double NumberB { get; set; }
+
+ protected async override Task<string> OnRun(Action<String> multiResponseCallback)
+ {
+ var response = await Transporter.SendRequest<CalculateRequest, CalculateResponse>(
+ new CalculateRequest()
+ {
+ A = NumberA,
+ B = NumberB
+ }
+ );
+
+ return response.Sum.ToString();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Stubs/Stubs/Progress.cs b/Software/Visual_Studio/Tango.Stubs/Stubs/Progress.cs
new file mode 100644
index 000000000..e378791d2
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Stubs/Stubs/Progress.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Logging;
+using Tango.PMR;
+using Tango.PMR.Stubs;
+using Tango.Transport;
+
+namespace Tango.Stubs.Stubs
+{
+ [Stub("Progress", "Check for multiple response request", StubDirection.ToMachine)]
+ public class Progress : StubBase
+ {
+ public Progress(ITransporter transporter) : base(transporter)
+ {
+ }
+
+ protected override Task<string> OnRun(Action<String> multiResponseCallback)
+ {
+ Transporter.SendContinuousRequest<ProgressRequest, ProgressResponse>(MessageFactory.CreateTangoMessage<ProgressRequest>(), (response) =>
+ {
+ multiResponseCallback(response.Progress.ToString());
+ });
+
+ return Task.FromResult<String>("");
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Stubs/Tango.Stubs.csproj b/Software/Visual_Studio/Tango.Stubs/Tango.Stubs.csproj
new file mode 100644
index 000000000..5dadee0ab
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Stubs/Tango.Stubs.csproj
@@ -0,0 +1,93 @@
+<?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>{1981B537-39E9-4E7D-8430-27466481AEEE}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tango.Stubs</RootNamespace>
+ <AssemblyName>Tango.Stubs</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.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Versioning\GlobalVersionInfo.cs">
+ <Link>GlobalVersionInfo.cs</Link>
+ </Compile>
+ <Compile Include="AvailableStub.cs" />
+ <Compile Include="IStub.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="StubDirection.cs" />
+ <Compile Include="Stubs\Progress.cs" />
+ <Compile Include="Stubs\Calculate.cs" />
+ <Compile Include="StubAttribute.cs" />
+ <Compile Include="StubBase.cs" />
+ <Compile Include="StubState.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.Emulations\Tango.Emulations.csproj">
+ <Project>{63561e19-ff5a-414b-a5ef-e30711543e1d}</Project>
+ <Name>Tango.Emulations</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>
+ <ProjectReference Include="..\Tango.Transport\Tango.Transport.csproj">
+ <Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
+ <Name>Tango.Transport</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Stubs/packages.config b/Software/Visual_Studio/Tango.Stubs/packages.config
new file mode 100644
index 000000000..e7e6cbade
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Stubs/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.Protobuf" version="3.4.1" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Transport/Adapters/SplitterAdapter.cs b/Software/Visual_Studio/Tango.Transport/Adapters/SplitterAdapter.cs
new file mode 100644
index 000000000..48b477c39
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/Adapters/SplitterAdapter.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Transport.Adapters
+{
+ public class SplitterAdapter : TransportAdapterBase
+ {
+ public override Task Connect()
+ {
+ throw new NotImplementedException();
+ }
+
+ public override Task Disconnect()
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void Write(byte[] data)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/Adapters/TcpTransportAdapter.cs b/Software/Visual_Studio/Tango.Transport/Adapters/TcpTransportAdapter.cs
new file mode 100644
index 000000000..97757deac
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/Adapters/TcpTransportAdapter.cs
@@ -0,0 +1,198 @@
+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.Transport.Adapters
+{
+ /// <summary>
+ /// Represents an <see cref="ITransportAdapter"/> which communicates over TCP/IP.
+ /// </summary>
+ /// <seealso cref="Tango.Transport.TransportAdapterBase" />
+ public class TcpTransportAdapter : TransportAdapterBase
+ {
+ private TcpClient _socket;
+ private Thread _pullThread;
+ private bool _initializedFromConstructor;
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets the TCP listener port.
+ /// </summary>
+ public int Port { get; set; }
+
+ #endregion
+
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TcpTransportAdapter"/> class.
+ /// </summary>
+ public TcpTransportAdapter()
+ {
+ Address = "127.0.0.1";
+ Port = 9999;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TcpTransportAdapter"/> class.
+ /// </summary>
+ /// <param name="address">The address.</param>
+ /// <param name="port">The port.</param>
+ public TcpTransportAdapter(String address, int port) : this()
+ {
+ Address = address;
+ Port = port;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TcpTransportAdapter"/> class.
+ /// </summary>
+ /// <param name="socket">The socket.</param>
+ public TcpTransportAdapter(TcpClient socket) : this()
+ {
+ _initializedFromConstructor = true;
+ _socket = socket;
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Connects the transport component.
+ /// </summary>
+ /// <returns></returns>
+ public override Task Connect()
+ {
+ ThrowIfDisposed();
+
+ return Task.Factory.StartNew(() =>
+ {
+ try
+ {
+ if (State != TransportComponentState.Connected)
+ {
+ if (!_initializedFromConstructor)
+ {
+ _socket = new TcpClient(Address, Port);
+ }
+
+ State = TransportComponentState.Connected;
+ _pullThread = new Thread(PullThreadMethod);
+ _pullThread.IsBackground = true;
+ _pullThread.Start();
+ LogManager.Log("TCP adapter Connected...");
+ }
+ }
+ catch (Exception ex)
+ {
+ throw LogManager.Log(ex, "Could not connect the TCP adapter.");
+ }
+ });
+ }
+
+ /// <summary>
+ /// Disconnects the transport component.
+ /// </summary>
+ /// <returns></returns>
+ public override Task Disconnect()
+ {
+ return Task.Factory.StartNew((Action)(() =>
+ {
+ try
+ {
+ if (State == TransportComponentState.Connected)
+ {
+ State = TransportComponentState.Disconnected;
+ _socket.GetStream().Close();
+ _socket.Close();
+ LogManager.Log("TCP adapter disconnected.");
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Could not disconnect the TCP adapter.");
+ }
+ }));
+ }
+
+ /// <summary>
+ /// Writes the specified data to the stream.
+ /// </summary>
+ /// <param name="data">The data.</param>
+ public override void Write(byte[] data)
+ {
+ ThrowIfDisposed();
+
+ try
+ {
+ _socket.GetStream().Write(data, 0, data.Length);
+ }
+ catch (Exception ex)
+ {
+ OnFailed(LogManager.Log(ex));
+ }
+ }
+
+ #endregion
+
+ #region Pull Thread
+
+ private void PullThreadMethod()
+ {
+ int counter = 0;
+
+ try
+ {
+ while (State == TransportComponentState.Connected)
+ {
+ if (_socket.Available > 0)
+ {
+ byte[] data = new byte[_socket.Available];
+ _socket.GetStream().Read(data, 0, data.Length);
+ OnDataAvailable(data);
+ }
+
+ Thread.Sleep(10);
+ counter++;
+
+ if (counter >= 200)
+ {
+ try
+ {
+ if (_socket.Client.Poll(1, SelectMode.SelectRead) && _socket.Client.Available == 0)
+ {
+ OnFailed(LogManager.Log(new TimeoutException("Client disconnected.")));
+ return;
+ }
+ }
+ catch (SocketException ex)
+ {
+ OnFailed(LogManager.Log(ex));
+ return;
+ }
+
+ counter = 0;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ OnFailed(ex);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/Adapters/UsbTransportAdapter.cs b/Software/Visual_Studio/Tango.Transport/Adapters/UsbTransportAdapter.cs
new file mode 100644
index 000000000..665f2d779
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/Adapters/UsbTransportAdapter.cs
@@ -0,0 +1,150 @@
+using System;
+using System.Collections.Generic;
+using System.IO.Ports;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.Logging;
+
+namespace Tango.Transport.Adapters
+{
+ /// <summary>
+ /// Represents an <see cref="ITransportAdapter"/> which communicates over USB serial port.
+ /// </summary>
+ /// <seealso cref="Tango.Transport.TransportAdapterBase" />
+ public class UsbTransportAdapter : TransportAdapterBase
+ {
+ private SerialPort _serialPort; //Serial port instance used to communicate over the serial port.
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="UsbTransportAdapter"/> class.
+ /// </summary>
+ public UsbTransportAdapter()
+ {
+ Address = "COM1";
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="UsbTransportAdapter"/> class.
+ /// </summary>
+ /// <param name="portName">The COM.</param>
+ public UsbTransportAdapter(String portName) : base()
+ {
+ Address = portName;
+ }
+
+ /// <summary>
+ /// Connects the transport component.
+ /// </summary>
+ /// <returns></returns>
+ public override Task Connect()
+ {
+ ThrowIfDisposed();
+
+ return Task.Factory.StartNew(() =>
+ {
+ try
+ {
+ if (State != TransportComponentState.Connected)
+ {
+ LogManager.Log("Connecting USB adapter on port " + Address + "...");
+
+ if (_serialPort != null)
+ {
+ _serialPort.DataReceived -= OnSerialPortDataReceived;
+ }
+
+ _serialPort = new SerialPort();
+ _serialPort.DataReceived += OnSerialPortDataReceived;
+ _serialPort.PortName = Address;
+ _serialPort.Open();
+ _serialPort.DiscardInBuffer();
+ _serialPort.DiscardOutBuffer();
+ State = TransportComponentState.Connected;
+
+ LogManager.Log("USB adapter connected.");
+ }
+ }
+ catch (Exception ex)
+ {
+ throw LogManager.Log(ex, "Could not open serial port on " + Address + ".");
+ }
+ });
+ }
+
+ /// <summary>
+ /// Disconnects the transport component.
+ /// </summary>
+ /// <returns></returns>
+ public override Task Disconnect()
+ {
+ ThrowIfDisposed();
+
+ return Task.Factory.StartNew(() =>
+ {
+ try
+ {
+ if (State == TransportComponentState.Connected)
+ {
+ LogManager.Log("Disconnecting USB adapter on port " + Address + "...");
+
+ if (_serialPort != null)
+ {
+ _serialPort.DataReceived -= OnSerialPortDataReceived;
+ }
+
+ _serialPort.DiscardOutBuffer();
+ _serialPort.DiscardInBuffer();
+ _serialPort.Close();
+ State = TransportComponentState.Disconnected;
+ LogManager.Log("USB adapter disconnected.");
+ }
+ }
+ catch (Exception ex)
+ {
+ throw LogManager.Log(ex, "Could not close serial port on " + Address + ".");
+ }
+ });
+ }
+
+ /// <summary>
+ /// Writes the specified data to the stream.
+ /// </summary>
+ /// <param name="data">The data.</param>
+ public override void Write(byte[] data)
+ {
+ ThrowIfDisposed();
+
+ try
+ {
+ _serialPort.Write(data, 0, data.Length);
+ }
+ catch (Exception ex)
+ {
+ OnFailed(LogManager.Log(ex));
+ }
+ }
+
+ /// <summary>
+ /// Called when internal serial port has received data.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="e">The <see cref="SerialDataReceivedEventArgs"/> instance containing the event data.</param>
+ protected virtual void OnSerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
+ {
+ try
+ {
+ if (e.EventType == SerialData.Eof) return;
+ Thread.Sleep(10);
+ byte[] data = new byte[_serialPort.BytesToRead];
+ _serialPort.Read(data, 0, data.Length);
+ OnDataAvailable(data);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error occurred while trying to read from serial port.");
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/ITransportAdapter.cs b/Software/Visual_Studio/Tango.Transport/ITransportAdapter.cs
new file mode 100644
index 000000000..b0e055cde
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/ITransportAdapter.cs
@@ -0,0 +1,33 @@
+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.Transport
+{
+ /// <summary>
+ /// Represents a transport adapter capable of connecting, writing and receiving data from a serial stream.
+ /// </summary>
+ /// <seealso cref="Tango.Transport.ITransportComponent" />
+ public interface ITransportAdapter : ITransportComponent
+ {
+ /// <summary>
+ /// Writes the specified data to the stream.
+ /// </summary>
+ /// <param name="data">The data.</param>
+ void Write(byte[] data);
+
+ /// <summary>
+ /// Occurs when new data is available.
+ /// </summary>
+ event EventHandler<byte[]> DataAvailable;
+
+ /// <summary>
+ /// Gets or sets the channel address.
+ /// </summary>
+ String Address { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/ITransportComponent.cs b/Software/Visual_Studio/Tango.Transport/ITransportComponent.cs
new file mode 100644
index 000000000..06207ddf9
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/ITransportComponent.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Transport
+{
+ /// <summary>
+ /// Represents a transport component.
+ /// </summary>
+ public interface ITransportComponent : IDisposable
+ {
+ /// <summary>
+ /// Connects the transport component.
+ /// </summary>
+ /// <returns></returns>
+ Task Connect();
+ /// <summary>
+ /// Disconnects the transport component.
+ /// </summary>
+ /// <returns></returns>
+ Task Disconnect();
+ /// <summary>
+ /// Occurs when component state changes.
+ /// </summary>
+ event EventHandler<TransportComponentState> StateChanged;
+ /// <summary>
+ /// Gets the component state.
+ /// </summary>
+ TransportComponentState State { get; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/ITransporter.cs b/Software/Visual_Studio/Tango.Transport/ITransporter.cs
new file mode 100644
index 000000000..07b7dd554
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/ITransporter.cs
@@ -0,0 +1,95 @@
+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.Transport.Adapters;
+using Tango.PMR;
+using Tango.PMR.Common;
+using System.Collections.ObjectModel;
+
+namespace Tango.Transport
+{
+ /// <summary>
+ /// Represents a transportation engine which can send and receive <see cref="TangoMessage{T}"/> message using one or many <see cref="ITransportAdapter">Transport adapters</see>.
+ /// </summary>
+ /// <seealso cref="Tango.Transport.ITransportComponent" />
+ public interface ITransporter : ITransportComponent
+ {
+ /// <summary>
+ /// Gets the serial adapter.
+ /// </summary>
+ ObservableCollection<ITransportAdapter> Adapters { get; }
+
+ /// <summary>
+ /// Sends a broadcast request to through all adapters.
+ /// </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>
+ Task<Response> SendRequest<Request, Response>(TangoMessage<Request> request) where Request : IMessage<Request> where Response : IMessage<Response>;
+
+ /// <summary>
+ /// Sends a request through the specified adapter.
+ /// </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>
+ /// <param name="adapter">Transport adapter</param>
+ /// <returns></returns>
+ Task<Response> SendRequest<Request, Response>(TangoMessage<Request> request, ITransportAdapter adapter) where Request : IMessage<Request> where Response : IMessage<Response>;
+
+ /// <summary>
+ /// Sends a request through all adapters which is expected to return multiple response messages.
+ /// </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>
+ /// <param name="adapter">Transport adapter</param>
+ /// <param name="responseCallback">The response callback delegate.</param>
+ /// <returns></returns>
+ void SendContinuousRequest<Request, Response>(TangoMessage<Request> request, Action<Response> responseCallback) where Request : IMessage<Request> where Response : IMessage<Response>;
+
+ /// <summary>
+ /// Sends a request through the specified adapter which is expected to return multiple response messages.
+ /// </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>
+ /// <param name="adapter">Transport adapter</param>
+ /// <param name="responseCallback">The response callback delegate.</param>
+ /// <returns></returns>
+ void SendContinuousRequest<Request, Response>(TangoMessage<Request> request, ITransportAdapter adapter, Action<Response> responseCallback) 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>
+ Task SendResponse<Response>(TangoMessage<Response> response) where Response : IMessage<Response>;
+
+ /// <summary>
+ /// Sends a response for the specified token.
+ /// </summary>
+ /// <typeparam name="Response">The type of the response.</typeparam>
+ /// <param name="response">The response.</param>
+ /// <param name="token">The token.</param>
+ /// <returns></returns>
+ Task SendResponse<Response>(TangoMessage<Response> response,String token) where Response : IMessage<Response>;
+
+ /// <summary>
+ /// Occurs when a new request message has been received.
+ /// </summary>
+ event EventHandler<MessageContainer> RequestReceived;
+
+ /// <summary>
+ /// Gets or sets the request timeout.
+ /// </summary>
+ TimeSpan RequestTimeout { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/PendingResponse.cs b/Software/Visual_Studio/Tango.Transport/PendingResponse.cs
new file mode 100644
index 000000000..bb9718b19
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/PendingResponse.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Transport
+{
+ /// <summary>
+ /// Represents a pending response waiting to be returned to the request sender.
+ /// </summary>
+ public class PendingResponse
+ {
+ /// <summary>
+ /// Gets or sets the adapter target response adapter.
+ /// </summary>
+ public ITransportAdapter Adapter { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this is a continuous request.
+ /// </summary>
+ public bool IsContinuous { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PendingResponse"/> class.
+ /// </summary>
+ /// <param name="adapter">The adapter.</param>
+ /// <param name="isContinuous">if set to <c>true</c> [is continuous].</param>
+ public PendingResponse(ITransportAdapter adapter,bool isContinuous)
+ {
+ Adapter = adapter;
+ IsContinuous = isContinuous;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.Transport/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..9a309793f
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Transport Components")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Transport/Servers/ClientConnectedEventArgs.cs b/Software/Visual_Studio/Tango.Transport/Servers/ClientConnectedEventArgs.cs
new file mode 100644
index 000000000..976a749cc
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/Servers/ClientConnectedEventArgs.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Transport.Servers
+{
+ /// <summary>
+ /// Represents a <see cref="TcpServer"/> new client event arguments.
+ /// </summary>
+ /// <seealso cref="System.EventArgs" />
+ public class ClientConnectedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets or sets the new socket.
+ /// </summary>
+ public TcpClient Socket { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ClientConnectedEventArgs"/> class.
+ /// </summary>
+ /// <param name="socket">The socket.</param>
+ public ClientConnectedEventArgs(TcpClient socket)
+ {
+ Socket = socket;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/Servers/TcpServer.cs b/Software/Visual_Studio/Tango.Transport/Servers/TcpServer.cs
new file mode 100644
index 000000000..8ce79757a
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/Servers/TcpServer.cs
@@ -0,0 +1,124 @@
+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.Transport.Servers
+{
+ /// <summary>
+ /// Represents a TCP/IP listener wrapper.
+ /// </summary>
+ 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));
+ WaitForConnection();
+ }
+ catch (ObjectDisposedException ex)
+ {
+ //Ignore..
+ }
+ }
+ }
+
+ #endregion
+
+ #region Virtual Methods
+
+ protected virtual void OnClientConnected(TcpClient socket)
+ {
+ LogManager.Log("New client connected.");
+
+ Task.Factory.StartNew(() =>
+ {
+
+ ClientConnected?.Invoke(this, new ClientConnectedEventArgs(socket));
+
+ },CancellationToken.None,TaskCreationOptions.None,scheduler);
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj
new file mode 100644
index 000000000..54c7565cf
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj
@@ -0,0 +1,107 @@
+<?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>{74E700B0-1156-4126-BE40-EE450D3C3026}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tango.Transport</RootNamespace>
+ <AssemblyName>Tango.Transport</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\SplitterAdapter.cs" />
+ <Compile Include="Adapters\UsbTransportAdapter.cs" />
+ <Compile Include="ITransportComponent.cs" />
+ <Compile Include="ITransportAdapter.cs" />
+ <Compile Include="Adapters\TcpTransportAdapter.cs" />
+ <Compile Include="PendingResponse.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ITransporter.cs" />
+ <Compile Include="Servers\ClientConnectedEventArgs.cs" />
+ <Compile Include="Servers\TcpServer.cs" />
+ <Compile Include="TransportAdapterBase.cs" />
+ <Compile Include="TransportComponentState.cs" />
+ <Compile Include="TransporterBase.cs" />
+ <Compile Include="Transporters\JsonTransporter.cs" />
+ <Compile Include="Transporters\ProtoTransporter.cs" />
+ <Compile Include="TransportMessage.cs" />
+ <Compile Include="TransportMessageBase.cs" />
+ <Compile Include="TransportMessageDirection.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>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Transport/TransportAdapterBase.cs b/Software/Visual_Studio/Tango.Transport/TransportAdapterBase.cs
new file mode 100644
index 000000000..670ef20c3
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/TransportAdapterBase.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Logging;
+
+namespace Tango.Transport
+{
+ /// <summary>
+ /// Represents an <see cref="ITransportAdapter"/> base class.
+ /// </summary>
+ /// <seealso cref="Tango.Transport.ITransportAdapter" />
+ public abstract class TransportAdapterBase : ITransportAdapter
+ {
+ #region Events
+
+ /// <summary>
+ /// Occurs when component state changes.
+ /// </summary>
+ public event EventHandler<TransportComponentState> StateChanged;
+
+ /// <summary>
+ /// Occurs when new data is available.
+ /// </summary>
+ public event EventHandler<byte[]> DataAvailable;
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets the channel address.
+ /// </summary>
+ public String Address { get; set; }
+
+ private TransportComponentState _state;
+ /// <summary>
+ /// Gets the component state.
+ /// </summary>
+ public TransportComponentState State
+ {
+ get { return _state; }
+ protected set
+ {
+ _state = value;
+ OnStateChanged(_state);
+ }
+ }
+
+ #endregion
+
+ #region Virtual Methods
+
+ /// <summary>
+ /// Called when the adapter has failed.
+ /// </summary>
+ /// <param name="ex">The ex.</param>
+ protected virtual void OnFailed(Exception ex)
+ {
+ Disconnect().Wait();
+ State = TransportComponentState.Failed;
+ LogManager.Log(ex, "Adapter failed.");
+ }
+
+ /// <summary>
+ /// Called when there is new data available.
+ /// </summary>
+ /// <param name="data">The data.</param>
+ protected virtual void OnDataAvailable(byte[] data)
+ {
+ DataAvailable?.Invoke(this, data);
+ }
+
+ /// <summary>
+ /// Called when the adapter state has changed.
+ /// </summary>
+ /// <param name="state">The state.</param>
+ protected virtual void OnStateChanged(TransportComponentState state)
+ {
+ StateChanged?.Invoke(this, state);
+ }
+
+ /// <summary>
+ /// Throws an exception if adapter is in a failed or disposed state.
+ /// </summary>
+ protected virtual void ThrowIfDisposed()
+ {
+ if (State == TransportComponentState.Disposed)
+ {
+ throw LogManager.Log(new ObjectDisposedException("The adapter is in a " + State + " state."));
+ }
+ }
+
+ #endregion
+
+ #region Dispose
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public virtual void Dispose()
+ {
+ Disconnect().Wait();
+ State = TransportComponentState.Disposed;
+ }
+
+ #endregion
+
+ #region Abstract Methods
+
+ /// <summary>
+ /// Writes the specified data to the stream.
+ /// </summary>
+ /// <param name="data">The data.</param>
+ public abstract void Write(byte[] data);
+
+ /// <summary>
+ /// Connects the transport component.
+ /// </summary>
+ /// <returns></returns>
+ public abstract Task Connect();
+
+ /// <summary>
+ /// Disconnects the transport component.
+ /// </summary>
+ /// <returns></returns>
+ public abstract Task Disconnect();
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/TransportComponentState.cs b/Software/Visual_Studio/Tango.Transport/TransportComponentState.cs
new file mode 100644
index 000000000..6764876a0
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/TransportComponentState.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Transport
+{
+ /// <summary>
+ /// Represents a <see cref="ITransportComponent"/> state.
+ /// </summary>
+ public enum TransportComponentState
+ {
+ /// <summary>
+ /// Disconnected.
+ /// </summary>
+ Disconnected,
+ /// <summary>
+ /// Started.
+ /// </summary>
+ Connected,
+ /// <summary>
+ /// Failed.
+ /// </summary>
+ Failed,
+ /// <summary>
+ /// Disposed.
+ /// </summary>
+ Disposed,
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/TransportMessage.cs b/Software/Visual_Studio/Tango.Transport/TransportMessage.cs
new file mode 100644
index 000000000..90e600a06
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/TransportMessage.cs
@@ -0,0 +1,62 @@
+using Google.Protobuf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.PMR;
+
+namespace Tango.Transport
+{
+ /// <summary>
+ /// Represents a generic transport message.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <seealso cref="Tango.Transport.TransportMessageBase" />
+ public class TransportMessage<T> : TransportMessageBase
+ {
+ private TaskCompletionSource<T> _completionSource;
+
+ public Action<T> ResponseCallback { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TransportMessage{T}"/> class.
+ /// </summary>
+ /// <param name="token">The token.</param>
+ /// <param name="message">The message.</param>
+ /// <param name="direction">The direction.</param>
+ /// <param name="toBytes">To bytes.</param>
+ /// <param name="completionSource">The completion source.</param>
+ public TransportMessage(ITransportAdapter adapter, string token, object message, TransportMessageDirection direction, Func<byte[]> toBytes, TaskCompletionSource<T> completionSource) : base(adapter, token, message, direction, toBytes)
+ {
+ _completionSource = completionSource;
+ }
+
+ /// <summary>
+ /// Notifies the message observer of the new result.
+ /// </summary>
+ /// <param name="result">The result.</param>
+ public override void SetResult(object result, bool completed)
+ {
+ _completionSource.SetResult((T)result);
+ }
+
+ /// <summary>
+ /// Notifies the message observer of an exception.
+ /// </summary>
+ /// <param name="ex">The ex.</param>
+ public override void SetException(Exception ex)
+ {
+ _completionSource.SetException(ex);
+ }
+
+ /// <summary>
+ /// Invokes the response callback.
+ /// </summary>
+ /// <param name="response">The response.</param>
+ public override void InvokeResponseCallback(object response, bool completed)
+ {
+ ResponseCallback((T)response);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/TransportMessageBase.cs b/Software/Visual_Studio/Tango.Transport/TransportMessageBase.cs
new file mode 100644
index 000000000..c9202efc6
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/TransportMessageBase.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Transport
+{
+ /// <summary>
+ /// Represents a base transport message.
+ /// </summary>
+ public abstract class TransportMessageBase
+ {
+ /// <summary>
+ /// Gets or sets the source/destination adapter.
+ /// </summary>
+ public ITransportAdapter Adapter { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance is multi response.
+ /// </summary>
+ public bool IsContinuous { get; set; }
+
+ /// <summary>
+ /// Gets or sets the message token.
+ /// </summary>
+ public String Token { get; set; }
+
+ /// <summary>
+ /// Gets or sets the message direction.
+ /// </summary>
+ public TransportMessageDirection Direction { get; set; }
+
+ /// <summary>
+ /// Gets or sets method to serial the message to byte array.
+ /// </summary>
+ public Func<byte[]> Serialize { get; set; }
+
+ /// <summary>
+ /// Gets or sets the message.
+ /// </summary>
+ public Object Message { get; set; }
+
+ /// <summary>
+ /// Notifies the message observer of the new result.
+ /// </summary>
+ /// <param name="result">The result.</param>
+ public abstract void SetResult(object result, bool completed);
+
+ /// <summary>
+ /// Notifies the message observer of an exception.
+ /// </summary>
+ /// <param name="ex">The ex.</param>
+ public abstract void SetException(Exception ex);
+
+ /// <summary>
+ /// Invokes the response callback.
+ /// </summary>
+ /// <param name="response">The response.</param>
+ public abstract void InvokeResponseCallback(object response, bool completed);
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TransportMessageBase"/> class.
+ /// </summary>
+ /// <param name="token">The token.</param>
+ /// <param name="message">The message.</param>
+ /// <param name="direction">The direction.</param>
+ /// <param name="toBytes">To bytes.</param>
+ public TransportMessageBase(ITransportAdapter adapter, String token, object message, TransportMessageDirection direction, Func<byte[]> toBytes)
+ {
+ Adapter = adapter;
+ Token = token;
+ Message = message;
+ Direction = direction;
+ Serialize = toBytes;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/TransportMessageDirection.cs b/Software/Visual_Studio/Tango.Transport/TransportMessageDirection.cs
new file mode 100644
index 000000000..6802afbdf
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/TransportMessageDirection.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Transport
+{
+ /// <summary>
+ /// Represents <see cref="TransportMessageBase"/> direction.
+ /// </summary>
+ public enum TransportMessageDirection
+ {
+ /// <summary>
+ /// Request.
+ /// </summary>
+ Request,
+ /// <summary>
+ /// Response.
+ /// </summary>
+ Response,
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs
new file mode 100644
index 000000000..3bfa019f3
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs
@@ -0,0 +1,574 @@
+using Google.Protobuf;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.Logging;
+using Tango.PMR;
+using Tango.PMR.Common;
+
+namespace Tango.Transport
+{
+ /// <summary>
+ /// Represents an <see cref="ITransporter"/> base class.
+ /// </summary>
+ /// <seealso cref="Tango.Transport.ITransporter" />
+ public abstract class TransporterBase : ITransporter
+ {
+ private ConcurrentQueue<TransportMessageBase> _sendingQueue;
+ private List<TransportMessageBase> _pendingRequests;
+ private ConcurrentQueue<KeyValuePair<ITransportAdapter, byte[]>> _arrivedResponses;
+ private Thread _pushThread;
+ private Thread _pullThread;
+ private ObservableCollection<ITransportAdapter> _adapters;
+ private Dictionary<String, PendingResponse> _pendingResponses;
+
+ #region Events
+
+ /// <summary>
+ /// Occurs when a new request message has been received.
+ /// </summary>
+ public event EventHandler<MessageContainer> RequestReceived;
+
+ /// <summary>
+ /// Occurs when component state changes.
+ /// </summary>
+ public event EventHandler<TransportComponentState> StateChanged;
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets the serial adapter.
+ /// </summary>
+ public ObservableCollection<ITransportAdapter> Adapters
+ {
+ get { return _adapters; }
+ protected set
+ {
+ if (_adapters != null)
+ {
+ _adapters.CollectionChanged -= OnAdaptersCollectionChanged;
+ }
+
+ _adapters = value;
+
+ if (_adapters != null)
+ {
+ _adapters.CollectionChanged += OnAdaptersCollectionChanged;
+ }
+ }
+ }
+
+ private TransportComponentState _state;
+ /// <summary>
+ /// Gets the component state.
+ /// </summary>
+ public TransportComponentState State
+ {
+ get { return _state; }
+ protected set
+ {
+ _state = value;
+ OnStateChanged(_state);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the request timeout.
+ /// </summary>
+ public TimeSpan RequestTimeout { get; set; }
+
+ #endregion
+
+ #region Virtual Methods
+
+ /// <summary>
+ /// Called when the collection of adapters has changed.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="e">The <see cref="System.Collections.Specialized.NotifyCollectionChangedEventArgs"/> instance containing the event data.</param>
+ protected virtual async void OnAdaptersCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ LogManager.Log("Adapters collection changed, Listing adapters:");
+
+ foreach (var ad in _adapters)
+ {
+ LogManager.Log(ad.GetType().Name + ", " + ad.Address + ", " + ad.State.ToString());
+
+ ad.StateChanged -= OnAdapterStateChanged;
+ ad.StateChanged += OnAdapterStateChanged;
+ ad.DataAvailable -= OnAdapterDataAvailable;
+ ad.DataAvailable += OnAdapterDataAvailable;
+
+ if (State == TransportComponentState.Connected && ad.State == TransportComponentState.Disconnected)
+ {
+ await ad.Connect();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Called when the current adapter state has changed.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="e">The e.</param>
+ protected virtual void OnAdapterStateChanged(object sender, TransportComponentState e)
+ {
+ if (e == TransportComponentState.Disposed)
+ {
+ Adapters.Remove(sender as ITransportAdapter);
+ }
+ else if (e == TransportComponentState.Failed)
+ {
+ //TODO: decide what to do in this case..
+ }
+ }
+
+ /// <summary>
+ /// Called when there is data available from the adapter.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="data">The data.</param>
+ protected virtual void OnAdapterDataAvailable(object sender, byte[] data)
+ {
+ _arrivedResponses.Enqueue(new KeyValuePair<ITransportAdapter, byte[]>(sender as ITransportAdapter, data));
+ }
+
+ /// <summary>
+ /// Called when the component has failed.
+ /// </summary>
+ /// <param name="ex">The ex.</param>
+ protected virtual void OnFailed(Exception ex)
+ {
+ Disconnect().Wait();
+ State = TransportComponentState.Failed;
+ LogManager.Log(ex, "Transporter failed.");
+ }
+
+ /// <summary>
+ /// Called when a new request has been received.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ protected virtual void OnRequestReceived(MessageContainer request)
+ {
+ RequestReceived?.Invoke(this, request);
+ }
+
+ /// <summary>
+ /// Called when the component state has changed.
+ /// </summary>
+ /// <param name="state">The state.</param>
+ protected virtual void OnStateChanged(TransportComponentState state)
+ {
+ StateChanged?.Invoke(this, state);
+ }
+
+ /// <summary>
+ /// Override in order to provide a method serializer for <see cref="TangoMessage{T}"/>.
+ /// </summary>
+ /// <typeparam name="Request">The type of the request.</typeparam>
+ /// <param name="message">The message.</param>
+ /// <returns></returns>
+ protected virtual Func<byte[]> OnSerializeingMessage<Request>(TangoMessage<Request> message) where Request : IMessage<Request>
+ {
+ return message.ToBytes;
+ }
+
+ /// <summary>
+ /// Override in order to provide a deserialized message container part of the message.
+ /// </summary>
+ /// <param name="data">The data.</param>
+ /// <returns></returns>
+ protected virtual MessageContainer OnParseContainer(byte[] data)
+ {
+ return MessageFactory.ParseContainer(data);
+ }
+
+ /// <summary>
+ /// Override in order to provide a deserialized message from a container.
+ /// </summary>
+ /// <param name="container">The container.</param>
+ /// <returns></returns>
+ protected virtual IMessage OnParseMessage(MessageContainer container)
+ {
+ return MessageFactory.ParseMessageFromContainer(container);
+ }
+
+ #endregion
+
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TransporterBase"/> class.
+ /// </summary>
+ public TransporterBase()
+ {
+ Adapters = new ObservableCollection<ITransportAdapter>();
+ _pendingResponses = new Dictionary<string, PendingResponse>();
+ _sendingQueue = new ConcurrentQueue<TransportMessageBase>();
+ _pendingRequests = new List<TransportMessageBase>();
+ _arrivedResponses = new ConcurrentQueue<KeyValuePair<ITransportAdapter, byte[]>>();
+ RequestTimeout = TimeSpan.FromSeconds(5);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TransporterBase"/> class.
+ /// </summary>
+ /// <param name="adapter">The transport adapter.</param>
+ public TransporterBase(ITransportAdapter adapter) : this()
+ {
+ Adapters.Add(adapter);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Connects the transport component.
+ /// </summary>
+ /// <returns></returns>
+ public async Task Connect()
+ {
+ State = TransportComponentState.Connected;
+ StartThreads();
+ await Task.WhenAll(Adapters.Select(x => x.Connect()));
+ LogManager.Log("Transporter Connected...");
+ }
+
+ /// <summary>
+ /// Disconnects the transport component.
+ /// </summary>
+ /// <returns></returns>
+ public async Task Disconnect()
+ {
+ State = TransportComponentState.Disconnected;
+ await Task.WhenAll(Adapters.Select(x => x.Disconnect()));
+ LogManager.Log("Transporter Disconnected...");
+ }
+
+ /// <summary>
+ /// Sends a broadcast request to through all adapters.
+ /// </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 Task<Response> SendRequest<Request, Response>(TangoMessage<Request> request) where Request : IMessage<Request> where Response : IMessage<Response>
+ {
+ return SendRequest<Request, Response>(request, null);
+ }
+
+ /// <summary>
+ /// Sends a request through the specified adapter.
+ /// </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>
+ /// <param name="adapter">Transport adapter</param>
+ /// <returns></returns>
+ public Task<Response> SendRequest<Request, Response>(TangoMessage<Request> request, ITransportAdapter adapter) where Request : IMessage<Request> where Response : IMessage<Response>
+ {
+ LogManager.Log("Queuing request message: " + typeof(Request).Name + " Token: " + request.Container.Token + " on adapter: " + (adapter != null ? adapter.Address : "ALL"));
+ LogManager.Log("Expected response: " + typeof(Response).Name);
+
+ TaskCompletionSource<Response> source = new TaskCompletionSource<Response>();
+ TransportMessage<Response> message = new TransportMessage<Response>(adapter, request.Container.Token, request, TransportMessageDirection.Request, OnSerializeingMessage(request), source);
+ _sendingQueue.Enqueue(message);
+ Task.Delay(RequestTimeout).ContinueWith((x) =>
+ {
+ if (!source.Task.IsCompleted)
+ {
+ LogManager.Log("Request message: " + typeof(Response).Name + " had timed out after " + RequestTimeout.TotalSeconds + " seconds.");
+ LogManager.Log("Setting request task exception...");
+ source.SetException(new TimeoutException());
+ }
+ });
+ return source.Task;
+ }
+
+ /// <summary>
+ /// Sends a request through all adapters which is expected to return multiple response messages.
+ /// </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>
+ /// <param name="responseCallback">The response callback delegate.</param>
+ public void SendContinuousRequest<Request, Response>(TangoMessage<Request> request, Action<Response> responseCallback) where Request : IMessage<Request> where Response : IMessage<Response>
+ {
+ SendContinuousRequest(request, null, responseCallback);
+ }
+
+ /// <summary>
+ /// Sends a request through the specified adapter which is expected to return multiple response messages.
+ /// </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>
+ /// <param name="adapter">Transport adapter</param>
+ /// <param name="responseCallback">The response callback delegate.</param>
+ public void SendContinuousRequest<Request, Response>(TangoMessage<Request> request, ITransportAdapter adapter, Action<Response> responseCallback) where Request : IMessage<Request> where Response : IMessage<Response>
+ {
+ LogManager.Log("Queuing continuous request message: " + typeof(Request).Name + " on adapter: " + (adapter != null ? adapter.Address : "ALL"));
+ LogManager.Log("Expected response: " + typeof(Response).Name);
+
+ request.Container.Continuous = true;
+ request.Container.Completed = false;
+
+ TransportMessage<Response> message = new TransportMessage<Response>(adapter, request.Container.Token, request, TransportMessageDirection.Request, OnSerializeingMessage(request), null)
+ {
+ IsContinuous = true,
+ ResponseCallback = responseCallback,
+ };
+ _sendingQueue.Enqueue(message);
+ }
+
+ /// <summary>
+ /// Sends a response.
+ /// </summary>
+ /// <typeparam name="Response">The type of the response.</typeparam>
+ /// <param name="response">The response.</param>
+ /// <returns></returns>
+ public Task SendResponse<Response>(TangoMessage<Response> response) where Response : IMessage<Response>
+ {
+ return SendResponse<Response>(response, response.Container.Token);
+ }
+
+ /// <summary>
+ /// Sends a response for the specified token.
+ /// </summary>
+ /// <typeparam name="Response">The type of the response.</typeparam>
+ /// <param name="response">The response.</param>
+ /// <param name="token">The token.</param>
+ /// <returns></returns>
+ public Task SendResponse<Response>(TangoMessage<Response> response, String token) where Response : IMessage<Response>
+ {
+ response.Container.Token = token;
+
+ LogManager.Log("Queuing response message: " + typeof(Response).Name);
+
+ PendingResponse pendingResponse = null;
+ ITransportAdapter adapter = null;
+
+ LogManager.Log("Searching for matching request token: " + token);
+
+ if (_pendingResponses.TryGetValue(token, out pendingResponse))
+ {
+ adapter = pendingResponse.Adapter;
+ LogManager.Log("Found matching request token: " + token + " on adapter: " + (adapter != null ? adapter.Address : "ALL"));
+
+ if (!pendingResponse.IsContinuous)
+ {
+ LogManager.Log("Removing matching request token.");
+ _pendingResponses.Remove(token);
+ }
+ else if (response.Container.Completed)
+ {
+ LogManager.Log("Response completed. Removing matching request token.");
+ _pendingResponses.Remove(token);
+ }
+ }
+ else
+ {
+ //This should never happen.
+ throw LogManager.Log(new InvalidOperationException("Matching request token was not found!"));
+ }
+
+ TaskCompletionSource<object> source = new TaskCompletionSource<object>();
+ TransportMessage<object> message = new TransportMessage<object>(adapter, token, response, TransportMessageDirection.Response, OnSerializeingMessage(response), source);
+ _sendingQueue.Enqueue(message);
+ return source.Task;
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ /// <summary>
+ /// Starts the pull and push threads.
+ /// </summary>
+ private void StartThreads()
+ {
+ _pullThread = new Thread(PullThreadMethod);
+ _pullThread.IsBackground = true;
+ _pullThread.Start();
+
+ _pushThread = new Thread(PushThreadMethod);
+ _pushThread.IsBackground = true;
+ _pushThread.Start();
+ }
+
+ #endregion
+
+ #region Push Thread
+
+ /// <summary>
+ /// Push thread loop.
+ /// </summary>
+ private void PushThreadMethod()
+ {
+ try
+ {
+ while (State == TransportComponentState.Connected)
+ {
+ if (_sendingQueue.Count > 0)
+ {
+ TransportMessageBase message;
+ if (_sendingQueue.TryDequeue(out message))
+ {
+ try
+ {
+ if (message.Adapter == null)
+ {
+ foreach (var adapter in Adapters.Where(x => x.State == TransportComponentState.Connected))
+ {
+ adapter.Write(message.Serialize());
+ LogManager.Log("Message sent on adapter: " + adapter.Address + "...");
+ }
+ }
+ else
+ {
+ message.Adapter.Write(message.Serialize());
+ LogManager.Log("Message sent on adapter: " + message.Adapter.Address + "...");
+ }
+
+ if (message.Direction == TransportMessageDirection.Request)
+ {
+ _pendingRequests.Add(message);
+ }
+ else
+ {
+ message.SetResult(true, true);
+ }
+ }
+ catch (Exception ex)
+ {
+ message.SetException(ex);
+ }
+ }
+ }
+
+ Thread.Sleep(10);
+ }
+ }
+ catch (Exception ex)
+ {
+ OnFailed(ex);
+ }
+ }
+
+ #endregion
+
+ #region Pull Thread
+
+ /// <summary>
+ /// Pull thread loop.
+ /// </summary>
+ private void PullThreadMethod()
+ {
+ try
+ {
+ while (State == TransportComponentState.Connected)
+ {
+ KeyValuePair<ITransportAdapter, byte[]> data;
+
+ if (_arrivedResponses.Count > 0)
+ {
+ if (_arrivedResponses.TryDequeue(out data))
+ {
+ LogManager.Log("Message received on adapter: " + data.Key.Address);
+
+ LogManager.Log("Parsing message container...");
+ MessageContainer container = OnParseContainer(data.Value);
+ LogManager.Log("Searching for pending request token: " + container.Token);
+ TransportMessageBase request = _pendingRequests.SingleOrDefault(x => x.Token == container.Token);
+
+ if (request != null)
+ {
+ LogManager.Log("Found pending request: " + request.Message.GetType().GetGenericArguments()[0].Name);
+
+ if (!request.IsContinuous)
+ {
+ LogManager.Log("Pending request was identified as 'single response'. Removing pending request.");
+
+ _pendingRequests.Remove(request);
+
+ try
+ {
+ LogManager.Log("Parsing inner response message and setting pending request task result...");
+ request.SetResult(OnParseMessage(container), true);
+ }
+ catch (Exception ex)
+ {
+ request.SetException(LogManager.Log(ex, "Error parsing inner message."));
+ }
+ }
+ else
+ {
+ LogManager.Log("Pending request was identified as 'continuous response'. keeping pending request.");
+
+ try
+ {
+ LogManager.Log("Parsing inner response message and invoking continuous response callback...");
+ if (container.Completed)
+ {
+ LogManager.Log("Continuous sequence completed.");
+ }
+ request.InvokeResponseCallback(OnParseMessage(container), container.Completed);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error parsing inner message.");
+ }
+ }
+ }
+ else
+ {
+ LogManager.Log("Message was identified as a new request message: " + container.Type.ToString());
+
+ try
+ {
+ LogManager.Log("Saving request token and adapter: " + container.Token + ", " + data.Key.Address);
+ _pendingResponses.Add(container.Token, new PendingResponse(data.Key, container.Continuous));
+ LogManager.Log("Invoking RequestReceived event...");
+ Task.Factory.StartNew(() => OnRequestReceived(container));
+ }
+ catch
+ {
+ //Ignore any exception that might occur on the event handler side...
+ }
+ }
+ }
+ }
+
+ Thread.Sleep(10);
+ }
+ }
+ catch (Exception ex)
+ {
+ OnFailed(ex);
+ }
+ }
+
+ #endregion
+
+ #region Dispose
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ Disconnect().Wait();
+ State = TransportComponentState.Disposed;
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/Transporters/JsonTransporter.cs b/Software/Visual_Studio/Tango.Transport/Transporters/JsonTransporter.cs
new file mode 100644
index 000000000..d490d4a61
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/Transporters/JsonTransporter.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Google.Protobuf;
+using Tango.PMR;
+using Tango.PMR.Common;
+
+namespace Tango.Transport.Transporters
+{
+ /// <summary>
+ /// Represents an <see cref="ITransporter"/> which send and receive <see cref="TangoMessage{T}"/> messages using JSON formatted strings.
+ /// </summary>
+ /// <seealso cref="Tango.Transport.TransporterBase" />
+ public class JsonTransporter : TransporterBase
+ {
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="JsonTransporter"/> class.
+ /// </summary>
+ public JsonTransporter() : base()
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="JsonTransporter"/> class.
+ /// </summary>
+ /// <param name="adapter">The transport adapter.</param>
+ public JsonTransporter(ITransportAdapter adapter) : base(adapter)
+ {
+
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Override in order to provide a method serializer for <see cref="TangoMessage{T}" />.
+ /// </summary>
+ /// <typeparam name="Request">The type of the request.</typeparam>
+ /// <param name="message">The message.</param>
+ /// <returns></returns>
+ protected override Func<byte[]> OnSerializeingMessage<Request>(TangoMessage<Request> message)
+ {
+ return message.ToJsonBytes;
+ }
+
+ /// <summary>
+ /// Override in order to provide a deserialized message container part of the message.
+ /// </summary>
+ /// <param name="data">The data.</param>
+ /// <returns></returns>
+ protected override MessageContainer OnParseContainer(byte[] data)
+ {
+ return MessageFactory.ParseContainerJson(data);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/Transporters/ProtoTransporter.cs b/Software/Visual_Studio/Tango.Transport/Transporters/ProtoTransporter.cs
new file mode 100644
index 000000000..7c82639d2
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/Transporters/ProtoTransporter.cs
@@ -0,0 +1,47 @@
+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.Transport.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.Transport.Transporters
+{
+ /// <summary>
+ /// Represents an <see cref="ITransporter"/> which send and receive <see cref="TangoMessage{T}"/> messages using Protobuf binary data.
+ /// </summary>
+ /// <seealso cref="Tango.Transport.TransporterBase" />
+ public class ProtoTransporter : TransporterBase
+ {
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ProtoTransporter"/> class.
+ /// </summary>
+ public ProtoTransporter() : base()
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ProtoTransporter"/> class.
+ /// </summary>
+ /// <param name="adapter">The transport adapter.</param>
+ public ProtoTransporter(ITransportAdapter adapter) : base(adapter)
+ {
+
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Transport/packages.config b/Software/Visual_Studio/Tango.Transport/packages.config
new file mode 100644
index 000000000..5a7de5f4e
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Transport/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.UnitTesting/Helper.cs b/Software/Visual_Studio/Tango.UnitTesting/Helper.cs
new file mode 100644
index 000000000..ece74d3f3
--- /dev/null
+++ b/Software/Visual_Studio/Tango.UnitTesting/Helper.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Logging;
+
+namespace Tango.UnitTesting
+{
+ /// <summary>
+ /// Contains several unit testing helper methods.
+ /// </summary>
+ public static class Helper
+ {
+ /// <summary>
+ /// Gets the absolute path to the specified file name in the solution 'Resources' folder.
+ /// </summary>
+ /// <param name="fileName">Name of the file.</param>
+ /// <returns></returns>
+ public static String GetResourcePath(String fileName)
+ {
+ return Path.GetFullPath(@"..\..\Resources\" + fileName);
+ }
+
+ /// <summary>
+ /// Gets the PMR (Protobuf Messages Repository) path.
+ /// </summary>
+ /// <returns></returns>
+ public static String GetPMRPath()
+ {
+ return Path.GetFullPath(@"..\..\..\PMR\Messages\");
+ }
+
+ /// <summary>
+ /// Initializes the logging manager.
+ /// </summary>
+ public static ConsoleLogger InitializeLogging(bool useConsole = false, [CallerMemberName] string testName = null)
+ {
+ LogManager.RegisterLogger(new FileLogger(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "logs", "Unit Testing", testName + ".txt")));
+ if (useConsole)
+ {
+ var consoleLogger = new ConsoleLogger(testName);
+ LogManager.RegisterLogger(consoleLogger);
+ return consoleLogger;
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Creates a temporary folder and returns it's path.
+ /// </summary>
+ /// <returns></returns>
+ public static String GetTempFolderPathAppend(String customFolder, [CallerMemberName] string testName = null)
+ {
+ String tempDirectory = Path.Combine(Path.GetTempPath(), "Twine", "Unit Testing", testName, customFolder);
+ Directory.CreateDirectory(tempDirectory);
+ return tempDirectory;
+ }
+
+ /// <summary>
+ /// Creates a temporary folder and returns it's path.
+ /// </summary>
+ /// <returns></returns>
+ public static String GetTempFolderPath([CallerMemberName] string testName = null)
+ {
+ String tempDirectory = Path.Combine(Path.GetTempPath(), "Twine", "Unit Testing", testName, Path.GetRandomFileName());
+ Directory.CreateDirectory(tempDirectory);
+ return tempDirectory;
+ }
+
+ /// <summary>
+ /// Tries to delete folder.
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <returns></returns>
+ public static bool TryDeleteFolder(String path)
+ {
+ try
+ {
+ Directory.Delete(path, true);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Shows the file in explorer.
+ /// </summary>
+ /// <param name="path">Name of the file/folder.</param>
+ public static void ShowInExplorer(String path)
+ {
+ Process.Start("explorer.exe", string.Format("/select,\"{0}\"", path));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.UnitTesting/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.UnitTesting/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..0551f8f77
--- /dev/null
+++ b/Software/Visual_Studio/Tango.UnitTesting/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Unit Testing")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.UnitTesting/Protobuf_TST.cs b/Software/Visual_Studio/Tango.UnitTesting/Protobuf_TST.cs
new file mode 100644
index 000000000..ed3bfbb7d
--- /dev/null
+++ b/Software/Visual_Studio/Tango.UnitTesting/Protobuf_TST.cs
@@ -0,0 +1,115 @@
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Tango.Protobuf;
+using System.Threading;
+using System.Collections.Generic;
+using System.Linq;
+using System.IO;
+using Google.Protobuf;
+using Tango.PMR.Jobs;
+using Tango.PMR.Common;
+using Tango.PMR;
+using Tango.Logging;
+using Newtonsoft.Json;
+using System.Runtime.InteropServices;
+using Tango.Core.Helpers;
+using System.Text;
+using Tango.PMR.Stubs;
+
+namespace Tango.UnitTesting
+{
+ [TestClass]
+ [TestCategory("Protobuf")]
+ public class Protobuf_TST
+ {
+ [DllImport("Tango.ProtoTest.dll", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int Calculate(IntPtr data, int size, ref IntPtr output);
+
+ /// <summary>
+ /// Compiles all the whole PMR using all available compilers.
+ /// </summary>
+ [TestMethod]
+ public void Compile_All_PMR()
+ {
+ var console = Helper.InitializeLogging(true);
+
+ String pmrFolder = Helper.GetPMRPath();
+
+ List<String> tempFolders = new List<string>();
+
+ foreach (var compiler in CompilerFactory.GetAvailableCompilers())
+ {
+ CompilerFolderResult result = compiler.CompileFolder(pmrFolder);
+ String tmpFolder = Helper.GetTempFolderPathAppend(compiler.Language.ToString());
+ result.Save(tmpFolder);
+ tempFolders.Add(tmpFolder);
+ }
+
+ Helper.ShowInExplorer(Directory.GetParent(tempFolders.First()).FullName);
+
+ console.WaitForConsoleExit().Wait();
+
+ foreach (var folder in tempFolders)
+ {
+ Helper.TryDeleteFolder(folder);
+ }
+ }
+
+ /// <summary>
+ /// Writes and reads a proto message then compares.
+ /// </summary>
+ [TestMethod]
+ public void Read_Write_Message()
+ {
+ var console = Helper.InitializeLogging(true);
+
+ TangoMessage<Job> container = MessageFactory.CreateTangoMessage<Job>();
+
+ container.Message.Name = "Test Job";
+
+ container.Message.Segments.Add(new Segment()
+ {
+ Color = new RGB() { R = 1, G = 2, B = 3 },
+ Length = 10,
+ Name = "Segment 1"
+ });
+
+ container.Message.Segments.Add(new Segment()
+ {
+ Color = new RGB() { R = 10, G = 20, B = 30 },
+ Length = 100,
+ Name = "Segment 2"
+ });
+
+ LogManager.Log("Write Message:" + Environment.NewLine + JsonConvert.SerializeObject(container.Message, Formatting.Indented));
+
+ var bytes = container.ToBytes();
+
+ var parsed = MessageFactory.ParseTangoMessage<Job>(bytes);
+
+ LogManager.Log("Read Message:" + Environment.NewLine + JsonConvert.SerializeObject(parsed.Message, Formatting.Indented));
+
+ Assert.AreEqual(container.Message, parsed.Message);
+
+ LogManager.Log("Test Passed!");
+
+ console.WaitForConsoleExit().Wait();
+ }
+
+ /// <summary>
+ /// Calls a C++ native library and get a result.
+ /// </summary>
+ [TestMethod]
+ public void Call_CPP_And_Get_Result()
+ {
+ CalculateRequest request = new CalculateRequest();
+ request.A = 10;
+ request.B = 5;
+
+ NativePMR<CalculateRequest, CalculateResponse> nativePMR = new NativePMR<CalculateRequest, CalculateResponse>(Calculate);
+ CalculateResponse response = nativePMR.Invoke(request);
+
+ Assert.AreEqual(response.Sum, request.A + request.B);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj
new file mode 100644
index 000000000..a377179b9
--- /dev/null
+++ b/Software/Visual_Studio/Tango.UnitTesting/Tango.UnitTesting.csproj
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="..\packages\MSTest.TestAdapter.1.1.11\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.1.1.11\build\net45\MSTest.TestAdapter.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{FB82AA6B-1652-452C-8235-4FB2E524FBC0}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tango.UnitTesting</RootNamespace>
+ <AssemblyName>Tango.UnitTesting</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
+ <IsCodedUITest>False</IsCodedUITest>
+ <TestProjectType>UnitTest</TestProjectType>
+ <NuGetPackageImportStamp>
+ </NuGetPackageImportStamp>
+ </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>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </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="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\packages\MSTest.TestFramework.1.1.11\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\packages\MSTest.TestFramework.1.1.11\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
+ </Reference>
+ <Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Versioning\GlobalVersionInfo.cs">
+ <Link>GlobalVersionInfo.cs</Link>
+ </Compile>
+ <Compile Include="Helper.cs" />
+ <Compile Include="Protobuf_TST.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.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.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>
+ <Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.1.11\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.1.11\build\net45\MSTest.TestAdapter.props'))" />
+ <Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.1.11\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.1.11\build\net45\MSTest.TestAdapter.targets'))" />
+ </Target>
+ <Import Project="..\packages\MSTest.TestAdapter.1.1.11\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.1.1.11\build\net45\MSTest.TestAdapter.targets')" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.UnitTesting/packages.config b/Software/Visual_Studio/Tango.UnitTesting/packages.config
new file mode 100644
index 000000000..d3cd9d043
--- /dev/null
+++ b/Software/Visual_Studio/Tango.UnitTesting/packages.config
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.Protobuf" version="3.4.1" targetFramework="net45" />
+ <package id="MSTest.TestAdapter" version="1.1.11" targetFramework="net45" />
+ <package id="MSTest.TestFramework" version="1.1.11" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.sln b/Software/Visual_Studio/Tango.sln
new file mode 100644
index 000000000..329649af7
--- /dev/null
+++ b/Software/Visual_Studio/Tango.sln
@@ -0,0 +1,235 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26430.16
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Protobuf", "Tango.Protobuf\Tango.Protobuf.csproj", "{40073806-914E-4E78-97AB-FA9639308EBE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Versioning", "Versioning", "{E53A5748-F312-4A70-AB93-53249749D359}"
+ ProjectSection(SolutionItems) = preProject
+ Versioning\GlobalVersionInfo.cs = Versioning\GlobalVersionInfo.cs
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Core", "Tango.Core\Tango.Core.csproj", "{A34EE0F0-649D-41C8-8489-B6F1CC6924EE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utilities", "Utilities", "{5F6BBAA8-EAD0-4B18-97E5-55B4F56DD760}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Protobuf.UI", "Utilities\Tango.Protobuf.UI\Tango.Protobuf.UI.csproj", "{37E45CE1-A0F6-4ED7-9791-A1BED947602F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.SharedUI", "Tango.SharedUI\Tango.SharedUI.csproj", "{AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Protobuf.CLI", "Utilities\Tango.Protobuf.CLI\Tango.Protobuf.CLI.csproj", "{DE5AB980-A9AD-4273-8272-C4E1E062E3EC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Logging", "Tango.Logging\Tango.Logging.csproj", "{BC932DBD-7CDB-488C-99E4-F02CF441F55E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.UnitTesting", "Tango.UnitTesting\Tango.UnitTesting.csproj", "{FB82AA6B-1652-452C-8235-4FB2E524FBC0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Resources", "Resources", "{727F6479-A4A7-4288-ADD2-005CE0C5DE49}"
+ ProjectSection(SolutionItems) = preProject
+ Resources\dummyFile.txt = Resources\dummyFile.txt
+ EndProjectSection
+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.Transport", "Tango.Transport\Tango.Transport.csproj", "{74E700B0-1156-4126-BE40-EE450D3C3026}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Emulations", "Tango.Emulations\Tango.Emulations.csproj", "{63561E19-FF5A-414B-A5EF-E30711543E1D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.MachineEM.UI", "Utilities\Tango.MachineEM.UI\Tango.MachineEM.UI.csproj", "{1971345A-0627-4428-88AA-1CCC4BFAEF4B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.MobileEM.UI", "Utilities\Tango.MobileEM.UI\Tango.MobileEM.UI.csproj", "{372401B3-FFEB-483F-965F-261506B3FDFB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Stubs", "Tango.Stubs\Tango.Stubs.csproj", "{1981B537-39E9-4E7D-8430-27466481AEEE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Native", "Native", "{4443B71C-216E-4D4C-8D19-868F50803813}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tango.ProtoTest", "Native\Tango.ProtoTest\Tango.ProtoTest.vcxproj", "{35397DDA-DDC7-46BE-A802-3B722B6858E9}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {40073806-914E-4E78-97AB-FA9639308EBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {40073806-914E-4E78-97AB-FA9639308EBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {40073806-914E-4E78-97AB-FA9639308EBE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {40073806-914E-4E78-97AB-FA9639308EBE}.Debug|x64.Build.0 = Debug|Any CPU
+ {40073806-914E-4E78-97AB-FA9639308EBE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {40073806-914E-4E78-97AB-FA9639308EBE}.Debug|x86.Build.0 = Debug|Any CPU
+ {40073806-914E-4E78-97AB-FA9639308EBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {40073806-914E-4E78-97AB-FA9639308EBE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {40073806-914E-4E78-97AB-FA9639308EBE}.Release|x64.ActiveCfg = Release|Any CPU
+ {40073806-914E-4E78-97AB-FA9639308EBE}.Release|x64.Build.0 = Release|Any CPU
+ {40073806-914E-4E78-97AB-FA9639308EBE}.Release|x86.ActiveCfg = Release|Any CPU
+ {40073806-914E-4E78-97AB-FA9639308EBE}.Release|x86.Build.0 = Release|Any CPU
+ {A34EE0F0-649D-41C8-8489-B6F1CC6924EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A34EE0F0-649D-41C8-8489-B6F1CC6924EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A34EE0F0-649D-41C8-8489-B6F1CC6924EE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A34EE0F0-649D-41C8-8489-B6F1CC6924EE}.Debug|x64.Build.0 = Debug|Any CPU
+ {A34EE0F0-649D-41C8-8489-B6F1CC6924EE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A34EE0F0-649D-41C8-8489-B6F1CC6924EE}.Debug|x86.Build.0 = Debug|Any CPU
+ {A34EE0F0-649D-41C8-8489-B6F1CC6924EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A34EE0F0-649D-41C8-8489-B6F1CC6924EE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A34EE0F0-649D-41C8-8489-B6F1CC6924EE}.Release|x64.ActiveCfg = Release|Any CPU
+ {A34EE0F0-649D-41C8-8489-B6F1CC6924EE}.Release|x64.Build.0 = Release|Any CPU
+ {A34EE0F0-649D-41C8-8489-B6F1CC6924EE}.Release|x86.ActiveCfg = Release|Any CPU
+ {A34EE0F0-649D-41C8-8489-B6F1CC6924EE}.Release|x86.Build.0 = Release|Any CPU
+ {37E45CE1-A0F6-4ED7-9791-A1BED947602F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {37E45CE1-A0F6-4ED7-9791-A1BED947602F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {37E45CE1-A0F6-4ED7-9791-A1BED947602F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {37E45CE1-A0F6-4ED7-9791-A1BED947602F}.Debug|x64.Build.0 = Debug|Any CPU
+ {37E45CE1-A0F6-4ED7-9791-A1BED947602F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {37E45CE1-A0F6-4ED7-9791-A1BED947602F}.Debug|x86.Build.0 = Debug|Any CPU
+ {37E45CE1-A0F6-4ED7-9791-A1BED947602F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {37E45CE1-A0F6-4ED7-9791-A1BED947602F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {37E45CE1-A0F6-4ED7-9791-A1BED947602F}.Release|x64.ActiveCfg = Release|Any CPU
+ {37E45CE1-A0F6-4ED7-9791-A1BED947602F}.Release|x64.Build.0 = Release|Any CPU
+ {37E45CE1-A0F6-4ED7-9791-A1BED947602F}.Release|x86.ActiveCfg = Release|Any CPU
+ {37E45CE1-A0F6-4ED7-9791-A1BED947602F}.Release|x86.Build.0 = Release|Any CPU
+ {AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}.Debug|x64.Build.0 = Debug|Any CPU
+ {AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}.Debug|x86.Build.0 = Debug|Any CPU
+ {AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}.Release|x64.ActiveCfg = Release|Any CPU
+ {AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}.Release|x64.Build.0 = Release|Any CPU
+ {AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}.Release|x86.ActiveCfg = Release|Any CPU
+ {AC489889-6E50-4F16-9DBA-FF4C6F9EC72B}.Release|x86.Build.0 = Release|Any CPU
+ {DE5AB980-A9AD-4273-8272-C4E1E062E3EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DE5AB980-A9AD-4273-8272-C4E1E062E3EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DE5AB980-A9AD-4273-8272-C4E1E062E3EC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {DE5AB980-A9AD-4273-8272-C4E1E062E3EC}.Debug|x64.Build.0 = Debug|Any CPU
+ {DE5AB980-A9AD-4273-8272-C4E1E062E3EC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {DE5AB980-A9AD-4273-8272-C4E1E062E3EC}.Debug|x86.Build.0 = Debug|Any CPU
+ {DE5AB980-A9AD-4273-8272-C4E1E062E3EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DE5AB980-A9AD-4273-8272-C4E1E062E3EC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DE5AB980-A9AD-4273-8272-C4E1E062E3EC}.Release|x64.ActiveCfg = Release|Any CPU
+ {DE5AB980-A9AD-4273-8272-C4E1E062E3EC}.Release|x64.Build.0 = Release|Any CPU
+ {DE5AB980-A9AD-4273-8272-C4E1E062E3EC}.Release|x86.ActiveCfg = Release|Any CPU
+ {DE5AB980-A9AD-4273-8272-C4E1E062E3EC}.Release|x86.Build.0 = Release|Any CPU
+ {BC932DBD-7CDB-488C-99E4-F02CF441F55E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BC932DBD-7CDB-488C-99E4-F02CF441F55E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BC932DBD-7CDB-488C-99E4-F02CF441F55E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {BC932DBD-7CDB-488C-99E4-F02CF441F55E}.Debug|x64.Build.0 = Debug|Any CPU
+ {BC932DBD-7CDB-488C-99E4-F02CF441F55E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {BC932DBD-7CDB-488C-99E4-F02CF441F55E}.Debug|x86.Build.0 = Debug|Any CPU
+ {BC932DBD-7CDB-488C-99E4-F02CF441F55E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BC932DBD-7CDB-488C-99E4-F02CF441F55E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BC932DBD-7CDB-488C-99E4-F02CF441F55E}.Release|x64.ActiveCfg = Release|Any CPU
+ {BC932DBD-7CDB-488C-99E4-F02CF441F55E}.Release|x64.Build.0 = Release|Any CPU
+ {BC932DBD-7CDB-488C-99E4-F02CF441F55E}.Release|x86.ActiveCfg = Release|Any CPU
+ {BC932DBD-7CDB-488C-99E4-F02CF441F55E}.Release|x86.Build.0 = Release|Any CPU
+ {FB82AA6B-1652-452C-8235-4FB2E524FBC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FB82AA6B-1652-452C-8235-4FB2E524FBC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FB82AA6B-1652-452C-8235-4FB2E524FBC0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FB82AA6B-1652-452C-8235-4FB2E524FBC0}.Debug|x64.Build.0 = Debug|Any CPU
+ {FB82AA6B-1652-452C-8235-4FB2E524FBC0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FB82AA6B-1652-452C-8235-4FB2E524FBC0}.Debug|x86.Build.0 = Debug|Any CPU
+ {FB82AA6B-1652-452C-8235-4FB2E524FBC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FB82AA6B-1652-452C-8235-4FB2E524FBC0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FB82AA6B-1652-452C-8235-4FB2E524FBC0}.Release|x64.ActiveCfg = Release|Any CPU
+ {FB82AA6B-1652-452C-8235-4FB2E524FBC0}.Release|x64.Build.0 = Release|Any CPU
+ {FB82AA6B-1652-452C-8235-4FB2E524FBC0}.Release|x86.ActiveCfg = Release|Any CPU
+ {FB82AA6B-1652-452C-8235-4FB2E524FBC0}.Release|x86.Build.0 = Release|Any CPU
+ {E4927038-348D-4295-AAF4-861C58CB3943}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E4927038-348D-4295-AAF4-861C58CB3943}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E4927038-348D-4295-AAF4-861C58CB3943}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E4927038-348D-4295-AAF4-861C58CB3943}.Debug|x64.Build.0 = Debug|Any CPU
+ {E4927038-348D-4295-AAF4-861C58CB3943}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E4927038-348D-4295-AAF4-861C58CB3943}.Debug|x86.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
+ {E4927038-348D-4295-AAF4-861C58CB3943}.Release|x64.ActiveCfg = Release|Any CPU
+ {E4927038-348D-4295-AAF4-861C58CB3943}.Release|x64.Build.0 = Release|Any CPU
+ {E4927038-348D-4295-AAF4-861C58CB3943}.Release|x86.ActiveCfg = Release|Any CPU
+ {E4927038-348D-4295-AAF4-861C58CB3943}.Release|x86.Build.0 = Release|Any CPU
+ {74E700B0-1156-4126-BE40-EE450D3C3026}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {74E700B0-1156-4126-BE40-EE450D3C3026}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {74E700B0-1156-4126-BE40-EE450D3C3026}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {74E700B0-1156-4126-BE40-EE450D3C3026}.Debug|x64.Build.0 = Debug|Any CPU
+ {74E700B0-1156-4126-BE40-EE450D3C3026}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {74E700B0-1156-4126-BE40-EE450D3C3026}.Debug|x86.Build.0 = Debug|Any CPU
+ {74E700B0-1156-4126-BE40-EE450D3C3026}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {74E700B0-1156-4126-BE40-EE450D3C3026}.Release|Any CPU.Build.0 = Release|Any CPU
+ {74E700B0-1156-4126-BE40-EE450D3C3026}.Release|x64.ActiveCfg = Release|Any CPU
+ {74E700B0-1156-4126-BE40-EE450D3C3026}.Release|x64.Build.0 = Release|Any CPU
+ {74E700B0-1156-4126-BE40-EE450D3C3026}.Release|x86.ActiveCfg = Release|Any CPU
+ {74E700B0-1156-4126-BE40-EE450D3C3026}.Release|x86.Build.0 = Release|Any CPU
+ {63561E19-FF5A-414B-A5EF-E30711543E1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {63561E19-FF5A-414B-A5EF-E30711543E1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {63561E19-FF5A-414B-A5EF-E30711543E1D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {63561E19-FF5A-414B-A5EF-E30711543E1D}.Debug|x64.Build.0 = Debug|Any CPU
+ {63561E19-FF5A-414B-A5EF-E30711543E1D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {63561E19-FF5A-414B-A5EF-E30711543E1D}.Debug|x86.Build.0 = Debug|Any CPU
+ {63561E19-FF5A-414B-A5EF-E30711543E1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {63561E19-FF5A-414B-A5EF-E30711543E1D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {63561E19-FF5A-414B-A5EF-E30711543E1D}.Release|x64.ActiveCfg = Release|Any CPU
+ {63561E19-FF5A-414B-A5EF-E30711543E1D}.Release|x64.Build.0 = Release|Any CPU
+ {63561E19-FF5A-414B-A5EF-E30711543E1D}.Release|x86.ActiveCfg = Release|Any CPU
+ {63561E19-FF5A-414B-A5EF-E30711543E1D}.Release|x86.Build.0 = Release|Any CPU
+ {1971345A-0627-4428-88AA-1CCC4BFAEF4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1971345A-0627-4428-88AA-1CCC4BFAEF4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1971345A-0627-4428-88AA-1CCC4BFAEF4B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1971345A-0627-4428-88AA-1CCC4BFAEF4B}.Debug|x64.Build.0 = Debug|Any CPU
+ {1971345A-0627-4428-88AA-1CCC4BFAEF4B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1971345A-0627-4428-88AA-1CCC4BFAEF4B}.Debug|x86.Build.0 = Debug|Any CPU
+ {1971345A-0627-4428-88AA-1CCC4BFAEF4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1971345A-0627-4428-88AA-1CCC4BFAEF4B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1971345A-0627-4428-88AA-1CCC4BFAEF4B}.Release|x64.ActiveCfg = Release|Any CPU
+ {1971345A-0627-4428-88AA-1CCC4BFAEF4B}.Release|x64.Build.0 = Release|Any CPU
+ {1971345A-0627-4428-88AA-1CCC4BFAEF4B}.Release|x86.ActiveCfg = Release|Any CPU
+ {1971345A-0627-4428-88AA-1CCC4BFAEF4B}.Release|x86.Build.0 = Release|Any CPU
+ {372401B3-FFEB-483F-965F-261506B3FDFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {372401B3-FFEB-483F-965F-261506B3FDFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {372401B3-FFEB-483F-965F-261506B3FDFB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {372401B3-FFEB-483F-965F-261506B3FDFB}.Debug|x64.Build.0 = Debug|Any CPU
+ {372401B3-FFEB-483F-965F-261506B3FDFB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {372401B3-FFEB-483F-965F-261506B3FDFB}.Debug|x86.Build.0 = Debug|Any CPU
+ {372401B3-FFEB-483F-965F-261506B3FDFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {372401B3-FFEB-483F-965F-261506B3FDFB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {372401B3-FFEB-483F-965F-261506B3FDFB}.Release|x64.ActiveCfg = Release|Any CPU
+ {372401B3-FFEB-483F-965F-261506B3FDFB}.Release|x64.Build.0 = Release|Any CPU
+ {372401B3-FFEB-483F-965F-261506B3FDFB}.Release|x86.ActiveCfg = Release|Any CPU
+ {372401B3-FFEB-483F-965F-261506B3FDFB}.Release|x86.Build.0 = Release|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Debug|x64.Build.0 = Debug|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Debug|x86.Build.0 = Debug|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Release|x64.ActiveCfg = Release|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Release|x64.Build.0 = Release|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Release|x86.ActiveCfg = Release|Any CPU
+ {1981B537-39E9-4E7D-8430-27466481AEEE}.Release|x86.Build.0 = Release|Any CPU
+ {35397DDA-DDC7-46BE-A802-3B722B6858E9}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {35397DDA-DDC7-46BE-A802-3B722B6858E9}.Debug|x64.ActiveCfg = Debug|x64
+ {35397DDA-DDC7-46BE-A802-3B722B6858E9}.Debug|x64.Build.0 = Debug|x64
+ {35397DDA-DDC7-46BE-A802-3B722B6858E9}.Debug|x86.ActiveCfg = Debug|Win32
+ {35397DDA-DDC7-46BE-A802-3B722B6858E9}.Debug|x86.Build.0 = Debug|Win32
+ {35397DDA-DDC7-46BE-A802-3B722B6858E9}.Release|Any CPU.ActiveCfg = Release|Win32
+ {35397DDA-DDC7-46BE-A802-3B722B6858E9}.Release|x64.ActiveCfg = Release|x64
+ {35397DDA-DDC7-46BE-A802-3B722B6858E9}.Release|x64.Build.0 = Release|x64
+ {35397DDA-DDC7-46BE-A802-3B722B6858E9}.Release|x86.ActiveCfg = Release|Win32
+ {35397DDA-DDC7-46BE-A802-3B722B6858E9}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {37E45CE1-A0F6-4ED7-9791-A1BED947602F} = {5F6BBAA8-EAD0-4B18-97E5-55B4F56DD760}
+ {DE5AB980-A9AD-4273-8272-C4E1E062E3EC} = {5F6BBAA8-EAD0-4B18-97E5-55B4F56DD760}
+ {1971345A-0627-4428-88AA-1CCC4BFAEF4B} = {5F6BBAA8-EAD0-4B18-97E5-55B4F56DD760}
+ {372401B3-FFEB-483F-965F-261506B3FDFB} = {5F6BBAA8-EAD0-4B18-97E5-55B4F56DD760}
+ {35397DDA-DDC7-46BE-A802-3B722B6858E9} = {4443B71C-216E-4D4C-8D19-868F50803813}
+ EndGlobalSection
+EndGlobal
diff --git a/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/App.config b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/App.config
new file mode 100644
index 000000000..8e1564635
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/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/Utilities/Tango.MachineEM.UI/App.xaml b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/App.xaml
new file mode 100644
index 000000000..f43a3b797
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/App.xaml
@@ -0,0 +1,26 @@
+<Application x:Class="Tango.MachineEM.UI.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:vm="clr-namespace:Tango.MachineEM.UI.ViewModels"
+ xmlns:local="clr-namespace:Tango.MachineEM.UI"
+ 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" />
+
+ <!--View Models-->
+ <ResourceDictionary>
+ <vm:MainViewVM x:Key="MainViewVM" />
+ </ResourceDictionary>
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </Application.Resources>
+</Application>
diff --git a/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/App.xaml.cs b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/App.xaml.cs
new file mode 100644
index 000000000..24222d957
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/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.MachineEM.UI
+{
+ /// <summary>
+ /// Interaction logic for App.xaml
+ /// </summary>
+ public partial class App : Application
+ {
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Images/machine-trans.png b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Images/machine-trans.png
new file mode 100644
index 000000000..a7cf65852
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Images/machine-trans.png
Binary files differ
diff --git a/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/MainWindow.xaml b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/MainWindow.xaml
new file mode 100644
index 000000000..318a4133e
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/MainWindow.xaml
@@ -0,0 +1,16 @@
+<mahapps:MetroWindow x:Class="Tango.MachineEM.UI.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.MachineEM.UI"
+ xmlns:views="clr-namespace:Tango.MachineEM.UI.Views"
+ 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>
+ <views:MainView DataContext="{StaticResource MainViewVM}"></views:MainView>
+ </Grid>
+</mahapps:MetroWindow>
diff --git a/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/MainWindow.xaml.cs b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/MainWindow.xaml.cs
new file mode 100644
index 000000000..7baded308
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/MainWindow.xaml.cs
@@ -0,0 +1,33 @@
+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.Logging;
+
+namespace Tango.MachineEM.UI
+{
+ /// <summary>
+ /// Interaction logic for MainWindow.xaml
+ /// </summary>
+ public partial class MainWindow : MetroWindow
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MainWindow"/> class.
+ /// </summary>
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..67dc85fcd
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Machine Emulator")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Properties/Resources.Designer.cs b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..03267e59a
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/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.MachineEM.UI.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.MachineEM.UI.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/Utilities/Tango.MachineEM.UI/Properties/Resources.resx b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Properties/Resources.resx
new file mode 100644
index 000000000..af7dbebba
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/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/Utilities/Tango.MachineEM.UI/Properties/Settings.Designer.cs b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..01ea89440
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/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.MachineEM.UI.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/Utilities/Tango.MachineEM.UI/Properties/Settings.settings b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Properties/Settings.settings
new file mode 100644
index 000000000..033d7a5e9
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/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/Utilities/Tango.MachineEM.UI/Tango.MachineEM.UI.csproj b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Tango.MachineEM.UI.csproj
new file mode 100644
index 000000000..79e395584
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Tango.MachineEM.UI.csproj
@@ -0,0 +1,156 @@
+<?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>{1971345A-0627-4428-88AA-1CCC4BFAEF4B}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <RootNamespace>Tango.MachineEM.UI</RootNamespace>
+ <AssemblyName>Tango.MachineEM.UI</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.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>
+ <Private>True</Private>
+ </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>
+ <Compile Include="ViewModels\MainViewVM.cs" />
+ <Compile Include="Views\MainView.xaml.cs">
+ <DependentUpon>MainView.xaml</DependentUpon>
+ </Compile>
+ <Page Include="MainWindow.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <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>
+ <Page Include="Views\MainView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ </ItemGroup>
+ <ItemGroup>
+ <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>
+ <Resource Include="Images\machine-trans.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Emulations\Tango.Emulations.csproj">
+ <Project>{63561e19-ff5a-414b-a5ef-e30711543e1d}</Project>
+ <Name>Tango.Emulations</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>
+ <ProjectReference Include="..\..\Tango.Stubs\Tango.Stubs.csproj">
+ <Project>{1981b537-39e9-4e7d-8430-27466481aeee}</Project>
+ <Name>Tango.Stubs</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Transport\Tango.Transport.csproj">
+ <Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
+ <Name>Tango.Transport</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/ViewModels/MainViewVM.cs
new file mode 100644
index 000000000..7b70b277e
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/ViewModels/MainViewVM.cs
@@ -0,0 +1,242 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Emulations.Emulators;
+using Tango.Logging;
+using Tango.SharedUI;
+using Tango.SharedUI.Commands;
+using Tango.Stubs;
+using Tango.Transport.Adapters;
+using Tango.Transport.Servers;
+using Tango.Transport.Transporters;
+
+namespace Tango.MachineEM.UI.ViewModels
+{
+ public class MainViewVM : ExtendedObject
+ {
+ private TcpServer TcpServer;
+ private bool _running;
+
+ #region Properties
+
+ private MachineEmulator _emulator;
+ /// <summary>
+ /// Gets or sets the machine emulator.
+ /// </summary>
+ public MachineEmulator Emulator
+ {
+ get { return _emulator; }
+ set { _emulator = value; RaisePropertyChanged(nameof(Emulator)); }
+ }
+
+ private String _log;
+ /// <summary>
+ /// Gets or sets the log.
+ /// </summary>
+ public String Log
+ {
+ get { return _log; }
+ set { _log = value; RaisePropertyChanged(nameof(Log)); }
+ }
+
+ /// <summary>
+ /// Gets or sets the available stubs.
+ /// </summary>
+ public List<AvailableStub> AvailableStubs { get; set; }
+
+ private AvailableStub _selectedAvailableStub;
+ /// <summary>
+ /// Gets or sets the selected available stub.
+ /// </summary>
+ public AvailableStub SelectedAvailableStub
+ {
+ get { return _selectedAvailableStub; }
+ set
+ {
+ _selectedAvailableStub = value; RaisePropertyChanged(nameof(SelectedAvailableStub));
+ OnStubSelected(value);
+ }
+ }
+
+ private StubBase _selectedStub;
+ /// <summary>
+ /// Gets or sets the selected stub.
+ /// </summary>
+ public StubBase SelectedStub
+ {
+ get { return _selectedStub; }
+ set { _selectedStub = value; RaisePropertyChanged(nameof(SelectedStub)); }
+ }
+
+
+ #endregion
+
+ #region Private Methods
+
+ /// <summary>
+ /// Called when available stub is selected.
+ /// </summary>
+ /// <param name="availableStub">The available stub.</param>
+ private void OnStubSelected(AvailableStub availableStub)
+ {
+ if (availableStub != null)
+ {
+ SelectedStub = availableStub.CreateInstance(Emulator.Transporter);
+ }
+ }
+
+ #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 run command.
+ /// </summary>
+ public RelayCommand RunCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the cancel command.
+ /// </summary>
+ public RelayCommand CancelCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the clear command.
+ /// </summary>
+ public RelayCommand ClearCommand { get; set; }
+
+ #endregion
+
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MainViewVM"/> class.
+ /// </summary>
+ public MainViewVM()
+ {
+ MainViewLogger logger = new MainViewLogger();
+ logger.NewLog += (output) =>
+ {
+ Log += output + Environment.NewLine;
+ };
+
+ LogManager.RegisterLogger(logger);
+
+ Emulator = new MachineEmulator(new ProtoTransporter());
+
+ StartCommand = new RelayCommand(Start, (x) => !Emulator.IsStarted);
+ StopCommand = new RelayCommand(Stop,(x) => Emulator.IsStarted);
+ RunCommand = new RelayCommand(RunSelectedStub, (x) => !_running);
+ CancelCommand = new RelayCommand(Cancel, (x) => _running);
+ ClearCommand = new RelayCommand(() => Log = String.Empty);
+
+ AvailableStubs = StubBase.GetAvailableStubs(StubDirection.ToMobile);
+ }
+
+ #endregion
+
+ #region Event Handlers
+
+ /// <summary>
+ /// Handles the ClientConnected event of the TcpServer control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="ClientConnectedEventArgs"/> instance containing the event data.</param>
+ private void TcpServer_ClientConnected(object sender, ClientConnectedEventArgs e)
+ {
+ Emulator.Transporter.Adapters.Add(new TcpTransportAdapter(e.Socket));
+ }
+
+ #endregion
+
+ #region Command Handlers
+
+ /// <summary>
+ /// Stops the TCP server and emulator.
+ /// </summary>
+ private async void Start()
+ {
+ TcpServer = new TcpServer(9999);
+ TcpServer.ClientConnected += TcpServer_ClientConnected;
+ TcpServer.Start();
+ await Emulator.Start();
+ InvalidateRelayCommands();
+ }
+
+ /// <summary>
+ /// Starts the TCP server/USB and emulator.
+ /// </summary>
+ private async void Stop()
+ {
+ TcpServer.Stop();
+ await Emulator.Stop();
+ InvalidateRelayCommands();
+ }
+
+ /// <summary>
+ /// Runs the selected stub.
+ /// </summary>
+ private async void RunSelectedStub()
+ {
+ _running = true;
+ InvalidateRelayCommands();
+ var result = await SelectedStub.Run((response) =>
+ {
+ _running = false;
+ Log += response + Environment.NewLine;
+ InvalidateRelayCommands();
+
+ });
+
+ Log += result + Environment.NewLine;
+
+ _running = false;
+ InvalidateRelayCommands();
+ }
+
+ private async void Cancel()
+ {
+
+ }
+
+ #endregion
+
+ #region Custom Logger
+
+ public class MainViewLogger : ILogger
+ {
+ public bool Enabled { get; set; }
+ public bool Immediate { get; set; }
+ public event Action<String> NewLog;
+
+ public MainViewLogger()
+ {
+ Enabled = true;
+ Immediate = true;
+ }
+
+ public void OnError(LogItemBase output)
+ {
+ NewLog?.Invoke(output.ToString());
+ }
+
+ public void OnTrace(LogItemBase output)
+ {
+ NewLog?.Invoke(output.ToString());
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Views/MainView.xaml b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Views/MainView.xaml
new file mode 100644
index 000000000..c2068acf7
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Views/MainView.xaml
@@ -0,0 +1,154 @@
+<UserControl x:Class="Tango.MachineEM.UI.Views.MainView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:editors="clr-namespace:Tango.SharedUI.Editors;assembly=Tango.SharedUI"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:local="clr-namespace:Tango.MachineEM.UI.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="720" d:DesignWidth="1000" Foreground="Gainsboro">
+ <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>
+
+ <Grid Background="#181818">
+ <Grid Margin="10 0 10 0">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="40"/>
+ <RowDefinition Height="346*"/>
+ <RowDefinition Height="70"/>
+ </Grid.RowDefinitions>
+
+ <TextBlock VerticalAlignment="Center" FontSize="16" Foreground="#BB1404" FontWeight="Bold">STUBS</TextBlock>
+
+ <ListBox Grid.Row="1" ItemsSource="{Binding AvailableStubs}" SelectedItem="{Binding SelectedAvailableStub}" SelectedIndex="-1">
+ <ListBox.ItemTemplate>
+ <DataTemplate>
+ <Grid>
+ <StackPanel Orientation="Horizontal" Margin="2 10 0 10">
+ <fa:ImageAwesome Icon="Cogs" Foreground="Gray" Width="24" Height="24" VerticalAlignment="Center"></fa:ImageAwesome>
+ <StackPanel Margin="5 0 0 0" VerticalAlignment="Center">
+ <TextBlock Margin="2" FontSize="14" Text="{Binding Name}"></TextBlock>
+ <TextBlock Margin="2" FontSize="12" Text="{Binding Description}"></TextBlock>
+ </StackPanel>
+ </StackPanel>
+ <Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Stroke="Black" StrokeThickness="1"></Rectangle>
+ </Grid>
+ </DataTemplate>
+ </ListBox.ItemTemplate>
+ </ListBox>
+
+ <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right">
+ <Button Cursor="Hand" Width="50" Height="50" VerticalAlignment="Center" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding ClearCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Refresh" Foreground="Gainsboro" Width="24"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+ <Button Cursor="Hand" Width="50" Height="50" VerticalAlignment="Center" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding CancelCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Stop" Foreground="Red" Width="24"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+ <Button Cursor="Hand" Width="50" Height="50" VerticalAlignment="Center" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding RunCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Play" Width="24" Foreground="LimeGreen"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+ </StackPanel>
+ </Grid>
+ </Grid>
+
+ <Grid Grid.Column="1">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="107*"/>
+ <RowDefinition Height="60*"/>
+ </Grid.RowDefinitions>
+
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="200"/>
+ <ColumnDefinition Width="1*"/>
+ </Grid.ColumnDefinitions>
+
+ <Grid>
+ <GroupBox Header="PARAMETERS" Padding="5">
+ <Grid Background="#252525">
+ <editors:ParameterizedEditor ParameterizedObject="{Binding SelectedStub}" ItemMargin="10" ItemLabelMargin="0 0 0 5" />
+ </Grid>
+ </GroupBox>
+ </Grid>
+ </Grid>
+
+ <Grid Grid.Row="1">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="30"/>
+ <RowDefinition Height="1*"/>
+ </Grid.RowDefinitions>
+
+ <Border Background="#202020" Padding="5" CornerRadius="10 0 0 10">
+ <TextBlock FontSize="16" VerticalAlignment="Center">LOG</TextBlock>
+ </Border>
+
+ <Grid Grid.Row="1">
+ <TextBox x:Name="txtResponse" IsReadOnly="True" TextChanged="txtResponse_TextChanged" Text="{Binding Log}" Background="Black" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" BorderThickness="0" Padding="5" FontSize="11" Foreground="Gainsboro"></TextBox>
+ </Grid>
+ </Grid>
+ </Grid>
+ </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>
+</UserControl>
diff --git a/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Views/MainView.xaml.cs b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Views/MainView.xaml.cs
new file mode 100644
index 000000000..9112f28f4
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/Views/MainView.xaml.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Tango.MachineEM.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for MainView.xaml
+ /// </summary>
+ public partial class MainView : UserControl
+ {
+ public MainView()
+ {
+ InitializeComponent();
+ }
+
+ private void txtResponse_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ //txtResponse.ScrollToEnd();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/packages.config b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/packages.config
new file mode 100644
index 000000000..9cbe8b937
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MachineEM.UI/packages.config
@@ -0,0 +1,6 @@
+<?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" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.config b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.config
new file mode 100644
index 000000000..8e1564635
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/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/Utilities/Tango.MobileEM.UI/App.xaml b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.xaml
new file mode 100644
index 000000000..83d97bea5
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.xaml
@@ -0,0 +1,28 @@
+<Application x:Class="Tango.MobileEM.UI.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:vm="clr-namespace:Tango.MobileEM.UI.ViewModels"
+ xmlns:local="clr-namespace:Tango.MobileEM.UI"
+ 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" />
+
+ <!--View Models-->
+ <ResourceDictionary>
+ <vm:MainWindowVM x:Key="MainWindowVM"></vm:MainWindowVM>
+ <vm:MainViewVM x:Key="MainViewVM"></vm:MainViewVM>
+ <vm:StubsViewVM x:Key="StubsViewVM"></vm:StubsViewVM>
+ </ResourceDictionary>
+ </ResourceDictionary.MergedDictionaries>
+ </ResourceDictionary>
+ </Application.Resources>
+</Application>
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.xaml.cs b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.xaml.cs
new file mode 100644
index 000000000..57e3ddcad
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/App.xaml.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.Emulations.Emulators;
+using Tango.Transport.Adapters;
+using Tango.Transport.Transporters;
+
+namespace Tango.MobileEM.UI
+{
+ /// <summary>
+ /// Interaction logic for App.xaml
+ /// </summary>
+ public partial class App : Application
+ {
+ public static MobileEmulator Emulator { get; set; }
+
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ base.OnStartup(e);
+ Emulator = new MobileEmulator(new ProtoTransporter(new TcpTransportAdapter("127.0.0.1", 9999)));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Images/phone.png b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Images/phone.png
new file mode 100644
index 000000000..d93503adc
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Images/phone.png
Binary files differ
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml
new file mode 100644
index 000000000..1280b76f8
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml
@@ -0,0 +1,81 @@
+<mahapps:MetroWindow x:Class="Tango.MobileEM.UI.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:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI"
+ xmlns:views="clr-namespace:Tango.MobileEM.UI.Views"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:local="clr-namespace:Tango.MobileEM.UI"
+ mc:Ignorable="d"
+ Title="Tango Machine Emulator" Height="668" Width="416" TitleCaps="False" BorderBrush="Gray" BorderThickness="1" WindowStartupLocation="CenterScreen" Background="#202020" Foreground="Gainsboro" DataContext="{StaticResource MainWindowVM}">
+ <Grid>
+ <Grid>
+ <Image Source="Images/phone.png" RenderOptions.BitmapScalingMode="Fant" Stretch="Fill"></Image>
+
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="52*"/>
+ <ColumnDefinition Width="237*"/>
+ <ColumnDefinition Width="55*"/>
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="81*"/>
+ <RowDefinition Height="379*"/>
+ <RowDefinition Height="65*"/>
+ </Grid.RowDefinitions>
+
+ <Grid Grid.Column="1" Grid.Row="1">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="1*"/>
+ <RowDefinition Height="40"/>
+ </Grid.RowDefinitions>
+
+ <controls:MultiTransitionControl x:Name="TransitionControl" AlwaysFade="True" TransitionType="Zoom" AnimationTime="500">
+ <controls:MultiTransitionControl.Controls>
+ <ContentControl Tag="MainView">
+ <views:MainView DataContext="{StaticResource MainViewVM}"></views:MainView>
+ </ContentControl>
+ <ContentControl Tag="StubsView">
+ <views:StubsView DataContext="{StaticResource StubsViewVM}"></views:StubsView>
+ </ContentControl>
+ <ContentControl Tag="StubView">
+ <views:StubView></views:StubView>
+ </ContentControl>
+ </controls:MultiTransitionControl.Controls>
+ </controls:MultiTransitionControl>
+
+ <Grid Grid.Row="1" Background="#151515">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="40"/>
+ <ColumnDefinition Width="1*"/>
+ </Grid.ColumnDefinitions>
+
+ <Button Margin="5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding BackCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="ArrowLeft" Width="16"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+
+ <UniformGrid Columns="2" Grid.Column="1">
+ <Button Margin="5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding Emulator.StopCommand}">
+ <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 5 0 5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding Emulator.StartCommand}">
+ <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>
+ </Grid>
+</mahapps:MetroWindow>
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml.cs b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml.cs
new file mode 100644
index 000000000..f003f708f
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/MainWindow.xaml.cs
@@ -0,0 +1,48 @@
+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.Emulations.Emulators;
+using Tango.Logging;
+using Tango.SharedUI.Commands;
+using Tango.Transport.Adapters;
+using Tango.Transport.Transporters;
+
+namespace Tango.MobileEM.UI
+{
+ /// <summary>
+ /// Interaction logic for MainWindow.xaml
+ /// </summary>
+ public partial class MainWindow : MetroWindow
+ {
+ public static MainWindow Instance { get; private set; }
+
+ public MainWindow()
+ {
+ LogManager.RegisterLogger(new VSOutputLogger());
+ InitializeComponent();
+ Instance = this;
+ }
+
+ public static void NavigateTo(Type view)
+ {
+ Instance.TransitionControl.AutoNavigate(view.Name);
+ }
+
+ public static void NavigateTo(Type view, object context)
+ {
+ Instance.TransitionControl.AutoNavigate(view.Name, context);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..e603a7590
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Mobile Emulator")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Properties/Resources.Designer.cs b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..979ab736c
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/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.MobileEM.UI.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.MobileEM.UI.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/Utilities/Tango.MobileEM.UI/Properties/Resources.resx b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Properties/Resources.resx
new file mode 100644
index 000000000..af7dbebba
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/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/Utilities/Tango.MobileEM.UI/Properties/Settings.Designer.cs b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..ed8de364e
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/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.MobileEM.UI.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/Utilities/Tango.MobileEM.UI/Properties/Settings.settings b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Properties/Settings.settings
new file mode 100644
index 000000000..033d7a5e9
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/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/Utilities/Tango.MobileEM.UI/Tango.MobileEM.UI.csproj b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Tango.MobileEM.UI.csproj
new file mode 100644
index 000000000..9546deaed
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Tango.MobileEM.UI.csproj
@@ -0,0 +1,173 @@
+<?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>{372401B3-FFEB-483F-965F-261506B3FDFB}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <RootNamespace>Tango.MobileEM.UI</RootNamespace>
+ <AssemblyName>Tango.MobileEM.UI</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.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>
+ <Private>True</Private>
+ </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>
+ <Compile Include="ViewModels\MainViewVM.cs" />
+ <Compile Include="ViewModels\MainWindowVM.cs" />
+ <Compile Include="ViewModels\StubsViewVM.cs" />
+ <Compile Include="ViewModels\StubViewVM.cs" />
+ <Compile Include="Views\MainView.xaml.cs">
+ <DependentUpon>MainView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Views\StubsView.xaml.cs">
+ <DependentUpon>StubsView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Views\StubView.xaml.cs">
+ <DependentUpon>StubView.xaml</DependentUpon>
+ </Compile>
+ <Page Include="MainWindow.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <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>
+ <Page Include="Views\MainView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Views\StubsView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Views\StubView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ </ItemGroup>
+ <ItemGroup>
+ <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>
+ <Resource Include="Images\phone.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Emulations\Tango.Emulations.csproj">
+ <Project>{63561e19-ff5a-414b-a5ef-e30711543e1d}</Project>
+ <Name>Tango.Emulations</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>
+ <ProjectReference Include="..\..\Tango.Stubs\Tango.Stubs.csproj">
+ <Project>{1981b537-39e9-4e7d-8430-27466481aeee}</Project>
+ <Name>Tango.Stubs</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Transport\Tango.Transport.csproj">
+ <Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
+ <Name>Tango.Transport</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainViewVM.cs
new file mode 100644
index 000000000..fdb751422
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainViewVM.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.MobileEM.UI.Views;
+using Tango.SharedUI;
+using Tango.SharedUI.Commands;
+
+namespace Tango.MobileEM.UI.ViewModels
+{
+ public class MainViewVM : ExtendedObject
+ {
+ #region Commands
+
+ public RelayCommand StubsCommand { get; set; }
+
+ #endregion
+
+ public MainViewVM()
+ {
+ StubsCommand = new RelayCommand(NavigateToStubs);
+ }
+
+ private void NavigateToStubs()
+ {
+ MainWindow.NavigateTo(typeof(StubsView));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainWindowVM.cs b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainWindowVM.cs
new file mode 100644
index 000000000..cd5c9bf93
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/MainWindowVM.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Emulations.Emulators;
+using Tango.MobileEM.UI.Views;
+using Tango.SharedUI;
+using Tango.SharedUI.Commands;
+using Tango.Transport.Adapters;
+using Tango.Transport.Transporters;
+
+namespace Tango.MobileEM.UI.ViewModels
+{
+ public class MainWindowVM : ExtendedObject
+ {
+ /// <summary>
+ /// Gets or sets the mobile emulator.
+ /// </summary>
+ public MobileEmulator Emulator
+ {
+ get { return App.Emulator; }
+ }
+
+ public RelayCommand BackCommand { get; set; }
+
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MainWindowVM"/> class.
+ /// </summary>
+ public MainWindowVM()
+ {
+ BackCommand = new RelayCommand(Back);
+ }
+
+ private void Back()
+ {
+ MainWindow.NavigateTo(typeof(MainView));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubViewVM.cs b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubViewVM.cs
new file mode 100644
index 000000000..29aed851b
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubViewVM.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Documents;
+using Tango.Logging;
+using Tango.SharedUI;
+using Tango.SharedUI.Commands;
+using Tango.Stubs;
+
+namespace Tango.MobileEM.UI.ViewModels
+{
+ public class StubViewVM : ExtendedObject
+ {
+ private bool _running;
+
+ public RelayCommand RunCommand { get; set; }
+ public RelayCommand CancelCommand { get; set; }
+ public RelayCommand ClearCommand { get; set; }
+ public StubBase Stub { get; set; }
+ public AvailableStub AvailableStub { get; set; }
+
+ private String _response;
+
+ public String Response
+ {
+ get { return _response; }
+ set { _response = value; RaisePropertyChanged(nameof(Response)); }
+ }
+
+
+ public StubViewVM(AvailableStub availableStub, StubBase stub)
+ {
+ AvailableStub = availableStub;
+ Stub = stub;
+ RunCommand = new RelayCommand(Run,(x) => !_running);
+ CancelCommand = new RelayCommand(Cancel,(x) => _running);
+ ClearCommand = new RelayCommand(() => Response = String.Empty);
+ }
+
+ private async void Run()
+ {
+ _running = true;
+ InvalidateRelayCommands();
+ var result = await Stub.Run((response) =>
+ {
+ _running = false;
+ Response += response + Environment.NewLine;
+ InvalidateRelayCommands();
+
+ });
+
+ Response += result + Environment.NewLine;
+
+ _running = false;
+ InvalidateRelayCommands();
+ }
+
+ private async void Cancel()
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubsViewVM.cs b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubsViewVM.cs
new file mode 100644
index 000000000..dc17d5cdc
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/ViewModels/StubsViewVM.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.MobileEM.UI.Views;
+using Tango.SharedUI;
+using Tango.Stubs;
+
+namespace Tango.MobileEM.UI.ViewModels
+{
+ public class StubsViewVM : ExtendedObject
+ {
+ public List<AvailableStub> AvailableStubs { get; set; }
+ private AvailableStub _selectedStub;
+
+ public AvailableStub SelectedStub
+ {
+ get { return _selectedStub; }
+ set
+ {
+ _selectedStub = value; RaisePropertyChanged(nameof(SelectedStub));
+ OnStubSelected(value);
+ }
+ }
+
+
+ public StubsViewVM()
+ {
+ AvailableStubs = StubBase.GetAvailableStubs(StubDirection.ToMachine);
+ }
+
+ private void OnStubSelected(AvailableStub availableStub)
+ {
+ if (availableStub != null)
+ {
+ StubBase stub = availableStub.CreateInstance(App.Emulator.Transporter);
+ MainWindow.NavigateTo(typeof(StubView), new StubViewVM(availableStub, stub));
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml
new file mode 100644
index 000000000..3c8caa918
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml
@@ -0,0 +1,29 @@
+<UserControl x:Class="Tango.MobileEM.UI.Views.MainView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:local="clr-namespace:Tango.MobileEM.UI.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="300" d:DesignWidth="200">
+
+ <Grid Margin="20">
+ <UniformGrid Rows="2">
+ <Button Width="100" Height="100" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding StubsCommand}">
+ <StackPanel Orientation="Vertical">
+ <fa:ImageAwesome Icon="Cogs" Width="32"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="10">Stubs</TextBlock>
+ </StackPanel>
+ </Button>
+
+ <Button Width="100" Height="100" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding MonitoringCommand}">
+ <StackPanel Orientation="Vertical">
+ <fa:ImageAwesome Icon="Gratipay" Width="32"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="10">Monitoring</TextBlock>
+ </StackPanel>
+ </Button>
+ </UniformGrid>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml.cs b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml.cs
new file mode 100644
index 000000000..c33fb0fe1
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/MainView.xaml.cs
@@ -0,0 +1,29 @@
+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.SharedUI.Commands;
+
+namespace Tango.MobileEM.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for MainView.xaml
+ /// </summary>
+ public partial class MainView : UserControl
+ {
+ public MainView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml
new file mode 100644
index 000000000..c0fa65b91
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml
@@ -0,0 +1,73 @@
+<UserControl x:Class="Tango.MobileEM.UI.Views.StubView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:editors="clr-namespace:Tango.SharedUI.Editors;assembly=Tango.SharedUI"
+ xmlns:local="clr-namespace:Tango.MobileEM.UI.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="400" d:DesignWidth="300">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="50"/>
+ <RowDefinition Height="105*"/>
+ <RowDefinition Height="68*"/>
+ </Grid.RowDefinitions>
+ <Grid VerticalAlignment="Top" Background="#151515">
+ <StackPanel Orientation="Horizontal" Margin="5">
+ <fa:ImageAwesome Icon="Cogs" Foreground="Red" Width="24" Height="24" VerticalAlignment="Center"></fa:ImageAwesome>
+ <StackPanel Margin="5 0 0 0" VerticalAlignment="Center">
+ <TextBlock Margin="2" FontSize="14" Text="{Binding AvailableStub.Name}"></TextBlock>
+ <TextBlock Margin="2" FontSize="12" Text="{Binding AvailableStub.Description}"></TextBlock>
+ </StackPanel>
+ </StackPanel>
+ </Grid>
+
+ <Grid Grid.Row="1" Background="#202020">
+ <editors:ParameterizedEditor ParameterizedObject="{Binding Stub}" Margin="10" ItemMargin="10" ItemLabelMargin="0 0 0 5" />
+ </Grid>
+
+ <Grid Grid.Row="2">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="1*"/>
+ <RowDefinition Height="40"/>
+ </Grid.RowDefinitions>
+
+ <Grid Background="Black">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="20"/>
+ <RowDefinition Height="40*"/>
+ </Grid.RowDefinitions>
+
+ <TextBlock Background="#151515" Foreground="Red" VerticalAlignment="Center" FontSize="11" Margin="5 0 0 0">Response</TextBlock>
+
+ <TextBox x:Name="txtResponse" TextChanged="txtResponse_TextChanged" Grid.Row="1" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" Background="Transparent" Foreground="Gainsboro" FontSize="10" BorderThickness="0" IsReadOnly="True" Padding="5" Text="{Binding Response}">
+
+ </TextBox>
+ </Grid>
+
+ <Grid Grid.Row="1" Background="Black">
+ <Rectangle VerticalAlignment="Top" Stroke="#202020" StrokeThickness="1"></Rectangle>
+ <UniformGrid Columns="3" HorizontalAlignment="Right">
+ <Button Cursor="Hand" Width="35" Height="35" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding ClearCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Refresh" Foreground="Gainsboro" Width="16"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+ <Button Cursor="Hand" Width="35" Height="35" VerticalAlignment="Center" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding CancelCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Stop" Foreground="Red" Width="16"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+ <Button Cursor="Hand" Width="35" Height="35" VerticalAlignment="Center" Style="{DynamicResource MetroCircleButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding RunCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Play" Width="16" Foreground="LimeGreen"></fa:ImageAwesome>
+ </StackPanel>
+ </Button>
+ </UniformGrid>
+ </Grid>
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml.cs b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml.cs
new file mode 100644
index 000000000..8ce034020
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubView.xaml.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Tango.MobileEM.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for StubView.xaml
+ /// </summary>
+ public partial class StubView : UserControl
+ {
+ public StubView()
+ {
+ InitializeComponent();
+ }
+
+ private void txtResponse_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ txtResponse.ScrollToEnd();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml
new file mode 100644
index 000000000..effbd48fe
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml
@@ -0,0 +1,28 @@
+<UserControl x:Class="Tango.MobileEM.UI.Views.StubsView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:local="clr-namespace:Tango.MobileEM.UI.Views"
+ mc:Ignorable="d"
+ d:DesignHeight="300" d:DesignWidth="200">
+ <Grid>
+ <ListBox x:Name="list" Background="Transparent" ItemsSource="{Binding AvailableStubs}" SelectedItem="{Binding SelectedStub}" SelectedIndex="-1" SelectionChanged="ListBox_SelectionChanged">
+ <ListBox.ItemTemplate>
+ <DataTemplate>
+ <Grid>
+ <StackPanel Orientation="Horizontal" Margin="2 10 0 10">
+ <fa:ImageAwesome Icon="Cogs" Foreground="Red" Width="24" Height="24" VerticalAlignment="Center"></fa:ImageAwesome>
+ <StackPanel Margin="5 0 0 0" VerticalAlignment="Center">
+ <TextBlock Margin="2" FontSize="14" Text="{Binding Name}"></TextBlock>
+ <TextBlock Margin="2" FontSize="12" Text="{Binding Description}"></TextBlock>
+ </StackPanel>
+ </StackPanel>
+ <Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Stroke="Black" StrokeThickness="1"></Rectangle>
+ </Grid>
+ </DataTemplate>
+ </ListBox.ItemTemplate>
+ </ListBox>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml.cs b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml.cs
new file mode 100644
index 000000000..7c42ba82c
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/Views/StubsView.xaml.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Tango.MobileEM.UI.Views
+{
+ /// <summary>
+ /// Interaction logic for StubsView.xaml
+ /// </summary>
+ public partial class StubsView : UserControl
+ {
+ public StubsView()
+ {
+ InitializeComponent();
+ }
+
+ private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (e.AddedItems.Count > 0)
+ {
+ list.SelectedIndex = -1;
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/packages.config b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/packages.config
new file mode 100644
index 000000000..9cbe8b937
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.MobileEM.UI/packages.config
@@ -0,0 +1,6 @@
+<?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" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/App.config b/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/App.config
new file mode 100644
index 000000000..8e1564635
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/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/Utilities/Tango.Protobuf.CLI/Options.cs b/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Options.cs
new file mode 100644
index 000000000..321ab4494
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Options.cs
@@ -0,0 +1,32 @@
+using CommandLine;
+using CommandLine.Text;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf.CLI
+{
+ public class Options
+ {
+ [Option('i', Required = true, HelpText = "Source folder to compile.")]
+ public String SourceFolder { get; set; }
+
+ [Option('o', Required = true, HelpText = "Output folder to save the compiled files.")]
+ public String OutputFolder { get; set; }
+
+ [Option('l', Required = true, HelpText = "Target language.")]
+ public String Language { get; set; }
+
+ [ParserState]
+ public IParserState LastParserState { get; set; }
+
+ [HelpOption]
+ public string GetUsage()
+ {
+ return HelpText.AutoBuild(this,
+ (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Program.cs b/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Program.cs
new file mode 100644
index 000000000..123de0996
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Program.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf.CLI
+{
+ class Program
+ {
+ static int Main(string[] args)
+ {
+ if (args.Length == 0)
+ {
+ return ExitHelp();
+ }
+
+ var options = new Options();
+
+ if (CommandLine.Parser.Default.ParseArguments(args, options))
+ {
+ if (!Directory.Exists(options.SourceFolder))
+ {
+ return ExitError("Could not locate source folder \"" + Path.GetFullPath(options.SourceFolder) + "\"");
+ }
+ if (!Directory.Exists(options.OutputFolder))
+ {
+ return ExitError("Could not locate output folder " + Path.GetFullPath(options.OutputFolder));
+ }
+
+ CompilerLanguage language;
+ if (!Enum.TryParse<CompilerLanguage>(options.Language, out language))
+ {
+ return ExitError("Invalid language: " + options.Language);
+ }
+
+ try
+ {
+ var compiler = CompilerFactory.CreateCompiler(language);
+ var result = compiler.CompileFolder(Path.GetFullPath(options.SourceFolder));
+ result.Save(Path.GetFullPath(options.OutputFolder));
+ }
+ catch (Exception ex)
+ {
+ return ExitError(ex.Message);
+ }
+ }
+
+ return ExitSuccess("Protobuf folder compiled to " + Path.GetFullPath(options.OutputFolder));
+ }
+
+ private static int ExitSuccess(String text)
+ {
+ Console.WriteLine(text);
+ return 0;
+ }
+
+ private static int ExitError(String error)
+ {
+ Console.WriteLine(error);
+ return -1;
+ }
+
+ private static int ExitHelp()
+ {
+ Console.WriteLine(
+@"
+ Example: proto-tc -i <source folder> -o <output folder> -l <language>
+
+ Available -l arguments:
+
+ CSharp
+ Java
+ JavaNano
+ CPP
+ C
+ EmbeddedC
+ JS
+ Python
+ PHP
+ Ruby
+");
+
+ return -1;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..316919706
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Protobuf Compilation CLI")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Tango.Protobuf.CLI.csproj b/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Tango.Protobuf.CLI.csproj
new file mode 100644
index 000000000..537920dac
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/Tango.Protobuf.CLI.csproj
@@ -0,0 +1,65 @@
+<?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>{DE5AB980-A9AD-4273-8272-C4E1E062E3EC}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>Tango.Protobuf.CLI</RootNamespace>
+ <AssemblyName>proto-tc</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </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="CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <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" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\..\Versioning\GlobalVersionInfo.cs">
+ <Link>GlobalVersionInfo.cs</Link>
+ </Compile>
+ <Compile Include="Options.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Tango.Protobuf\Tango.Protobuf.csproj">
+ <Project>{40073806-914e-4e78-97ab-fa9639308ebe}</Project>
+ <Name>Tango.Protobuf</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/packages.config b/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/packages.config
new file mode 100644
index 000000000..0d9f59112
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.CLI/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="CommandLineParser" version="1.9.71" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/App.config b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/App.config
new file mode 100644
index 000000000..8e1564635
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/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/Utilities/Tango.Protobuf.UI/App.xaml b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/App.xaml
new file mode 100644
index 000000000..d9f8d9bfa
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/App.xaml
@@ -0,0 +1,20 @@
+<Application x:Class="Tango.Protobuf.UI.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="clr-namespace:Tango.Protobuf.UI"
+ 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/Steel.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/Utilities/Tango.Protobuf.UI/App.xaml.cs b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/App.xaml.cs
new file mode 100644
index 000000000..d2560005a
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/App.xaml.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+using Tango.Logging;
+
+namespace Tango.Protobuf.UI
+{
+ /// <summary>
+ /// Interaction logic for App.xaml
+ /// </summary>
+ public partial class App : Application
+ {
+ private WpfGlobalExceptionTrapper exceptionTrapper;
+
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ base.OnStartup(e);
+
+ //Register Loggers.
+ LogManager.RegisterLogger(new FileLogger());
+ LogManager.RegisterLogger(new VSOutputLogger());
+
+ LogManager.Log("Application Started!");
+
+ exceptionTrapper = new WpfGlobalExceptionTrapper();
+ exceptionTrapper.Initialize(this);
+ exceptionTrapper.ApplicationCrashed += ExceptionTrapper_ApplicationCrashed;
+ }
+
+ #region Global Exception Trapping
+
+ /// <summary>
+ /// Handles the ApplicationCrashed event of the ExceptionTrapper control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="ApplicationCrashedEventArgs"/> instance containing the event data.</param>
+ private void ExceptionTrapper_ApplicationCrashed(object sender, ApplicationCrashedEventArgs e)
+ {
+ if (MessageBox.Show("The system has encountered and unhandled exception and it is recommended that you restart the application. Do you wish to restart the application?", "Twine", MessageBoxButton.YesNo, MessageBoxImage.Error, MessageBoxResult.No, MessageBoxOptions.DefaultDesktopOnly) == MessageBoxResult.Yes)
+ {
+ e.TryRecover = false;
+ LogManager.Log("User selection was to restart the application. Restarting...");
+ Process.Start(Application.ResourceAssembly.Location);
+ Environment.Exit(0);
+ }
+ else
+ {
+ e.TryRecover = true;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/DirectoryItem.cs b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/DirectoryItem.cs
new file mode 100644
index 000000000..3d272ac43
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/DirectoryItem.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf.UI
+{
+ public class DirectoryItem : Item
+ {
+ public List<Item> Items { get; set; }
+
+ public DirectoryItem()
+ {
+ Items = new List<Item>();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/ExceptionWindow.xaml b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/ExceptionWindow.xaml
new file mode 100644
index 000000000..938697ceb
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/ExceptionWindow.xaml
@@ -0,0 +1,40 @@
+<mahapps:MetroWindow x:Class="Tango.Protobuf.UI.ExceptionWindow"
+ 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:fa="http://schemas.fontawesome.io/icons/"
+ xmlns:local="clr-namespace:Tango.Protobuf.UI"
+ mc:Ignorable="d"
+ Title="Tango" Height="352" Width="566" WindowStartupLocation="CenterOwner" ShowInTaskbar="False" ShowMaxRestoreButton="False" ShowMinButton="False" Background="#202020" Foreground="Gainsboro" DataContext="{Binding RelativeSource={RelativeSource Self}}" >
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="59"/>
+ <RowDefinition Height="210*"/>
+ </Grid.RowDefinitions>
+
+ <TextBlock VerticalAlignment="Center" Margin="10" FontSize="16">Compilation Failed</TextBlock>
+
+ <Grid Grid.Row="1" Margin="10">
+ <DataGrid ItemsSource="{Binding Issues}" AutoGenerateColumns="False">
+ <DataGrid.Columns>
+ <DataGridTemplateColumn Header="#">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <fa:ImageAwesome Icon="ExclamationTriangle" Width="16" Height="16" Foreground="Red"></fa:ImageAwesome>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ <DataGridTemplateColumn Header="Description" Width="*">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding}" TextWrapping="Wrap"></TextBlock>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
+ </DataGrid.Columns>
+ </DataGrid>
+ </Grid>
+ </Grid>
+</mahapps:MetroWindow>
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/ExceptionWindow.xaml.cs b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/ExceptionWindow.xaml.cs
new file mode 100644
index 000000000..566f13bb5
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/ExceptionWindow.xaml.cs
@@ -0,0 +1,31 @@
+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.Shapes;
+
+namespace Tango.Protobuf.UI
+{
+ /// <summary>
+ /// Interaction logic for ExceptionWindow.xaml
+ /// </summary>
+ public partial class ExceptionWindow : MetroWindow
+ {
+ public List<String> Issues { get; set; }
+
+ public ExceptionWindow(List<String> issues)
+ {
+ Issues = issues;
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/FileItem.cs b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/FileItem.cs
new file mode 100644
index 000000000..c60e3fb0f
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/FileItem.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf.UI
+{
+ public class FileItem : Item
+ {
+ public override string ToString()
+ {
+ return File.ReadAllText(Path);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Item.cs b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Item.cs
new file mode 100644
index 000000000..69523aec5
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Item.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf.UI
+{
+ public class Item
+ {
+ public string Name { get; set; }
+ public string Path { get; set; }
+ public Object Object { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/ItemProvider.cs b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/ItemProvider.cs
new file mode 100644
index 000000000..1758a8543
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/ItemProvider.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Protobuf.UI
+{
+ public static class ItemProvider
+ {
+ public static List<Item> GetItems(string path)
+ {
+ var items = new List<Item>();
+
+ var dirInfo = new DirectoryInfo(path);
+
+ foreach (var directory in dirInfo.GetDirectories())
+ {
+ var item = new DirectoryItem
+ {
+ Name = directory.Name,
+ Path = directory.FullName,
+ Items = GetItems(directory.FullName)
+ };
+
+ items.Add(item);
+ }
+
+ foreach (var file in dirInfo.GetFiles("*.proto"))
+ {
+ var item = new FileItem
+ {
+ Name = file.Name,
+ Path = file.FullName
+ };
+
+ items.Add(item);
+ }
+
+ return items;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/MainWindow.xaml b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/MainWindow.xaml
new file mode 100644
index 000000000..3c0592736
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/MainWindow.xaml
@@ -0,0 +1,144 @@
+<mahapps:MetroWindow x:Class="Tango.Protobuf.UI.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:local="clr-namespace:Tango.Protobuf.UI"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:System="clr-namespace:System;assembly=mscorlib"
+ xmlns:proto="clr-namespace:Tango.Protobuf;assembly=Tango.Protobuf"
+ xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
+ xmlns:fa="http://schemas.fontawesome.io/icons/"
+ mc:Ignorable="d"
+ Title="Tango Protobuf Compilation Utility" Height="600" Width="1000" TitleCaps="False" BorderBrush="Gray" BorderThickness="1" WindowStartupLocation="CenterScreen" Background="#202020" Foreground="Gainsboro" DataContext="{Binding RelativeSource={RelativeSource Self}}">
+
+ <Window.Resources>
+
+ <converters:EnumToDescriptionConverter x:Key="EnumToDescriptionConverter"></converters:EnumToDescriptionConverter>
+
+ <ObjectDataProvider x:Key="languages" MethodName="GetValues"
+ ObjectType="{x:Type System:Enum}">
+ <ObjectDataProvider.MethodParameters>
+ <x:Type TypeName="proto:CompilerLanguage"/>
+ </ObjectDataProvider.MethodParameters>
+ </ObjectDataProvider>
+ </Window.Resources>
+
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="80" />
+ <RowDefinition Height="1*"/>
+ </Grid.RowDefinitions>
+
+ <Grid>
+ <Polygon Fill="#151515" HorizontalAlignment="Right" VerticalAlignment="Top" Points="80,0 400,0 400,80 0,80"></Polygon>
+
+ <Polygon Fill="#151515" HorizontalAlignment="Left" VerticalAlignment="Top" Points="0,0 100,0 200,80 0,80"></Polygon>
+ </Grid>
+
+ <Grid Margin="15 0 15 0" VerticalAlignment="Center">
+ <StackPanel Orientation="Horizontal">
+ <Menu HorizontalAlignment="Left" Width="100" VerticalAlignment="Center" Background="Transparent">
+ <MenuItem Header="File" Background="Transparent">
+ <MenuItem Header="Load File"/>
+ <MenuItem Header="Load Folder" Command="{Binding LoadFolderCommand}" />
+ </MenuItem>
+ </Menu>
+ </StackPanel>
+ <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
+ <Button Margin="5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding CompileCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Code" Width="16"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="10 0 10 0">Compile</TextBlock>
+ </StackPanel>
+ </Button>
+ <ComboBox Margin="5" Width="80" BorderThickness="0" ItemsSource="{Binding Source={StaticResource languages}}" SelectedItem="{Binding CompilerLanguage,Mode=TwoWay}">
+ <ComboBox.ItemTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource EnumToDescriptionConverter}}"></TextBlock>
+ </DataTemplate>
+ </ComboBox.ItemTemplate>
+ </ComboBox>
+ <Button Margin="30 5 5 5" Style="{StaticResource AccentedSquareButtonStyle}" mahapps:ButtonHelper.PreserveTextCase="True" BorderThickness="0" Command="{Binding SaveCommand}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Save" Width="16"></fa:ImageAwesome>
+ <TextBlock VerticalAlignment="Center" Margin="20 0 20 0">Save</TextBlock>
+ </StackPanel>
+ </Button>
+ </StackPanel>
+ </Grid>
+
+ <Grid Grid.Row="1" Margin="10">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="224*"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="195*"/>
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="100*"/>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="100*"/>
+ </Grid.ColumnDefinitions>
+
+ <Grid>
+ <GroupBox Header="Proto Files">
+ <TreeView Background="Transparent">
+ <TreeView.Resources>
+ <HierarchicalDataTemplate DataType="{x:Type local:DirectoryItem}"
+ ItemsSource="{Binding Items}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Folder" Foreground="Orange" Width="16" Height="16"></fa:ImageAwesome>
+ <TextBlock Margin="5 0 0 0" Text="{Binding Path=Name}" ToolTip="{Binding Path=Path}" />
+ </StackPanel>
+ </HierarchicalDataTemplate>
+
+ <DataTemplate DataType="{x:Type local:FileItem}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="File" Foreground="Gainsboro" Width="16" Height="16"></fa:ImageAwesome>
+ <TextBlock Margin="5 0 0 0" Text="{Binding Path=Name}" ToolTip="{Binding Path=Path}" />
+ </StackPanel>
+ </DataTemplate>
+ </TreeView.Resources>
+
+ <TreeView HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Left" ItemsSource="{Binding SourceItems}" SelectedItemChanged="Source_TreeView_SelectedItemChanged" />
+ </TreeView>
+ </GroupBox>
+ </Grid>
+
+ <GridSplitter Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Stretch" Width="5" Background="#151515"></GridSplitter>
+
+ <Grid Grid.Column="2">
+ <GroupBox Header="Compiled Files">
+ <TreeView Background="Transparent">
+ <TreeView.Resources>
+ <HierarchicalDataTemplate DataType="{x:Type proto:CompilerFolderResult}"
+ ItemsSource="{Binding Results}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Folder" Foreground="Orange" Width="16" Height="16"></fa:ImageAwesome>
+ <TextBlock Margin="5 0 0 0" Text="{Binding Path=Name}" ToolTip="{Binding Path=RelativePath}" />
+ </StackPanel>
+ </HierarchicalDataTemplate>
+
+ <DataTemplate DataType="{x:Type proto:CompilerFileResult}">
+ <StackPanel Orientation="Horizontal">
+ <fa:ImageAwesome Icon="Code" Foreground="Gainsboro" Width="16" Height="16"></fa:ImageAwesome>
+ <TextBlock Margin="5 0 0 0" Text="{Binding Path=Name}" />
+ </StackPanel>
+ </DataTemplate>
+ </TreeView.Resources>
+
+ <TreeView HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Left" ItemsSource="{Binding TargetItems}" SelectedItemChanged="Source_TreeView_SelectedItemChanged" />
+ </TreeView>
+ </GroupBox>
+ </Grid>
+
+ <GridSplitter Grid.Row="1" Grid.ColumnSpan="3" Height="5" Background="#151515" VerticalAlignment="Center" HorizontalAlignment="Stretch"></GridSplitter>
+
+ <Grid Grid.Row="2" Grid.ColumnSpan="3">
+ <GroupBox Header="Preview">
+ <TextBox Text="{Binding CurrentContent}" Background="#101010" FontFamily="Lucida Console" BorderThickness="0" Padding="5" AcceptsReturn="True" TextWrapping="NoWrap" IsReadOnly="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"></TextBox>
+ </GroupBox>
+ </Grid>
+ </Grid>
+ </Grid>
+</mahapps:MetroWindow>
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/MainWindow.xaml.cs b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/MainWindow.xaml.cs
new file mode 100644
index 000000000..a36292deb
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/MainWindow.xaml.cs
@@ -0,0 +1,148 @@
+using MahApps.Metro.Controls;
+using Microsoft.WindowsAPICodePack.Dialogs;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+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.Protobuf.Compilers;
+using Tango.SharedUI.Commands;
+
+namespace Tango.Protobuf.UI
+{
+ /// <summary>
+ /// Interaction logic for MainWindow.xaml
+ /// </summary>
+ public partial class MainWindow : MetroWindow
+ {
+ private String _sourceFolder;
+ private CompilerFolderResult _lastFolderResult;
+
+ public RelayCommand LoadFileCommand { get; set; }
+ public RelayCommand LoadFolderCommand { get; set; }
+ public RelayCommand CompileCommand { get; set; }
+ public RelayCommand SaveCommand { get; set; }
+
+ public List<Item> SourceItems
+ {
+ get { return (List<Item>)GetValue(SourceItemsProperty); }
+ set { SetValue(SourceItemsProperty, value); }
+ }
+ public static readonly DependencyProperty SourceItemsProperty =
+ DependencyProperty.Register("SourceItems", typeof(List<Item>), typeof(MainWindow), new PropertyMetadata(null));
+
+ public String CurrentContent
+ {
+ get { return (String)GetValue(CurrentContentProperty); }
+ set { SetValue(CurrentContentProperty, value); }
+ }
+ public static readonly DependencyProperty CurrentContentProperty =
+ DependencyProperty.Register("CurrentContent", typeof(String), typeof(MainWindow), new PropertyMetadata(null));
+
+ public List<ICompilerResult> TargetItems
+ {
+ get { return (List<ICompilerResult>)GetValue(TargetItemsProperty); }
+ set { SetValue(TargetItemsProperty, value); }
+ }
+ public static readonly DependencyProperty TargetItemsProperty =
+ DependencyProperty.Register("TargetItems", typeof(List<ICompilerResult>), typeof(MainWindow), new PropertyMetadata(null));
+
+ public CompilerLanguage CompilerLanguage
+ {
+ get { return (CompilerLanguage)GetValue(CompilerLanguageProperty); }
+ set { SetValue(CompilerLanguageProperty, value); }
+ }
+ public static readonly DependencyProperty CompilerLanguageProperty =
+ DependencyProperty.Register("CompilerLanguage", typeof(CompilerLanguage), typeof(MainWindow), new PropertyMetadata(CompilerLanguage.CSharp));
+
+ public MainWindow()
+ {
+ SourceItems = new List<Item>();
+ TargetItems = new List<ICompilerResult>();
+
+ LoadFileCommand = new RelayCommand(LoadFile);
+ LoadFolderCommand = new RelayCommand(LoadFolder);
+ CompileCommand = new RelayCommand(Compile);
+ SaveCommand = new RelayCommand(Save);
+
+ InitializeComponent();
+ }
+
+ private void LoadFolder()
+ {
+ var dialog = new CommonOpenFileDialog();
+ dialog.IsFolderPicker = true;
+ CommonFileDialogResult result = dialog.ShowDialog();
+ if (result == CommonFileDialogResult.Ok)
+ {
+ _sourceFolder = dialog.FileName;
+ SourceItems = ItemProvider.GetItems(_sourceFolder);
+ }
+ }
+
+ private void LoadFile()
+ {
+ throw new NotImplementedException();
+ }
+
+ private void Source_TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
+ {
+ if (e.NewValue is FileItem)
+ {
+ CurrentContent = File.ReadAllText((e.NewValue as FileItem).Path);
+ }
+ else if (e.NewValue is CompilerFileResult)
+ {
+ CurrentContent = (e.NewValue as CompilerFileResult).Content;
+ }
+ else
+ {
+ CurrentContent = String.Empty;
+ }
+ }
+
+ private void Compile()
+ {
+ IProtoCompiler compiler = CompilerFactory.CreateCompiler(CompilerLanguage);
+
+
+ try
+ {
+ _lastFolderResult = compiler.CompileFolder(_sourceFolder);
+ TargetItems = _lastFolderResult.Results.ToList();
+ }
+ catch (CompilerException ex)
+ {
+ ExceptionWindow exWin = new ExceptionWindow(ex.Issues);
+ exWin.Owner = this;
+ exWin.ShowDialog();
+ }
+ }
+
+ private void Save()
+ {
+ if (_lastFolderResult != null)
+ {
+ var dialog = new CommonOpenFileDialog();
+ dialog.IsFolderPicker = true;
+ CommonFileDialogResult result = dialog.ShowDialog();
+ if (result == CommonFileDialogResult.Ok)
+ {
+ _lastFolderResult.Save(dialog.FileName);
+ }
+ }
+ }
+
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..f391aa2a5
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Protobuf Compilation Utility")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Properties/Resources.Designer.cs b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..452dd71b0
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/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.Protobuf.UI.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.Protobuf.UI.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/Utilities/Tango.Protobuf.UI/Properties/Resources.resx b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Properties/Resources.resx
new file mode 100644
index 000000000..af7dbebba
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/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/Utilities/Tango.Protobuf.UI/Properties/Settings.Designer.cs b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..281a586b2
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/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.Protobuf.UI.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/Utilities/Tango.Protobuf.UI/Properties/Settings.settings b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Properties/Settings.settings
new file mode 100644
index 000000000..033d7a5e9
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/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/Utilities/Tango.Protobuf.UI/Tango.Protobuf.UI.csproj b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Tango.Protobuf.UI.csproj
new file mode 100644
index 000000000..f85fe33ae
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/Tango.Protobuf.UI.csproj
@@ -0,0 +1,151 @@
+<?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>{37E45CE1-A0F6-4ED7-9791-A1BED947602F}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <RootNamespace>Tango.Protobuf.UI</RootNamespace>
+ <AssemblyName>TangoProtoGUI</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>
+ <PropertyGroup>
+ <ApplicationIcon>proto.ico</ApplicationIcon>
+ </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="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="Microsoft.WindowsAPICodePack, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\WindowsAPICodePack-Core.1.1.1\lib\Microsoft.WindowsAPICodePack.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.WindowsAPICodePack.Shell, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\WindowsAPICodePack-Shell.1.1.1\lib\Microsoft.WindowsAPICodePack.Shell.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <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="ExceptionWindow.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <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="DirectoryItem.cs" />
+ <Compile Include="ExceptionWindow.xaml.cs">
+ <DependentUpon>ExceptionWindow.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="FileItem.cs" />
+ <Compile Include="Item.cs" />
+ <Compile Include="ItemProvider.cs" />
+ <Compile Include="MainWindow.xaml.cs">
+ <DependentUpon>MainWindow.xaml</DependentUpon>
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <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.Logging\Tango.Logging.csproj">
+ <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project>
+ <Name>Tango.Logging</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="proto.ico" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/packages.config b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/packages.config
new file mode 100644
index 000000000..e7f9bf0ff
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/packages.config
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="FontAwesome.WPF" version="4.7.0.9" targetFramework="net45" />
+ <package id="MahApps.Metro" version="1.5.0" targetFramework="net45" />
+ <package id="WindowsAPICodePack-Core" version="1.1.1" targetFramework="net45" />
+ <package id="WindowsAPICodePack-Shell" version="1.1.1" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/proto.ico b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/proto.ico
new file mode 100644
index 000000000..08c24170e
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.Protobuf.UI/proto.ico
Binary files differ
diff --git a/Software/Visual_Studio/Versioning/GlobalVersionInfo.cs b/Software/Visual_Studio/Versioning/GlobalVersionInfo.cs
new file mode 100644
index 000000000..a1208cae9
--- /dev/null
+++ b/Software/Visual_Studio/Versioning/GlobalVersionInfo.cs
@@ -0,0 +1,13 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+
+[assembly: AssemblyProduct("Tango")]
+
+[assembly: AssemblyCompany("Twine")]
+[assembly: AssemblyCopyright("Copyright © Twine LTD 2017")]
+[assembly: AssemblyTrademark("Twine LTD")]
+
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]