aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.Integration/ExtensionMethods/IExternalBridgeClientExtensions.cs
blob: 3e9546983020bd0e6bb31ee89f5e93fdf4e0214b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Integration.ExternalBridge;

/// <summary>
/// Contains <see cref="IExternalBridgeClient"/> extension methods.
/// </summary>
public static class IExternalBridgeClientExtensions
{
    /// <summary>
    /// Casts the external bridge client to the specified type T.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="client">The client.</param>
    /// <returns></returns>
    public static T As<T>(this IExternalBridgeClient client) where T : IExternalBridgeClient
    {
        return (T)client;
    }
}
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.Core.Commands;
using Tango.Transport.Adapters;
using Tango.Transport.Servers;
using Tango.Transport.Transporters;
using Tango.Core;
using Tango.Settings;
using Tango.PMR.ThreadLoading;
using Tango.PMR.DataStore;
using System.Windows;

namespace Tango.MachineEM.UI.ViewModels
{
    public class MainViewVM : ExtendedObject
    {
        private TcpServer TcpServer;
        private bool _running;
        private LogManager logManager = LogManager.Default;
        private bool _isThreadLoading;

        #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)); }
        }

        private List<String> _ports;
        /// <summary>
        /// Gets or sets the ports.
        /// </summary>
        public List<String> Ports
        {
            get { return _ports; }
            set { _ports = value; RaisePropertyChanged(nameof(Ports)); }
        }

        private String _selectedPort;
        /// <summary>
        /// Gets or sets the selected port.
        /// </summary>
        public String SelectedPort
        {
            get { return _selectedPort; }
            set { _selectedPort = value; RaisePropertyChanged(nameof(SelectedPort)); }
        }

        private ThreadLoadingState _threadLoadingState;
        public ThreadLoadingState ThreadLoadingState
        {
            get { return _threadLoadingState; }
            set { _threadLoadingState = value; OnThreadLoadingStateChanged(); }
        }


        #endregion

        #region Private Methods

        private void OnThreadLoadingStateChanged()
        {
            try
            {
                Emulator?.SetThreadLoadingState(ThreadLoadingState);
            }
            catch (Exception ex)
            {
                LogManager.Log(ex);
            }
        }

        #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; }

        /// <summary>
        /// Gets or sets the validate cartridge command.
        /// </summary>
        public RelayCommand ValidateCartridgeCommand { get; set; }

        /// <summary>
        /// Gets or sets the start thread loading sequence command.
        /// </summary>
        public RelayCommand StartThreadLoadingCommand { get; set; }

        /// <summary>
        /// Gets or sets the finalize thread loading command.
        /// </summary>
        public RelayCommand FinalizeThreadLoadingCommand { get; set; }

        /// <summary>
        /// Gets or sets the abort job.
        /// </summary>
        public RelayCommand AbortJobCommand { get; set; }

        public RelayCommand GetDataStoreItemCommand { get; set; }

        public RelayCommand PutDataStoreItemCommand { get; set; }

        public RelayCommand PerformDataStoreTestCommand { get; set; }

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="MainViewVM"/> class.
        /// </summary>
        public MainViewVM()
        {
            CoreSettings settings = SettingsManager.Default.GetOrCreate<CoreSettings>();
            settings.Save();

            SimpleStringLogger logger = new SimpleStringLogger(LogCategory.Critical, LogCategory.Error, LogCategory.Info, LogCategory.Warning);
            logger.LogReceived += (sedner, log) =>
            {
                Log += log.ToString() + Environment.NewLine;
            };

            logManager.RegisterLogger(logger);

            logManager.Log("Embedded Emulator Started...");


            Emulator = new MachineEmulator(new BasicTransporter());

            StartCommand = new RelayCommand(Start, (x) => !Emulator.IsStarted);
            StopCommand = new RelayCommand(Stop, (x) => Emulator.IsStarted);
            CancelCommand = new RelayCommand(Cancel, (x) => _running);
            ClearCommand = new RelayCommand(() => Log = String.Empty);
            ValidateCartridgeCommand = new RelayCommand(ValidateCartridge, (x) => Emulator.IsStarted);
            StartThreadLoadingCommand = new RelayCommand(StartThreadLoading, (x) => Emulator.IsStarted && !_isThreadLoading);
            FinalizeThreadLoadingCommand = new RelayCommand(FinalizeThreadLoading, (x) => Emulator.IsStarted && _isThreadLoading);
            AbortJobCommand = new RelayCommand(() => Emulator?.AbortJob(), (x) => Emulator.IsStarted);

            Ports = new List<string>()
            {
                "TCP",
                "COM1",
                "COM2",
                "COM3",
                "COM4",
                "COM5",
                "COM6",
                "COM7",
                "COM8",
                "COM9",
            };

            SelectedPort = Ports.First();

            PerformDataStoreTestCommand = new RelayCommand(Emulator.PerformDataStoreTest);
            GetDataStoreItemCommand = new RelayCommand(GetDataStoreItem);
            PutDataStoreItemCommand = new RelayCommand(PutDataStoreItem);
        }

        #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.Adapter = new TcpTransportAdapter(e.Socket);
        }

        #endregion

        #region Command Handlers

        /// <summary>
        /// Stops the TCP server and emulator.
        /// </summary>
        private async void Start()
        {
            if (SelectedPort == Ports.First())
            {
                TcpServer = new TcpServer(9999);
                TcpServer.ClientConnected += TcpServer_ClientConnected;
                TcpServer.Start();
            }
            else
            {
                Emulator.Transporter.Adapter = new UsbTransportAdapter(SelectedPort);
            }
            await Emulator.Start();
            InvalidateRelayCommands();
        }

        /// <summary>
        /// Starts the TCP server/USB and emulator.
        /// </summary>
        private async void Stop()
        {
            if (TcpServer != null)
            {
                TcpServer.Stop();
            }
            await Emulator.Stop();
            InvalidateRelayCommands();
        }

        private void Cancel()
        {

        }

        private async void ValidateCartridge()
        {
            LogManager.Log("Sending cartridge validation request...");
            try
            {
                var index = await Emulator.ValidateCartridge();
                LogManager.Log($"Cartridge validation response received: '{index}'.");
            }
            catch (Exception ex)
            {
                LogManager.Log(ex, "Cartridge validation request failed.");
            }
        }

        private async void StartThreadLoading()
        {
            LogManager.Log("Starting thread loading sequence...");
            Emulator.StartThreadLoading();
            _isThreadLoading = true;
            InvalidateRelayCommands();

            await Task.Delay(10000);
            _isThreadLoading = false;
            InvalidateRelayCommands();
        }

        private void FinalizeThreadLoading()
        {
            LogManager.Log("Finalizing thread loading sequence...");
            Emulator.FinalizeThreadLoading();
            _isThreadLoading = false;
            InvalidateRelayCommands();
        }

        private void GetDataStoreItem()
        {
            try
            {
                var result = GetUserInput<String>("Get Data Store Item", "Enter collection name", String.Empty);
                if (!result.Confirmed) return;
                var collectionName = result.Value;

                result = GetUserInput<String>("Get Data Store Item", "Enter item key", String.Empty);
                if (!result.Confirmed) return;
                var key = result.Value;

                Emulator.GetDataStoreItem(new PMR.DataStore.GetDataStoreItemRequest()
                {
                    Collection = collectionName,
                    Key = key
                });
            }
            catch { }
        }

        private void PutDataStoreItem()
        {
            try
            {
                var result = GetUserInput<String>("Put Data Store Item", "Enter collection name", String.Empty);
                if (!result.Confirmed) return;
                var collectionName = result.Value;

                result = GetUserInput<String>("Put Data Store Item", "Enter item key", String.Empty);
                if (!result.Confirmed) return;
                var key = result.Value;

                result = GetUserInput<String>("Put Data Store Item", "Enter data type", "Int32");
                if (!result.Confirmed) return;
                DataType dataType = (DataType)Enum.Parse(typeof(DataType), result.Value);

                result = GetUserInput<String>("Put Data Store Item", "Enter value", "10");
                if (!result.Confirmed) return;
                var value = result.Value;

                DataStoreItem item = new DataStoreItem();
                item.DataType = dataType;

                switch (dataType)
                {
                    case DataType.Int32:
                        item.Int32Value = int.Parse(value);
                        break;
                    case DataType.Float:
                        item.FloatValue = float.Parse(value);
                        break;
                    case DataType.Double:
                        item.DoubleValue = double.Parse(value);
                        break;
                    case DataType.Boolean:
                        item.BooleanValue = bool.Parse(value);
                        break;
                    case DataType.String:
                        item.StringValue = value;
                        break;
                    default:
                        LogManager.Log("Data type not supported by this emulator.");
                        throw new NotSupportedException();
                }

                Emulator.PutDataStoreItem(new PutDataStoreItemRequest()
                {
                    Collection = collectionName,
                    Key = key,
                    Item = item
                });
            }
            catch { }
        }

        #endregion

        #region Private Methods

        private class InputResult<T>
        {
            public bool Confirmed { get; set; }
            public T Value { get; set; }
        }

        private InputResult<T> GetUserInput<T>(String title, String message, T defaultValue)
        {
            InputWindow window = new InputWindow();
            window.Title = title;
            window.Message = message;
            window.Value = defaultValue.ToStringSafe();
            window.Owner = Application.Current.MainWindow;
            window.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
            window.WindowStyle = WindowStyle.ToolWindow;

            try
            {
                if (window.ShowDialog().Value)
                {
                    return new InputResult<T>() { Confirmed = true, Value = (T)Convert.ChangeType(window.Value, typeof(T)) };
                }
                else
                {
                    return new InputResult<T>();
                }
            }
            catch (Exception ex)
            {
                LogManager.Log(ex, "Error parsing input.");
                throw ex;
            }
        }

        #endregion
    }
}