Skip to content

Commit

Permalink
Refactor code to improve error handling and game button creation
Browse files Browse the repository at this point in the history
This commit introduces better error handling for file loading operations such as the system.xml and mame.xml. If these files are missing or corrupted, the application now shuts down, advising the user to reinstall the software. In addition, the game button creation was optimized to prioritize the machine's description as the search term, if it exists, for the YouTube video and info link functionalities. The system's edit page now creates an image folder for new systems, if not specified by the user.
  • Loading branch information
drpetersonfernandes committed Mar 31, 2024
1 parent 2e57081 commit f8fde6c
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 33 deletions.
43 changes: 43 additions & 0 deletions SimpleLauncher/EditSystem.xaml.cs
Expand Up @@ -2,6 +2,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
Expand Down Expand Up @@ -341,6 +342,10 @@ private void AddSystemButton_Click(object sender, RoutedEventArgs e)
{
ClearFields();
AdjustPlaceholderVisibility();

SaveSystemButton.IsEnabled = true;
DeleteSystemButton.IsEnabled = false;

MessageBox.Show("You can add a new system now.", "Info", MessageBoxButton.OK, MessageBoxImage.Information);
}

Expand Down Expand Up @@ -535,6 +540,44 @@ private void SaveSystemButton_Click(object sender, RoutedEventArgs e)

MessageBox.Show("System saved successfully.", "Info", MessageBoxButton.OK,
MessageBoxImage.Information);

// Create a folder inside images folder with the same name as SystemName
// only do that if user does not provide the SystemImageFolder
if (string.IsNullOrWhiteSpace(systemImageFolder))
{
// Get the application directory
string applicationDirectory = AppDomain.CurrentDomain.BaseDirectory;

// Construct the path to the 'images' directory
string imagesDirectory = Path.Combine(applicationDirectory, "images");

// Check if 'images' directory exists
if (!Directory.Exists(imagesDirectory))
{
Directory.CreateDirectory(imagesDirectory);
}

// Use SystemName as the name for the new folder inside 'images'
string newFolderPath = Path.Combine(imagesDirectory, systemName);

try
{
// Check if the folder exists, and create it if it doesn't
if (!Directory.Exists(newFolderPath))
{
Directory.CreateDirectory(newFolderPath);
MessageBox.Show($"I have also created a folder for this System within the 'images' folder at {newFolderPath}.\n\nYou may place the cover images for this System inside this folder.", "Info", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
catch (Exception exception)
{
string formattedException = $"The Simple Launcher failed to create an image folder for the newly created system.\n\nException detail: {exception}";
Task logTask = LogErrors.LogErrorAsync(exception, formattedException);
logTask.Wait(TimeSpan.FromSeconds(2));
throw;
}

}
}

private static void AddEmulatorToXml(XElement emulatorsElement, string name, string location, string parameters)
Expand Down
35 changes: 18 additions & 17 deletions SimpleLauncher/GameButtonFactory.cs
Expand Up @@ -29,15 +29,14 @@ internal class GameButtonFactory(

public async Task<Button> CreateGameButtonAsync(string filePath, string systemName, SystemConfig systemConfig)
{
// Load Video Url and Info Url from settings.xml
string videoUrl = settings.VideoUrl;
string infoUrl = settings.InfoUrl;

string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
fileNameWithoutExtension = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(fileNameWithoutExtension);

string imagePath = DetermineImagePath(fileNameWithoutExtension, systemConfig.SystemName, systemConfig);
bool isDefaultImage = imagePath.EndsWith(DefaultImagePath);

// Default search term for Video link and Info link
string searchTerm = fileNameWithoutExtension;

var textBlock = new TextBlock
{
Expand All @@ -54,6 +53,9 @@ public async Task<Button> CreateGameButtonAsync(string filePath, string systemNa
var machine = machines.FirstOrDefault(m => m.MachineName.Equals(fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase));
if (machine != null)
{
// Check if the machine's description is not null or empty; otherwise, keep using fileNameWithoutExtension
searchTerm = !string.IsNullOrWhiteSpace(machine.Description) ? machine.Description : fileNameWithoutExtension;

var descriptionTextBlock = new TextBlock
{
Text = machine.Description,
Expand All @@ -67,9 +69,8 @@ public async Task<Button> CreateGameButtonAsync(string filePath, string systemNa
textBlock.Inlines.Add(descriptionTextBlock);
}
}

var youtubeIcon = CreateYoutubeIcon(fileNameWithoutExtension, systemName, videoUrl);
var infoIcon = CreateInfoIcon(fileNameWithoutExtension, systemName, infoUrl);
var youtubeIcon = CreateYoutubeIcon(searchTerm, systemName, settings.VideoUrl);
var infoIcon = CreateInfoIcon(searchTerm, systemName, settings.InfoUrl);

var grid = new Grid
{
Expand Down Expand Up @@ -226,7 +227,7 @@ private static void LoadFallbackImage(Image imageControl, Button button, string
}
}

private Image CreateYoutubeIcon(string fileNameWithoutExtension, string systemName, string videoUrl)
private Image CreateYoutubeIcon(string searchTerm, string systemName, string videoUrl)
{
var youtubeIcon = new Image
{
Expand All @@ -246,8 +247,8 @@ private Image CreateYoutubeIcon(string fileNameWithoutExtension, string systemNa
youtubeIcon.PreviewMouseLeftButtonUp += (_, e) =>
{
PlayClick.PlayClickSound();
string searchTerm = $"{fileNameWithoutExtension} {systemName}";
string searchUrl = $"{videoUrl}{Uri.EscapeDataString(searchTerm)}";
string searchTerm2 = $"{searchTerm} {systemName}";
string searchUrl = $"{videoUrl}{Uri.EscapeDataString(searchTerm2)}";
try
{
Expand All @@ -259,9 +260,9 @@ private Image CreateYoutubeIcon(string fileNameWithoutExtension, string systemNa
}
catch (Exception exception)
{
string contextMessage = $"There was a problem open up the Video Link.\n\nException detail: {exception}";
string contextMessage = $"There was a problem open up the Video Link.\n\nException details: {exception}";
Task logTask = LogErrors.LogErrorAsync(exception, contextMessage);
MessageBox.Show($"There was a problem open up the Video Link.\n\nException detail: {exception.Message}.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
MessageBox.Show($"There was a problem open up the Video Link.\n\nException details: {exception.Message}.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
logTask.Wait(TimeSpan.FromSeconds(2));
throw;
}
Expand All @@ -270,7 +271,7 @@ private Image CreateYoutubeIcon(string fileNameWithoutExtension, string systemNa
return youtubeIcon;
}

private Image CreateInfoIcon(string fileNameWithoutExtension, string systemName, string infoUrl)
private Image CreateInfoIcon(string searchTerm, string systemName, string infoUrl)
{
var infoIcon = new Image
{
Expand All @@ -290,8 +291,8 @@ private Image CreateInfoIcon(string fileNameWithoutExtension, string systemName,
infoIcon.PreviewMouseLeftButtonUp += (_, e) =>
{
PlayClick.PlayClickSound();
string searchTerm = $"{fileNameWithoutExtension} {systemName}";
string searchUrl = $"{infoUrl}{Uri.EscapeDataString(searchTerm)}";
string searchTerm2 = $"{searchTerm} {systemName}";
string searchUrl = $"{infoUrl}{Uri.EscapeDataString(searchTerm2)}";
try
{
Process.Start(new ProcessStartInfo
Expand All @@ -302,9 +303,9 @@ private Image CreateInfoIcon(string fileNameWithoutExtension, string systemName,
}
catch (Exception exception)
{
string contextMessage = $"There was a problem open up the Info Link.\n\nException detail: {exception}";
string contextMessage = $"There was a problem open up the Info Link.\n\nException details: {exception}";
Task logTask = LogErrors.LogErrorAsync(exception, contextMessage);
MessageBox.Show($"There was a problem open up the Info Link.\n\nException detail: {exception.Message}.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
MessageBox.Show($"There was a problem open up the Info Link.\n\nException details: {exception.Message}.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
logTask.Wait(TimeSpan.FromSeconds(2));
throw;
}
Expand Down
2 changes: 1 addition & 1 deletion SimpleLauncher/MainWindow.xaml.cs
Expand Up @@ -39,7 +39,7 @@ public MainWindow()

// Load mame.xml
string xmlPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "mame.xml");
_machines = MameConfig.LoadFromXml(xmlPath).Result;
_machines = MameConfig.LoadFromXml(xmlPath);

// Load system.xml
try
Expand Down
30 changes: 23 additions & 7 deletions SimpleLauncher/MameConfig.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Xml.Linq;

Expand All @@ -12,7 +12,20 @@ public class MameConfig
public string MachineName { get; private init; }
public string Description { get; private init; }

public static async Task<List<MameConfig>> LoadFromXml(string xmlPath) {
public static List<MameConfig> LoadFromXml(string xmlPath)
{
// Check if the mame.xml file exists
if (!File.Exists(xmlPath))
{
MessageBox.Show("The file mame.xml could not be found.\n\nThe application will be Shutdown.\n\nPlease reinstall Simple Launcher to restore this file.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);

// Shutdown the application and exit
Application.Current.Shutdown();
Environment.Exit(0);

return new List<MameConfig>(); // This is technically unreachable due to the application exit above
}

try
{
XDocument xmlDoc = XDocument.Load(xmlPath);
Expand All @@ -23,12 +36,15 @@ public class MameConfig
Description = m.Element("Description")?.Value
}).ToList();
}
catch (Exception ex)
catch (Exception)
{
string errorMessage = $"Error loading MAME configurations from XML.\n\nException detail: {ex}";
MessageBox.Show(errorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
await LogErrors.LogErrorAsync(ex, $"{errorMessage}\n\nException details: {ex}");
return [];
MessageBox.Show("I could not load the file mame.xml or it is corrupted.\n\nThe application will be Shutdown.\n\nPlease reinstall Simple Launcher to restore this file.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);

// Shutdown current application instance
Application.Current.Shutdown();
Environment.Exit(0);

return new List<MameConfig>(); // This line is also technically unreachable due to the application exit
}
}
}
Expand Down
29 changes: 21 additions & 8 deletions SimpleLauncher/SystemConfig.cs
Expand Up @@ -30,7 +30,7 @@ public static List<SystemConfig> LoadSystemConfigs(string xmlPath)
{
try
{
// Check for the existence of the system.xml file
// Check for the existence of the system.xml
if (!File.Exists(xmlPath))
{
// Search for backup files in the application directory
Expand All @@ -52,17 +52,30 @@ public static List<SystemConfig> LoadSystemConfigs(string xmlPath)
}
else
{
string systemModel = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "system_model.xml");
// Rename system.model to to system.xml
File.Copy(systemModel, xmlPath!,
false); // Does not Overwrite the file if it already exists
try
{
// Location of system_model.xml
string systemModel = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "system_model.xml");

// Rename system.model to to system.xml
File.Copy(systemModel, xmlPath!, false); // Does not Overwrite the file if it already exists
}
catch (Exception)
{
string contextMessage = $"The file system_model.xml is missing.\n\nThe application will be Shutdown.\n\nPlease reinstall Simple Launcher to restore this file.";
MessageBox.Show(contextMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);

// Shutdown the application and exit
Application.Current.Shutdown();
Environment.Exit(0);
}
}
}
catch (Exception ex)
{
string contextMessage = $"Error creating the file system.xml.\n\nException details: {ex}\n";
string contextMessage = $"The file system.xml is corrupted.\n\nException details: {ex}";
Task logTask = LogErrors.LogErrorAsync(ex, contextMessage);
MessageBox.Show($"The system.xml is broken: {ex.Message}\n\nPlease fix it manually or delete it.\n\nIf you choose to delete it the application will create one for you.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
MessageBox.Show($"The system.xml is corrupted: {ex.Message}\n\nPlease fix it manually or delete it.\n\nIf you choose to delete it the application will create one for you.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
logTask.Wait(TimeSpan.FromSeconds(2));
return null;
}
Expand Down Expand Up @@ -126,7 +139,7 @@ public static List<SystemConfig> LoadSystemConfigs(string xmlPath)
}
catch (Exception ex2)
{
string contextMessage = $"Error loading system configurations from XML.\n\nException details: {ex2}";
string contextMessage = $"Error loading system configurations from system.xml.\n\nException details: {ex2}";
Task logTask = LogErrors.LogErrorAsync(ex2, contextMessage);
MessageBox.Show($"The system.xml is broken: {ex2.Message}\n\nPlease fix it manually or delete it.\n\nIf you choose to delete it the application will create one for you.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
logTask.Wait(TimeSpan.FromSeconds(2));
Expand Down

0 comments on commit f8fde6c

Please sign in to comment.