diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-04-27 02:01:37 +0300 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-04-27 02:01:37 +0300 |
| commit | 0c3ff71389d4a9a4c5e8454fac594705119b4dd1 (patch) | |
| tree | 53d562b48cfcc1f7f59102fb3b146283065ea7cb /Software/Visual_Studio | |
| parent | de15b1a5293e0b7191866d25d14bf7a421be5821 (diff) | |
| download | Tango-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')
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} |
