aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs')
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs252
1 files changed, 236 insertions, 16 deletions
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs
index c7351aa4a..83790a56f 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs
@@ -32,6 +32,10 @@ using Tango.PPC.UI.Dialogs;
using Tango.Core.Threading;
using Tango.PPC.Common.Messages;
using Tango.Core.ExtensionMethods;
+using Tango.PPC.Common.Navigation;
+using Tango.PPC.Common.Synchronization;
+using Tango.Insights;
+using System.Threading;
namespace Tango.PPC.UI.PPCApplication
{
@@ -49,6 +53,7 @@ namespace Tango.PPC.UI.PPCApplication
private IEventLogger _eventLogger;
private IPPCModuleLoader _moduleLoader;
private INotificationProvider _notificationProvider;
+ private IMachineDataSynchronizer _machineDataSynchronizer;
private WatchDogServer _watchdogServer;
private ObservablesContext _machineContext;
private ActionTimer _screenLockTimer;
@@ -59,6 +64,11 @@ namespace Tango.PPC.UI.PPCApplication
public event EventHandler SystemRestartRequired;
/// <summary>
+ /// Occurs when the updater utility has failed to perform the last update.
+ /// </summary>
+ public event EventHandler UpdaterFailed;
+
+ /// <summary>
/// Occurs when the application has started.
/// </summary>
public event EventHandler ApplicationStarted;
@@ -93,10 +103,15 @@ namespace Tango.PPC.UI.PPCApplication
/// </summary>
public bool IsShuttingDown { get; private set; }
+ private bool _isInTechnicianMode;
/// <summary>
/// Gets a value indicating whether the application is in technician mode.
/// </summary>
- public bool IsInTechnicianMode { get; private set; }
+ public bool IsInTechnicianMode
+ {
+ get { return _isInTechnicianMode; }
+ set { _isInTechnicianMode = value; RaisePropertyChangedAuto(); }
+ }
/// <summary>
/// Gets the application version.
@@ -125,6 +140,16 @@ namespace Tango.PPC.UI.PPCApplication
/// </summary>
public DateTime StartUpDate { get; private set; }
+ /// <summary>
+ /// Gets a value indicating whether an update has occurred before the application started.
+ /// </summary>
+ public bool IsAfterUpdate { get; private set; }
+
+ /// <summary>
+ /// Gets a value indicating whether the updater utility has failed to perform the last update.
+ /// </summary>
+ public bool IsUpdateFailed { get; private set; }
+
private bool _isScreenLocked;
/// <summary>
/// Gets or sets a value indicating whether the screen is currently locked.
@@ -136,15 +161,34 @@ namespace Tango.PPC.UI.PPCApplication
}
/// <summary>
+ /// Gets the firmware version.
+ /// </summary>
+ public Version FirmwareVersion
+ {
+ get
+ {
+ return Version.Parse(SettingsManager.Default.GetOrCreate<PPCSettings>().FirmwareVersion);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the application folder.
+ /// </summary>
+ public String StartPath { get; private set; }
+
+ /// <summary>
/// Initializes a new instance of the <see cref="DefaultPPCApplicationManager"/> class.
/// </summary>
- public DefaultPPCApplicationManager(IMachineProvider machineProvider, IDispatcherProvider dispatcherProvider, IEventLogger eventLogger, IPPCModuleLoader moduleLoader, INotificationProvider notificationProvider)
+ public DefaultPPCApplicationManager(IMachineProvider machineProvider, IDispatcherProvider dispatcherProvider, IEventLogger eventLogger, IPPCModuleLoader moduleLoader, INotificationProvider notificationProvider, IMachineDataSynchronizer machineDataSynchronizer)
{
+ StartPath = AssemblyHelper.GetCurrentAssemblyFolder();
+
_notificationProvider = notificationProvider;
_machineProvider = machineProvider;
_dispatcher = dispatcherProvider;
_eventLogger = eventLogger;
_moduleLoader = moduleLoader;
+ _machineDataSynchronizer = machineDataSynchronizer;
if (!DesignMode)
{
@@ -210,11 +254,15 @@ namespace Tango.PPC.UI.PPCApplication
{
LogManager.Log("Application started with '-update_ok' startup arguments. The application has been successfully updated.");
- if (settings.ApplicationState == ApplicationStates.PreSetup)
+ if (settings.ApplicationState == ApplicationStates.PreSetup || settings.ApplicationState == ApplicationStates.FactoryRestore)
{
isAfterSetup = true;
LogManager.Log("System restart is required.");
}
+ else
+ {
+ IsAfterUpdate = true;
+ }
settings.ApplicationState = ApplicationStates.Ready;
settings.Save();
@@ -226,13 +274,27 @@ namespace Tango.PPC.UI.PPCApplication
}
}
+ if (App.StartupArgs.Contains("-update_failed"))
+ {
+ LogManager.Log("Application started with '-update_failed' startup arguments. The updater utility has failed.");
+
+ IsUpdateFailed = true;
+
+ settings.ApplicationState = ApplicationStates.Ready;
+ settings.Save();
+ UpdaterFailed?.Invoke(this, new EventArgs());
+ return;
+ }
+
if (settings.ApplicationState == ApplicationStates.Ready)
{
LogManager.Log("Initializing ObservablesStaticCollections...");
ObservablesStaticCollections.Instance.Initialize();
LogManager.Log("Loading machine from database...");
_machineContext = ObservablesContext.CreateDefault();
- _machine = new MachineBuilder(_machineContext).SetFirst().WithVersion().WithSettings().WithOrganization().WithConfiguration().WithSpools().WithCats().Build();
+ _machine = new MachineBuilder(_machineContext).SetFirst().WithVersion().WithOrganization().WithConfiguration().WithSpools().WithCats().Build();
+
+
}
initialized = true;
@@ -276,7 +338,6 @@ namespace Tango.PPC.UI.PPCApplication
{
LogManager.Log($"Raising {nameof(ApplicationStarted)} event...");
- _eventLogger.Log(EventTypes.APPLICATION_STARTED, "Application Started!");
ApplicationStarted?.Invoke(this, new EventArgs());
LogManager.Log("Invoking PPC view models OnApplicationStarted methods...");
@@ -290,6 +351,8 @@ namespace Tango.PPC.UI.PPCApplication
}
}
+ var internalModules = this.GetType().Assembly.GetTypes().Where(xx => typeof(PPCModuleBase).IsAssignableFrom(xx)).ToList();
+
LogManager.Log("Waiting for IPPCModuleLoader instance injection...");
TangoIOC.Default.GetInstanceWhenAvailable<IPPCModuleLoader>((loader) =>
{
@@ -304,12 +367,32 @@ namespace Tango.PPC.UI.PPCApplication
{
if (!Views.LayoutView.Instance.NavigationControl.Elements.ToList().Exists(m => m.GetType() == module.MainViewType))
{
- LogManager.Log("Loading module view " + module.Name + "...");
- FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement;
- SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name);
- Views.LayoutView.Instance.NavigationControl.Elements.Add(view);
+ try
+ {
+ LogManager.Log("Loading module view " + module.Name + "...");
+ FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement;
+ SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name);
+ Views.LayoutView.Instance.NavigationControl.Elements.Add(view);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error loading module view for module {module.Name}.");
+ }
}
}
+
+ //Adding internal modules.
+ LogManager.Log("Loading internal modules...");
+ foreach (var type in internalModules)
+ {
+ var module = Activator.CreateInstance(type) as IPPCModule;
+ LogManager.Log("Loading module view " + module.Name + "...");
+ FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement;
+ SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name);
+ Views.LayoutView.Instance.NavigationControl.Elements.Add(view);
+ _moduleLoader.AllModules.Add(module);
+ _moduleLoader.UserModules.Add(module);
+ }
});
LogManager.Log($"{loader.UserModules.Count} modules loaded.");
@@ -334,6 +417,9 @@ namespace Tango.PPC.UI.PPCApplication
LogManager.Log("Initializing Machine Provider...");
_machineProvider.Init(_machine, _machineContext);
+ LogManager.Log("Starting Machine Data Synchronizer...");
+ _machineDataSynchronizer.IsEnabled = true;
+
LogManager.Log("Applications initialization completed!");
LogManager.Log("Checking for un-notified PPC view models...");
@@ -350,6 +436,7 @@ namespace Tango.PPC.UI.PPCApplication
_dispatcher.Invoke(() =>
{
LogManager.Log($"Invoking {nameof(ApplicationReady)} event.");
+ _eventLogger.Log(EventTypes.APPLICATION_STARTED, "Application Started!");
ApplicationReady?.Invoke(this, new EventArgs());
LogManager.Log("Notifying view models about application ready...");
@@ -390,7 +477,7 @@ namespace Tango.PPC.UI.PPCApplication
/// <summary>
/// Shutdown the application.
/// </summary>
- public void ShutDown()
+ public async void ShutDown()
{
if (IsShuttingDown) return;
@@ -408,13 +495,22 @@ namespace Tango.PPC.UI.PPCApplication
}
catch { }
+ try
+ {
+ await FinalizeApplication();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error occurred on application shutdown finalization.");
+ }
+
Environment.Exit(0);
}
/// <summary>
/// Restarts the application.
/// </summary>
- public void Restart()
+ public async void Restart()
{
if (IsShuttingDown) return;
@@ -422,13 +518,28 @@ namespace Tango.PPC.UI.PPCApplication
try
{
+ _dispatcher.Invoke(() =>
+ {
+ var nav = TangoIOC.Default.GetInstance<INavigationManager>();
+ if (nav != null)
+ {
+ nav.NavigateTo(NavigationView.RestartingView);
+ }
+ });
+
LogManager.Log("Restarting the application...");
+ await Task.Delay(8000);
+
_watchdogServer.Dispose();
foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<PPCViewModel>())
{
- vm.OnApplicationShuttingDown();
+ try
+ {
+ vm.OnApplicationShuttingDown();
+ }
+ catch { }
}
}
catch { }
@@ -442,6 +553,15 @@ namespace Tango.PPC.UI.PPCApplication
}
catch { }
+ try
+ {
+ await FinalizeApplication();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error occurred on application shutdown finalization.");
+ }
+
Process.Start(Application.ResourceAssembly.Location);
Environment.Exit(0);
}
@@ -449,25 +569,82 @@ namespace Tango.PPC.UI.PPCApplication
/// <summary>
/// Runs the updater utility and exits the application.
/// </summary>
- public void UpdateApplication(String updaterPath, String arguments)
+ public async void UpdateApplication(String updaterPath, String arguments)
{
if (IsShuttingDown) return;
IsShuttingDown = true;
+ LogManager.Log("Restarting application for update...");
+
try
{
- _watchdogServer.Dispose();
+ LogManager.Log("Navigating to restart view...");
+ _dispatcher.Invoke(() =>
+ {
+ var nav = TangoIOC.Default.GetInstance<INavigationManager>();
+ if (nav != null)
+ {
+ nav.NavigateTo(NavigationView.RestartingView);
+ }
+ });
+ LogManager.Log("Waiting 2 seconds...");
+ await Task.Delay(2000);
+
+ try
+ {
+ LogManager.Log("Disposing watch dog...");
+ _watchdogServer.Dispose();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error disposing watch dog.");
+ }
+
+ LogManager.Log("Raising OnApplicationShutDown for all view models...");
foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<PPCViewModel>())
{
- vm.OnApplicationShuttingDown();
+ try
+ {
+ vm.OnApplicationShuttingDown();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error on {vm.GetType().Name}.OnApplicationShutDown().");
+ }
}
}
catch { }
+ try
+ {
+ LogManager.Log("Saving application settings...");
+ SettingsManager.Default.GetOrCreate<PPCSettings>().PreviousApplicationVersion = Version.ToString();
+ SettingsManager.Default.Save();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error saving application settings.");
+ }
+
+ try
+ {
+ await FinalizeApplication();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error occurred on application shutdown finalization.");
+ }
+
LogManager.Log($"Executing '{updaterPath}' with arguments '{arguments}'...");
- Process.Start(updaterPath, arguments);
+
+ Process p = new Process();
+ p.StartInfo.FileName = updaterPath;
+ p.StartInfo.Arguments = arguments;
+ p.StartInfo.LoadUserProfile = true;
+ p.StartInfo.UseShellExecute = true;
+ p.Start();
LogManager.Log("Terminating application...");
Environment.Exit(0);
@@ -546,5 +723,48 @@ namespace Tango.PPC.UI.PPCApplication
{
IsScreenLocked = true;
}
+
+ public void SetWindowState(WindowState state)
+ {
+ InvokeUI(() =>
+ {
+ MainWindow.Instance.WindowState = state;
+ });
+ }
+
+ private Task FinalizeApplication()
+ {
+ LogManager.Log("Finalizing application...");
+
+ return LimitedTimeTask.StartNew(() =>
+ {
+ try
+ {
+ LogManager.Log("Flushing machine events...");
+ _eventLogger.Log(EventTypes.APPLICATION_TERMINATED, "User Interface Terminated.");
+ _eventLogger.FlushAll();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error flushing machine events.");
+ }
+
+ try
+ {
+ LogManager.Log("Disposing insights manager (max 40 seconds to complete)...");
+ Stopwatch watch = new Stopwatch();
+ watch.Start();
+ var frame = InsightsFrame.CreateEmpty(DateTime.UtcNow);
+ InsightsManager.Default.InsertFrame(frame);
+ InsightsManager.Default.Dispose();
+ watch.Stop();
+ LogManager.Log($"Insights manager disposed after {(int)watch.Elapsed.TotalSeconds} seconds.");
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error disposing insights manager.");
+ }
+ }, TimeSpan.FromSeconds(40));
+ }
}
}