public SaveMenuLayoutTaskData(AsyncTaskWithProgress task, MenuLayout menuLayout, string path, bool nonDirtying) : base(task) { lock (menuLayout.FileSystem) { if (!string.IsNullOrEmpty(path) && System.IO.File.Exists(path)) { var menuPath = string.Intern(path); lock (menuPath) { BackupPath = path.GetUniqueBackupFilePath(); System.IO.File.Copy(path, BackupPath); } } } OriginalMenuLayout = menuLayout; SaveGeneration = menuLayout.SaveGeneration; if (menuLayout.FileSystem.Origin == FileSystemOrigin.HostComputer) { MenuLayoutToSave = menuLayout.FileSystem.Clone().Directories[GlobalDirectoryTable.RootDirectoryNumber] as MenuLayout; MenuLayoutToSave.FileSystem.Frozen = true; #if MEASURE_SAVE_PERFORMANCE MenuLayoutToSave.SaveGeneration = menuLayout.SaveGeneration; #endif // MEASURE_SAVE_PERFORMANCE } else { MenuLayoutToSave = menuLayout; } Path = path; NonDirtying = nonDirtying; }
public static MenuLayout Load(string filePath) { MenuLayout menuLayout = null; #if MEASURE_LOAD_PERFORMANCE var stopwatch = System.Diagnostics.Stopwatch.StartNew(); try { #endif // MEASURE_LOAD_PERFORMANCE var path = string.Intern(filePath); lock (path) { using (var fileStream = FileUtilities.OpenFileStream(filePath)) { var overrides = GetAttributeOverrides(); var serializer = new System.Xml.Serialization.XmlSerializer(typeof(MenuLayout), overrides, new System.Type[] { typeof(FileNode), typeof(MenuLayout), typeof(Folder), typeof(Program) }, null, null); menuLayout = serializer.Deserialize(fileStream) as MenuLayout; menuLayout.LoadComplete(false); return(menuLayout); } } #if MEASURE_LOAD_PERFORMANCE } finally { stopwatch.Stop(); DebugMessage("Load " + filePath + " took " + stopwatch.Elapsed.ToString()); if (menuLayout != null) { menuLayout.Logger.Log("Load: " + filePath + " took " + stopwatch.Elapsed.ToString()); } } #endif // MEASURE_LOAD_PERFORMANCE }
/// <summary> /// Gets the menu layout to save. /// </summary> /// <returns>The menu layout to save.</returns> public MenuLayout GetMenuLayoutToSave() { if (MenuLayoutToSave.Crc32 != OriginalMenuLayout.Crc32) { MenuLayoutToSave = OriginalMenuLayout.FileSystem.Clone().Directories[GlobalDirectoryTable.RootDirectoryNumber] as MenuLayout; MenuLayoutToSave.SaveGeneration = OriginalMenuLayout.SaveGeneration; } return(MenuLayoutToSave); }
/// <summary> /// Synchronizes the host system's MenuLayout to match the contents of a Locutus device. /// </summary> /// <param name="device">The Locutus device whose file system is to be imposed upon the Menu Layout of the host PC.</param> /// <param name="hostMenuLayout">The host PC MenuLayout to be brought in sync with Locutus.</param> /// <param name="ignoreInconsistentFileSystem">If <c>true</c> and the device's file system is in an inconsistent state, do the sync anyway.</param> /// <param name="onCompleteHandler">Called upon successful completion of the operation. This argument may be <c>null</c>.</param> /// <param name="errorHandler">Error handler, used to report errors to the user.</param> public static void SyncDeviceToHost(this Device device, MenuLayout hostMenuLayout, bool ignoreInconsistentFileSystem, DeviceCommandCompleteHandler onCompleteHandler, DeviceCommandErrorHandler errorHandler) { if (device.IsSafeToStartCommand()) { ////var configuration = SingleInstanceApplication.Instance.GetConfiguration<Configuration>(); var customData = new Tuple <MenuLayout, bool>(hostMenuLayout, ignoreInconsistentFileSystem); var executeCommandTaskData = new ExecuteDeviceCommandAsyncTaskData(device, ProtocolCommandId.MultistagePseudoCommand) { Title = Resources.Strings.DeviceMultistageCommand_SyncingToFiles_Title, ProgressUpdateMode = ExecuteDeviceCommandProgressUpdateMode.Custom, Data = customData, OnSuccess = onCompleteHandler, OnFailure = errorHandler }; executeCommandTaskData.StartTask(SyncDeviceToHost, true, 1); } }
/// <summary> /// Downloads the host system's MenuLayout file system content to a Locutus device. /// </summary> /// <param name="device">The target Locutus device whose file system is to be updated to match that of the host PC.</param> /// <param name="hostMenuLayout">The host PC MenuLayout to push down to Locutus.</param> /// <param name="onCompleteHandler">Called upon successful completion of the operation. This argument may be <c>null</c>.</param> /// <param name="errorHandler">Error handler, used to report errors to the user.</param> public static void SyncHostToDevice(this Device device, MenuLayout hostMenuLayout, DeviceCommandCompleteHandler onCompleteHandler, DeviceCommandErrorHandler errorHandler) { if (device.IsSafeToStartCommand()) { var executeCommandTaskData = new ExecuteDeviceCommandAsyncTaskData(device, ProtocolCommandId.MultistagePseudoCommand) { Title = Resources.Strings.DeviceMultistageCommand_UpdatingFiles_Title, ProgressUpdateMode = ExecuteDeviceCommandProgressUpdateMode.Custom, // First bool is whether to reset menu position data (true => REMOVE IT). // Second bool is whether to update root file name (false => RETAIN IT). Data = new Tuple <MenuLayout, bool, bool>(hostMenuLayout, true, false), OnSuccess = onCompleteHandler, OnFailure = errorHandler }; executeCommandTaskData.StartTask(SyncHostToDevice, true, 1); } }
private static void RestoreFileSystem(AsyncTaskData taskData) { var data = (ExecuteDeviceCommandAsyncTaskData)taskData; var succeeded = false; try { var restoreDirectory = data.Data as string; var menuLayoutPath = System.IO.Path.Combine(restoreDirectory, Configuration.Instance.DefaultMenuLayoutFileName); var menuLayout = MenuLayout.Load(menuLayoutPath); // First bool is whether to reset menu position data (false => RESTORE IT). // Second bool is whether to update root file name (true => RESTORE IT). data.Data = new Tuple <MenuLayout, bool, bool>(menuLayout, false, true); SyncHostToDevice(data); succeeded = data.Succeeded; } finally { data.Succeeded = succeeded; } }
private static void BackupFileSystem(AsyncTaskData taskData) { var data = (ExecuteDeviceCommandAsyncTaskData)taskData; var succeeded = false; try { var configuration = SingleInstanceApplication.Instance.GetConfiguration <Configuration>(); var romsConfiguration = SingleInstanceApplication.Instance.GetConfiguration <INTV.Shared.Model.RomListConfiguration>(); var roms = SingleInstanceApplication.Instance.Roms; var device = data.Device; data.UpdateTaskProgress(0, Resources.Strings.DeviceMultistageCommand_BackupFileSystem_Syncing); var deviceFileSystemFlags = GetDirtyFlags.Instance.Execute <LfsDirtyFlags>(device.Port, data); // Always re-fetch the file system. When we're done, tell the UI to refresh. var fileSystem = DownloadFileSystemTables.Instance.Execute <FileSystem>(device.Port, data); fileSystem.Status = deviceFileSystemFlags; data.Result = new FileSystemSyncErrors(deviceFileSystemFlags); // Retrieve the forks. var backupDirectory = data.Data as string; var forksToBackup = fileSystem.Forks.Where(f => f != null); if (forksToBackup.Any() && !data.AcceptCancelIfRequested()) { var forkFileNames = new List <string>(); foreach (var fork in forksToBackup) { bool dontCare; var backupDir = backupDirectory; // we don't want to modify backupDirectory var fileName = GetPathForFork(data, fork, fileSystem, roms, romsConfiguration, ref backupDir, out dontCare); fileName = System.IO.Path.GetFileName(fileName); forkFileNames.Add(fileName); } succeeded = device.RetrieveForkData(data, forksToBackup, backupDirectory, forkFileNames); } else { succeeded = data.CancelRequsted; } if (succeeded && !data.AcceptCancelIfRequested()) { data.UpdateTaskProgress(0, Resources.Strings.DeviceMultistageCommand_BackupFileSystem_CreatingMenuLayout); var menuBackupPath = System.IO.Path.Combine(backupDirectory, configuration.DefaultMenuLayoutFileName); var menuLayout = new MenuLayout(fileSystem, device.UniqueId); menuLayout.LoadComplete(false); menuLayout.Save(menuBackupPath, true); } else if (data.CancelRequsted && succeeded) { succeeded = true; } } catch (Exception e) { System.Diagnostics.Debug.WriteLine(e.Message); succeeded = false; if (!string.IsNullOrWhiteSpace(data.FailureMessage)) { var builder = new System.Text.StringBuilder(Resources.Strings.DeviceMultistageCommand_BackupFileSystem_Failed); builder.AppendLine().AppendLine(data.FailureMessage); data.FailureMessage = builder.ToString(); } else { data.FailureMessage = Resources.Strings.DeviceMultistageCommand_BackupFileSystem_Failed; } throw; } finally { data.Succeeded = succeeded; } }