aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-04-27 02:01:37 +0300
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-04-27 02:01:37 +0300
commit0c3ff71389d4a9a4c5e8454fac594705119b4dd1 (patch)
tree53d562b48cfcc1f7f59102fb3b146283065ea7cb /Software/Visual_Studio
parentde15b1a5293e0b7191866d25d14bf7a421be5821 (diff)
downloadTango-0c3ff71389d4a9a4c5e8454fac594705119b4dd1.tar.gz
Tango-0c3ff71389d4a9a4c5e8454fac594705119b4dd1.zip
FSE TestRunner/Designer.
RequestUserInput. Fail. WriteLine/Json objects. Workaround for roslyn high memory/ GC.Collect.
Diffstat (limited to 'Software/Visual_Studio')
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/UserInputDialogView.xaml39
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/UserInputDialogView.xaml.cs28
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/UserInputDialogViewVM.cs97
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ITestContext.cs20
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Messages/TestProjectPublished.cs13
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj11
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/TestContext.cs198
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/TestFailedException.cs16
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/UserInput.cs18
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestDesignerViewVM.cs17
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestRunnerViewVM.cs23
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestRunnerCatalogView.xaml4
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestRunnerExecutionView.xaml67
-rw-r--r--Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj5
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs6
-rw-r--r--Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs2
-rw-r--r--Software/Visual_Studio/Tango.FSE.sln22
17 files changed, 515 insertions, 71 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/UserInputDialogView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/UserInputDialogView.xaml
new file mode 100644
index 000000000..755fa0b65
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/UserInputDialogView.xaml
@@ -0,0 +1,39 @@
+<UserControl x:Class="Tango.FSE.Stubs.Dialogs.UserInputDialogView"
+ 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:material="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:local="clr-namespace:Tango.FSE.Stubs.Dialogs"
+ mc:Ignorable="d"
+ Width="500" Height="Auto" MaxHeight="500" d:DataContext="{d:DesignInstance Type=local:UserInputDialogViewVM, IsDesignTimeCreatable=False}" Background="{StaticResource FSE_PrimaryBackgroundLightBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}">
+ <Grid Margin="10">
+ <DockPanel>
+ <StackPanel DockPanel.Dock="Top" >
+ <StackPanel Orientation="Horizontal">
+ <material:PackIcon Kind="EventEdit" Width="32" Height="32" />
+ <TextBlock Margin="10 0 0 0" FontSize="{StaticResource FSE_LargeFontSize}" VerticalAlignment="Center" Text="{Binding Title}"></TextBlock>
+ </StackPanel>
+ <TextBlock Margin="42 0 40 0" TextWrapping="Wrap" Text="{Binding Message}" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_GrayBrush}"></TextBlock>
+ </StackPanel>
+
+ <Border Margin="0 20 0 0" >
+ <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Padding="10">
+ <ItemsControl ItemsSource="{Binding Parameters}">
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <DockPanel Margin="0 10">
+ <material:PackIcon Kind="Pen" />
+ <StackPanel Margin="10 0 0 0">
+ <TextBlock Margin="2 0 0 0" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_GrayBrush}" Text="{Binding Name}"></TextBlock>
+ <TextBox Padding="5" Margin="0 2 0 0" Style="{StaticResource FSE_Rounded_Corners_TextBox}" Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>
+ </StackPanel>
+ </DockPanel>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </ScrollViewer>
+ </Border>
+ </DockPanel>
+ </Grid>
+</UserControl>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/UserInputDialogView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/UserInputDialogView.xaml.cs
new file mode 100644
index 000000000..d25c86ccd
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/UserInputDialogView.xaml.cs
@@ -0,0 +1,28 @@
+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.FSE.Stubs.Dialogs
+{
+ /// <summary>
+ /// Interaction logic for UserInputDialogView.xaml
+ /// </summary>
+ public partial class UserInputDialogView : UserControl
+ {
+ public UserInputDialogView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/UserInputDialogViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/UserInputDialogViewVM.cs
new file mode 100644
index 000000000..2160aa417
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/UserInputDialogViewVM.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.FSE.Common;
+
+namespace Tango.FSE.Stubs.Dialogs
+{
+ public class UserInputDialogViewVM : FSEDialogViewVM
+ {
+ public class Parameter
+ {
+ public PropertyInfo PropertyInfo { get; set; }
+ public FieldInfo FieldInfo { get; set; }
+ public String Name { get; set; }
+ public String Value { get; set; }
+ }
+
+ public String Title { get; set; }
+ public String Message { get; set; }
+ public List<Parameter> Parameters { get; set; }
+ public Object Model { get; set; }
+
+ public UserInputDialogViewVM(String title, String message, Object model)
+ {
+ CanClose = false;
+ Title = title;
+ Message = message;
+ Parameters = new List<Parameter>();
+ Model = model;
+ }
+
+ public void Init()
+ {
+ try
+ {
+ foreach (var prop in Model.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
+ {
+ var att = prop.GetCustomAttribute<UserInput>();
+
+ Parameter p = new Parameter();
+ p.PropertyInfo = prop;
+ p.Name = att != null ? att.Name : prop.Name.ToTitle();
+ p.Value = prop.GetValue(Model).ToStringSafe();
+ Parameters.Add(p);
+ }
+
+ foreach (var field in Model.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public))
+ {
+ var att = field.GetCustomAttribute<UserInput>();
+
+ Parameter p = new Parameter();
+ p.FieldInfo = field;
+ p.Name = att != null ? att.Name : field.Name.ToTitle();
+ p.Value = field.GetValue(Model).ToStringSafe();
+ Parameters.Add(p);
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new Exception("Error initializing the user input model.", ex);
+ }
+ }
+
+ public void FinalizeModel()
+ {
+ foreach (var p in Parameters)
+ {
+ if (p.PropertyInfo != null)
+ {
+ try
+ {
+ p.PropertyInfo.SetValue(Model, Convert.ChangeType(p.Value, p.PropertyInfo.PropertyType));
+ }
+ catch (Exception ex)
+ {
+ throw new ArgumentException($"Error setting the value '{p.Value}' for parameter '{p.PropertyInfo.Name}' of type '{p.PropertyInfo.PropertyType.Name}'.", ex);
+ }
+ }
+ else
+ {
+ try
+ {
+ p.FieldInfo.SetValue(Model, Convert.ChangeType(p.Value, p.FieldInfo.FieldType));
+ }
+ catch (Exception ex)
+ {
+ throw new ArgumentException($"Error setting the value '{p.Value}' for parameter '{p.FieldInfo.Name}' of type '{p.FieldInfo.FieldType.Name}'.", ex);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ITestContext.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ITestContext.cs
index ddc1b4fda..0897517ae 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ITestContext.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ITestContext.cs
@@ -17,12 +17,12 @@ namespace Tango.FSE.Stubs
Result AddResult(Result result);
void RemoveResult(Result result);
void ClearResults();
- IMessage Run(String stubName, params Object[] args);
- T Run<T>(String stubName, params Object[] args) where T : class, IMessage;
- IMessage Run(IMessage stub);
- T Run<T>(IMessage stub) where T : class, IMessage;
- void RunContinuous<T>(T stub, Action<T> callback) where T : class, IMessage;
- void RunContinuous<T>(String stubName, Action<T> callback, params Object[] args) where T : class, IMessage;
+ IMessage Run(String messageName, int? timeout = null, params Object[] args);
+ T Run<T>(String messageName, int? timeout = null, params Object[] args) where T : class, IMessage;
+ IMessage Run(IMessage message, int? timeout = null);
+ T Run<T>(IMessage message, int? timeout = null) where T : class, IMessage;
+ void RunContinuous<T>(IMessage message, Action<T> callback, int? timeout) where T : class, IMessage;
+ void RunContinuous<T>(String messageName, Action<T> callback, int? timeout, params Object[] args) where T : class, IMessage;
void WriteLine(Object obj);
void Write(Object obj);
void WriteLineHex(Object number, int digits);
@@ -32,5 +32,13 @@ namespace Tango.FSE.Stubs
void AppendToFile(String filePath, String content);
T GetInput<T>(String key);
Object GetInput(String key);
+ void Fail(String message);
+ void ShowInfo(String message);
+ void ShowWarning(String message);
+ void ShowError(String message);
+ bool ShowQuestion(String message);
+ bool ShowWarningQuestion(String message);
+ T RequestUserInputFor<T>(String title, String message);
+ T RequestUserInputFor<T>(T model, String title, String message);
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Messages/TestProjectPublished.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Messages/TestProjectPublished.cs
new file mode 100644
index 000000000..5895531af
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Messages/TestProjectPublished.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Stubs.Messages
+{
+ public class TestProjectPublishedOrSuppressed
+ {
+
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj
index 285d70780..4a589277c 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj
@@ -107,15 +107,22 @@
<DependentUpon>LoadPublishedProjectView.xaml</DependentUpon>
</Compile>
<Compile Include="Dialogs\LoadPublishedProjectViewVM.cs" />
+ <Compile Include="Dialogs\UserInputDialogView.xaml.cs">
+ <DependentUpon>UserInputDialogView.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Dialogs\UserInputDialogViewVM.cs" />
<Compile Include="ITestContext.cs" />
<Compile Include="ITestLogger.cs" />
+ <Compile Include="Messages\TestProjectPublished.cs" />
<Compile Include="ProjectRunner.cs" />
<Compile Include="ProjectRunnerState.cs" />
<Compile Include="Result.cs" />
<Compile Include="ResultType.cs" />
<Compile Include="TestContext.cs" />
+ <Compile Include="TestFailedException.cs" />
<Compile Include="TestInput.cs" />
<Compile Include="TestProject.cs" />
+ <Compile Include="UserInput.cs" />
<Compile Include="ViewModelLocator.cs" />
<Compile Include="StubsModule.cs" />
<Compile Include="ViewModels\MainViewVM.cs" />
@@ -237,6 +244,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Dialogs\UserInputDialogView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Themes\Generic.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/TestContext.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/TestContext.cs
index 19ec6fcc1..d043a7165 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/TestContext.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/TestContext.cs
@@ -3,15 +3,19 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
+using System.Reactive.Concurrency;
+using System.Reactive.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Google.Protobuf;
using Tango.Core.DI;
+using Tango.Core.ExtensionMethods;
using Tango.FSE.Common.Connection;
using Tango.FSE.Common.Notifications;
using Tango.FSE.Common.Threading;
+using Tango.FSE.Stubs.Dialogs;
using Tango.Integration.Operation;
using Tango.PMR;
using Tango.Scripting.Basic;
@@ -50,12 +54,12 @@ namespace Tango.FSE.Stubs
TangoIOC.Default.Inject(this);
}
- public IMessage Run(string stubName, params object[] args)
+ public IMessage Run(string messageName, int? timeout = null, params object[] args)
{
- var stubType = MessageFactory.GetAvailableRequestStubs().SingleOrDefault(x => x.Name.ToLower() == stubName.ToLower() || x.Name.Replace("Request", "").ToLower() == stubName.ToLower());
+ var stubType = MessageFactory.GetAvailableRequestStubs().SingleOrDefault(x => x.Name.ToLower() == messageName.ToLower() || x.Name.Replace("Request", "").ToLower() == messageName.ToLower());
if (stubType == null)
{
- throw new ArgumentException("Invalid stub '" + stubName + "'.");
+ throw new ArgumentException("Invalid stub '" + messageName + "'.");
}
var stubProps = stubType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
@@ -91,50 +95,73 @@ namespace Tango.FSE.Stubs
}
}
- return Run(request as IMessage);
+ return Run(request as IMessage, timeout);
}
- public T Run<T>(string stubName, params object[] args) where T : class, IMessage
+ public T Run<T>(string messageName, int? timeout = null, params object[] args) where T : class, IMessage
{
- return Run(stubName, args) as T;
+ return Run(messageName, timeout, args) as T;
}
- public IMessage Run(IMessage stub)
+ public IMessage Run(IMessage message, int? timeout = null)
{
- return MachineProvider.MachineOperator.SendRequest(stub, new Transport.TransportRequestConfig()).Result;
+ TimeSpan? timespan = null;
+
+ if (timeout != null)
+ {
+ timespan = TimeSpan.FromMilliseconds(timeout.Value);
+ }
+
+ return MachineProvider.MachineOperator.SendRequest(message, new Transport.TransportRequestConfig()
+ {
+ Timeout = timespan,
+ }).Result;
}
- public T Run<T>(IMessage stub) where T : class, IMessage
+ public T Run<T>(IMessage messageName, int? timeout = null) where T : class, IMessage
{
- return Run(stub) as T;
+ return Run(messageName, timeout) as T;
}
- public void RunContinuous<T>(T stub, Action<T> callback) where T : class, IMessage
+ public void RunContinuous<T>(IMessage messageName, Action<T> callback, int? timeout = null) where T : class, IMessage
{
- Type stubType = stub.GetType();
+ TaskCompletionSource<object> completion = new TaskCompletionSource<object>();
- MachineProvider.MachineOperator.SendContinuousRequest(stub, new Transport.TransportContinuousRequestConfig()).Subscribe((msg) =>
+ TimeSpan? timespan = null;
+
+ if (timeout != null)
{
- callback?.Invoke(msg as T);
+ timespan = TimeSpan.FromMilliseconds(timeout.Value);
+ }
- //Next
+ MachineProvider.MachineOperator.SendContinuousRequest(messageName, new Transport.TransportContinuousRequestConfig()
+ {
+ Timeout = timespan,
+ ContinuousTimeout = timespan
+ }).ObserveOn(new NewThreadScheduler()).Subscribe((msg) =>
+ {
+ try
+ {
+ callback?.Invoke(msg as T);
+ }
+ catch { }
}, (ex) =>
{
- //OnFailed(ex);
- //Error
+ completion.SetException(ex);
}, () =>
{
- //OnCompleted("Continuous request completed.");
- //Completed
+ completion.SetResult(true);
});
+
+ completion.Task.GetAwaiter().GetResult();
}
- public void RunContinuous<T>(string stubName, Action<T> callback, params object[] args) where T : class, IMessage
+ public void RunContinuous<T>(string messageName, Action<T> callback, int? timeout = null, params object[] args) where T : class, IMessage
{
- var stubType = MessageFactory.GetAvailableRequestStubs().SingleOrDefault(x => x.Name.ToLower() == stubName.ToLower() || x.Name.Replace("Request", "").ToLower() == stubName.ToLower());
+ var stubType = MessageFactory.GetAvailableRequestStubs().SingleOrDefault(x => x.Name.ToLower() == messageName.ToLower() || x.Name.Replace("Request", "").ToLower() == messageName.ToLower());
if (stubType == null)
{
- throw new ArgumentException("Invalid stub '" + stubName + "'.");
+ throw new ArgumentException("Invalid stub '" + messageName + "'.");
}
var stubProps = stubType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
@@ -170,17 +197,45 @@ namespace Tango.FSE.Stubs
}
}
- RunContinuous<IMessage>(request, callback as Action<IMessage>);
+ RunContinuous<IMessage>(request, callback as Action<IMessage>, timeout);
}
public void WriteLine(object obj)
{
- _logger?.WriteLine(obj != null ? obj.ToString() : "null");
+ String line = "null";
+
+ if (obj != null)
+ {
+ if (obj.GetType().IsClass)
+ {
+ line = obj.ToJsonString();
+ }
+ else
+ {
+ line = obj.ToString();
+ }
+ }
+
+ _logger?.WriteLine(line);
}
public void Write(object obj)
{
- _logger?.Write(obj != null ? obj.ToString() : "null");
+ String line = "null";
+
+ if (obj != null)
+ {
+ if (obj.GetType().IsClass)
+ {
+ line = obj.ToJsonString();
+ }
+ else
+ {
+ line = obj.ToString();
+ }
+ }
+
+ _logger?.WriteLine(line);
}
public void WriteLineHex(object number, int digits)
@@ -261,5 +316,98 @@ namespace Tango.FSE.Stubs
throw new KeyNotFoundException($"Could no find input with key '{key}'.");
}
}
+
+ public void Fail(string message)
+ {
+ throw new TestFailedException(message);
+ }
+
+ public void ShowInfo(string message)
+ {
+ TaskCompletionSource<object> completion = new TaskCompletionSource<object>();
+
+ DispatcherProvider.Invoke(async () =>
+ {
+ await NotificationProvider.ShowInfo(message);
+ completion.SetResult(true);
+ });
+
+ completion.Task.GetAwaiter().GetResult();
+ }
+
+ public void ShowWarning(string message)
+ {
+ TaskCompletionSource<object> completion = new TaskCompletionSource<object>();
+
+ DispatcherProvider.Invoke(async () =>
+ {
+ await NotificationProvider.ShowWarning(message);
+ completion.SetResult(true);
+ });
+
+ completion.Task.GetAwaiter().GetResult();
+ }
+
+ public void ShowError(string message)
+ {
+ TaskCompletionSource<object> completion = new TaskCompletionSource<object>();
+
+ DispatcherProvider.Invoke(async () =>
+ {
+ await NotificationProvider.ShowError(message);
+ completion.SetResult(true);
+ });
+
+ completion.Task.GetAwaiter().GetResult();
+ }
+
+ public bool ShowQuestion(string message)
+ {
+ TaskCompletionSource<bool> completion = new TaskCompletionSource<bool>();
+
+ DispatcherProvider.Invoke(async () =>
+ {
+ var result = await NotificationProvider.ShowQuestion(message);
+ completion.SetResult(result);
+ });
+
+ return completion.Task.GetAwaiter().GetResult();
+ }
+
+ public bool ShowWarningQuestion(string message)
+ {
+ TaskCompletionSource<bool> completion = new TaskCompletionSource<bool>();
+
+ DispatcherProvider.Invoke(async () =>
+ {
+ var result = await NotificationProvider.ShowWarningQuestion(message);
+ completion.SetResult(result);
+ });
+
+ return completion.Task.GetAwaiter().GetResult();
+ }
+
+ public T RequestUserInputFor<T>(string title, string message)
+ {
+ return RequestUserInputFor<T>(Activator.CreateInstance<T>(), title, message);
+ }
+
+ public T RequestUserInputFor<T>(T model, string title, string message)
+ {
+ UserInputDialogViewVM vm = new UserInputDialogViewVM(title, message, model);
+ vm.Init();
+
+ TaskCompletionSource<T> completion = new TaskCompletionSource<T>();
+
+ DispatcherProvider.Invoke(async () =>
+ {
+ await NotificationProvider.ShowDialog(vm);
+ completion.SetResult(model);
+ });
+
+ var result = completion.Task.GetAwaiter().GetResult();
+ vm.FinalizeModel();
+ return model;
+ }
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/TestFailedException.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/TestFailedException.cs
new file mode 100644
index 000000000..0e6e26dd4
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/TestFailedException.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Stubs
+{
+ public class TestFailedException : Exception
+ {
+ public TestFailedException(String message) : base(message)
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/UserInput.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/UserInput.cs
new file mode 100644
index 000000000..85282e781
--- /dev/null
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/UserInput.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.FSE.Stubs
+{
+ public class UserInput : Attribute
+ {
+ public String Name { get; set; }
+
+ public UserInput(String name)
+ {
+ Name = name;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestDesignerViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestDesignerViewVM.cs
index 726fd31e3..de1dfc50b 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestDesignerViewVM.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestDesignerViewVM.cs
@@ -20,6 +20,7 @@ using Tango.FSE.Common;
using Tango.FSE.Common.Navigation;
using Tango.FSE.Stubs.Contracts;
using Tango.FSE.Stubs.Dialogs;
+using Tango.FSE.Stubs.Messages;
using Tango.Integration.Operation;
using Tango.Scripting.Basic;
using Tango.Scripting.Editors;
@@ -319,10 +320,15 @@ namespace Tango.FSE.Stubs.ViewModels
Logger.WriteLine("Running project...");
var context = new TestContext(Project, this);
await ProjectRunner.Run(context);
- Logger.WriteLine("Project ran to completion with test result:");
- Logger.WriteLine(context.Results.ToJsonString());
+
Results = context.Results.ToList();
- SelectedToolWindow = ToolWindows.Results;
+
+ if (Results.Count > 0)
+ {
+ Logger.WriteLine("Project ran to completion with test result:");
+ Logger.WriteLine(Results.ToJsonString());
+ SelectedToolWindow = ToolWindows.Results;
+ }
}
}
catch (OperationCanceledException)
@@ -383,7 +389,7 @@ namespace Tango.FSE.Stubs.ViewModels
{
CompilationErrors = (await Project.Compile()).Errors;
- if (CompilationErrors.Count > 0)
+ if (CompilationErrors.Count > 0 && (SelectedToolWindow == ToolWindows.Output || SelectedToolWindow == ToolWindows.Results))
{
SelectedToolWindow = ToolWindows.Errors;
}
@@ -774,6 +780,8 @@ namespace Tango.FSE.Stubs.ViewModels
Project.Name,
Project.Description,
Project.ToJson());
+
+ RaiseMessage<TestProjectPublishedOrSuppressed>();
}
await NotificationProvider.ShowSuccess("Your test project is now published!\nNow you can execute this project from the Test Runner module.");
@@ -801,6 +809,7 @@ namespace Tango.FSE.Stubs.ViewModels
using (NotificationProvider.PushTaskItem("Suppressing test project..."))
{
PublishedTestProject = await Services.PublishedTestProjectsService.UnPublishTestProject(PublishedTestProject);
+ RaiseMessage<TestProjectPublishedOrSuppressed>();
}
await NotificationProvider.ShowInfo("This test project will no longer be available on the Test Runner module.");
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestRunnerViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestRunnerViewVM.cs
index b084f48ec..6e4ec2b74 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestRunnerViewVM.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestRunnerViewVM.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Tango.BL.Entities;
using Tango.Core.Commands;
using Tango.FSE.Common;
+using Tango.FSE.Stubs.Messages;
using Tango.FSE.Stubs.Views;
namespace Tango.FSE.Stubs.ViewModels
@@ -18,6 +19,8 @@ namespace Tango.FSE.Stubs.ViewModels
TestRunnerExecutionView
}
+ private bool _requiresReloadingOfProjects;
+
private RunnerView _selectedView;
public RunnerView SelectedView
{
@@ -72,6 +75,12 @@ namespace Tango.FSE.Stubs.ViewModels
set { _status = value; RaisePropertyChangedAuto(); }
}
+ private String _failedError;
+ public String FailedError
+ {
+ get { return _failedError; }
+ set { _failedError = value; RaisePropertyChangedAuto(); }
+ }
public RelayCommand<PublishedTestProject> EditProjectCommand { get; set; }
public RelayCommand<PublishedTestProject> RunProjectCommand { get; set; }
@@ -84,12 +93,16 @@ namespace Tango.FSE.Stubs.ViewModels
RunProjectCommand = new RelayCommand<PublishedTestProject>(RunProject);
StartProjectCommand = new RelayCommand(StartProject, () => ProjectRunner != null && ProjectRunner.CanRun);
StopProjectCommand = new RelayCommand(StopProject, () => ProjectRunner != null && ProjectRunner.IsRunning);
+
+ _requiresReloadingOfProjects = true;
+ RegisterForMessage<TestProjectPublishedOrSuppressed>((x) => _requiresReloadingOfProjects = true);
}
private async void StartProject()
{
try
{
+ FailedError = null;
Results = new List<Result>();
Status = "Running...";
var context = new TestContext(RunningTestProject, this);
@@ -104,7 +117,7 @@ namespace Tango.FSE.Stubs.ViewModels
catch (Exception ex)
{
Status = "Failed";
- //TODO: Display project runtime error!
+ FailedError = ex.FlattenMessage();
}
}
@@ -131,7 +144,11 @@ namespace Tango.FSE.Stubs.ViewModels
public override void OnNavigatedTo()
{
base.OnNavigatedTo();
- LoadPublishedTestProjects();
+
+ if (_requiresReloadingOfProjects)
+ {
+ LoadPublishedTestProjects();
+ }
}
private async void LoadPublishedTestProjects()
@@ -142,7 +159,7 @@ namespace Tango.FSE.Stubs.ViewModels
IsLoadingProjects = true;
PublishedTestProjects = new List<PublishedTestProject>();
PublishedTestProjects = await Services.PublishedTestProjectsService.GetPublishedTestProjects();
-
+ _requiresReloadingOfProjects = false;
IsFree = true;
}
catch (Exception ex)
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestRunnerCatalogView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestRunnerCatalogView.xaml
index 818e419c9..2af7253ae 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestRunnerCatalogView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestRunnerCatalogView.xaml
@@ -23,9 +23,9 @@
<LineBreak/>
<Run>Below is a collection of machine tests that can be executed independently.</Run>
<LineBreak/>
- <Run>Each test can yield on or more test results, and may require you to provide some input before execution.</Run>
+ <Run>Each test can yield one or more test results, and may require you to provide some input before execution.</Run>
<LineBreak/>
- <Run>Pressing the 'run' button on the desired test, will navigate you to the test execution screen.</Run>
+ <Run>Pressing the 'run' button on the desired test will navigate you to the test execution screen.</Run>
</TextBlock>
</StackPanel>
</DockPanel>
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestRunnerExecutionView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestRunnerExecutionView.xaml
index 784311f39..53c0bff56 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestRunnerExecutionView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestRunnerExecutionView.xaml
@@ -77,6 +77,11 @@
</DockPanel>
</StackPanel>
</StackPanel>
+ <StackPanel Margin="0 100 0 0" HorizontalAlignment="Left" Visibility="{Binding ProjectRunner.State,Converter={StaticResource EnumToVisibilityConverter},ConverterParameter='Failed'}">
+ <TextBlock FontSize="{StaticResource FSE_LargeFontSize}" FontWeight="SemiBold" Foreground="{StaticResource FSE_RedBrush}">Test Failed</TextBlock>
+ <TextBlock Margin="0 20 0 0">The test has failed to complete with the following error:</TextBlock>
+ <TextBlock Text="{Binding FailedError}" Margin="0 5 0 0" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_GrayBrush}" TextWrapping="Wrap"></TextBlock>
+ </StackPanel>
<StackPanel>
<StackPanel.Style>
<Style TargetType="StackPanel">
@@ -105,36 +110,38 @@
<TextBlock FontSize="{StaticResource FSE_LargeFontSize}" FontWeight="SemiBold" Foreground="{StaticResource FSE_PrimaryAccentBrush}">Results</TextBlock>
<!--<Rectangle Margin="0 2 0 0" Stroke="{StaticResource FSE_BorderBrush}" StrokeDashArray="5" />-->
</StackPanel>
- <ItemsControl ItemsSource="{Binding Results}" HorizontalAlignment="Left" Margin="0 20 0 0">
- <ItemsControl.ItemTemplate>
- <DataTemplate>
- <DockPanel Margin="10">
- <material:PackIcon HorizontalAlignment="Center" VerticalAlignment="Center" Width="42" Height="42">
- <material:PackIcon.Style>
- <Style TargetType="material:PackIcon">
- <Setter Property="Kind" Value="Check"></Setter>
- <Setter Property="Foreground" Value="{StaticResource FSE_SuccessBrush}"></Setter>
- <Style.Triggers>
- <DataTrigger Binding="{Binding Type}" Value="Warning">
- <Setter Property="Kind" Value="Alert"></Setter>
- <Setter Property="Foreground" Value="{StaticResource FSE_WarningBrush}"></Setter>
- </DataTrigger>
- <DataTrigger Binding="{Binding Type}" Value="Failed">
- <Setter Property="Kind" Value="Alert"></Setter>
- <Setter Property="Foreground" Value="{StaticResource FSE_ErrorBrush}"></Setter>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </material:PackIcon.Style>
- </material:PackIcon>
- <StackPanel Margin="15 0 0 0" VerticalAlignment="Center">
- <TextBlock Text="{Binding Name}" ></TextBlock>
- <TextBlock Margin="0 2 0 0" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_GrayBrush}" Text="{Binding Value}"></TextBlock>
- </StackPanel>
- </DockPanel>
- </DataTemplate>
- </ItemsControl.ItemTemplate>
- </ItemsControl>
+ <Grid>
+ <ItemsControl ItemsSource="{Binding Results}" HorizontalAlignment="Left" Margin="0 20 0 0">
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <DockPanel Margin="10">
+ <material:PackIcon HorizontalAlignment="Center" VerticalAlignment="Center" Width="42" Height="42">
+ <material:PackIcon.Style>
+ <Style TargetType="material:PackIcon">
+ <Setter Property="Kind" Value="Check"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_SuccessBrush}"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Type}" Value="Warning">
+ <Setter Property="Kind" Value="Alert"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_WarningBrush}"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Type}" Value="Failed">
+ <Setter Property="Kind" Value="Alert"></Setter>
+ <Setter Property="Foreground" Value="{StaticResource FSE_ErrorBrush}"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </material:PackIcon.Style>
+ </material:PackIcon>
+ <StackPanel Margin="15 0 0 0" VerticalAlignment="Center">
+ <TextBlock Text="{Binding Name}" ></TextBlock>
+ <TextBlock Margin="0 2 0 0" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_GrayBrush}" Text="{Binding Value}"></TextBlock>
+ </StackPanel>
+ </DockPanel>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ </Grid>
</StackPanel>
</StackPanel>
</ScrollViewer>
diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj
index 72b4bf121..0cdb832cb 100644
--- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj
+++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj
@@ -614,7 +614,10 @@
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
- <PostBuildEvent>RD /S /Q "$(TargetDir)cs\"
+ <PostBuildEvent>call "$(DevEnvDir)..\..\vc\vcvarsall.bat" x86
+"$(DevEnvDir)..\..\vc\bin\EditBin.exe" "$(TargetPath)" /LARGEADDRESSAWARE
+
+RD /S /Q "$(TargetDir)cs\"
RD /S /Q "$(TargetDir)da\"
RD /S /Q "$(TargetDir)de\"
RD /S /Q "$(TargetDir)es\"
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs
index 7abcbb42d..fef43a35f 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs
@@ -123,6 +123,8 @@ namespace Tango.Scripting.Basic
var compileResults = s.Compile();
+ GC.Collect();
+
foreach (var error in compileResults.Where(x => x.Severity == Microsoft.CodeAnalysis.DiagnosticSeverity.Error))
{
CompilationError cError = new CompilationError();
@@ -178,6 +180,10 @@ namespace Tango.Scripting.Basic
{
session.Failed(ex.InnerException);
}
+ finally
+ {
+ GC.Collect();
+ }
});
scriptThread.SetApartmentState(ApartmentState);
diff --git a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs
index 42a1902e4..419e5adb8 100644
--- a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs
+++ b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs
@@ -456,6 +456,8 @@ namespace Tango.Emulations.Emulators
Transporter.SendResponse(res);
}
+
+ Transporter.SendResponse(new ProgressResponse(), request.Container.Token, new TransportResponseConfig() { Completed = true });
});
}
diff --git a/Software/Visual_Studio/Tango.FSE.sln b/Software/Visual_Studio/Tango.FSE.sln
index fe7f056e8..990e2328b 100644
--- a/Software/Visual_Studio/Tango.FSE.sln
+++ b/Software/Visual_Studio/Tango.FSE.sln
@@ -25,6 +25,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.FSE.Stubs", "FSE\Modu
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.FSE.Upgrade", "FSE\Modules\Tango.FSE.Upgrade\Tango.FSE.Upgrade.csproj", "{0C0B24CB-79AF-4253-AAC3-B2BADF034675}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.SharedUI", "Tango.SharedUI\Tango.SharedUI.csproj", "{8491D07B-C1F6-4B62-A412-41B9FD2D6538}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripting", "Scripting", "{6341BAC2-F9BE-4F10-BB13-DC4D59DD7B00}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Scripting.Editors", "Scripting\Tango.Scripting.Editors\Tango.Scripting.Editors.csproj", "{DA62FA39-668B-47A6-B0F2-D2C1DAF777B0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.Scripting.Basic", "Scripting\Tango.Scripting.Basic\Tango.Scripting.Basic.csproj", "{2B29A699-1D65-463A-8250-A2CE81D019C9}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -67,6 +75,18 @@ Global
{0C0B24CB-79AF-4253-AAC3-B2BADF034675}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C0B24CB-79AF-4253-AAC3-B2BADF034675}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C0B24CB-79AF-4253-AAC3-B2BADF034675}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8491D07B-C1F6-4B62-A412-41B9FD2D6538}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8491D07B-C1F6-4B62-A412-41B9FD2D6538}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8491D07B-C1F6-4B62-A412-41B9FD2D6538}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8491D07B-C1F6-4B62-A412-41B9FD2D6538}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DA62FA39-668B-47A6-B0F2-D2C1DAF777B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DA62FA39-668B-47A6-B0F2-D2C1DAF777B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DA62FA39-668B-47A6-B0F2-D2C1DAF777B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DA62FA39-668B-47A6-B0F2-D2C1DAF777B0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2B29A699-1D65-463A-8250-A2CE81D019C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2B29A699-1D65-463A-8250-A2CE81D019C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2B29A699-1D65-463A-8250-A2CE81D019C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2B29A699-1D65-463A-8250-A2CE81D019C9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -82,6 +102,8 @@ Global
{866B916A-207C-43F0-B403-7C4A820C2E11} = {DBE903D1-1D6C-4B0D-8EB1-CCB447FA1775}
{1754F846-4763-4000-807F-C7BFAA145DB2} = {DBE903D1-1D6C-4B0D-8EB1-CCB447FA1775}
{0C0B24CB-79AF-4253-AAC3-B2BADF034675} = {DBE903D1-1D6C-4B0D-8EB1-CCB447FA1775}
+ {DA62FA39-668B-47A6-B0F2-D2C1DAF777B0} = {6341BAC2-F9BE-4F10-BB13-DC4D59DD7B00}
+ {2B29A699-1D65-463A-8250-A2CE81D019C9} = {6341BAC2-F9BE-4F10-BB13-DC4D59DD7B00}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {44758539-3458-4A3E-89DD-68F496B34B45}