Skip to content

Commit fb5ca98

Browse files
committed
Should complete the scaffolding for the console app
1 parent 59543f4 commit fb5ca98

File tree

8 files changed

+245
-53
lines changed

8 files changed

+245
-53
lines changed

src/ArcadeManager.Console/ArcadeManager.Console.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.2" />
1112
<PackageReference Include="Spectre.Console" Version="0.49.1" />
1213
<PackageReference Include="Spectre.Console.Cli" Version="0.49.1" />
1314
</ItemGroup>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using ArcadeManager.Infrastructure;
2+
using ArcadeManager.Models;
3+
4+
namespace ArcadeManager.Console;
5+
6+
public class ConsoleEnvironment : IEnvironment
7+
{
8+
private AppData? _appData;
9+
private string? _basePath;
10+
11+
public AppData GetAppData()
12+
{
13+
if (_appData != null) { return _appData; }
14+
15+
string content = File.ReadAllText(Path.Join(GetBasePath(), "Data", "appdata.json"));
16+
_appData = Serializer.Deserialize<AppData>(content);
17+
18+
return _appData;
19+
}
20+
21+
public string GetBasePath()
22+
{
23+
if (!string.IsNullOrEmpty(_basePath)) { return _basePath; }
24+
25+
// See stackoverflow.com/a/58307732/6776
26+
using var processModule = System.Diagnostics.Process.GetCurrentProcess().MainModule;
27+
_basePath = System.IO.Path.GetDirectoryName(processModule?.FileName);
28+
29+
return _basePath!;
30+
}
31+
32+
public string GetSettingsOs()
33+
{
34+
// unused in console mode
35+
return string.Empty;
36+
}
37+
38+
public void SettingsIgnoredVersionAdd(string version)
39+
{
40+
// do nothing as the console version doesn't check for update
41+
}
42+
43+
public bool SettingsIgnoredVersionHas(string version)
44+
{
45+
// do nothing as the console version doesn't check for update
46+
return false;
47+
}
48+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
using ArcadeManager.Models;
3+
4+
namespace ArcadeManager.Console;
5+
6+
public class ConsoleMessageHandler : IMessageHandler
7+
{
8+
public bool MustCancel { get; set; }
9+
public int TotalItems { get; set; }
10+
public int TotalSteps { get; set; }
11+
public int CurrentItem { get; set; }
12+
public int CurrentStep { get; set; }
13+
14+
public void Done(string label, string folder)
15+
{
16+
System.Console.WriteLine(label);
17+
18+
if (!string.IsNullOrEmpty(folder)) {
19+
System.Console.WriteLine($"Target folder: {folder}");
20+
}
21+
}
22+
23+
public void Error(Exception ex)
24+
{
25+
System.Console.WriteLine(ex.Message);
26+
System.Console.WriteLine(ex.StackTrace);
27+
}
28+
29+
public void Init(string label)
30+
{
31+
System.Console.WriteLine(label);
32+
}
33+
34+
public void Processed(GameRom game)
35+
{
36+
System.Console.WriteLine($"Processed: {game.Name}");
37+
}
38+
39+
public void Progress(string label)
40+
{
41+
System.Console.WriteLine(label);
42+
}
43+
44+
public void Progress(string label, int total, int current)
45+
{
46+
System.Console.WriteLine(label);
47+
}
48+
}

src/ArcadeManager.Console/Program.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using System.ComponentModel;
2-
using System.Diagnostics.CodeAnalysis;
3-
using ArcadeManager.Console.Commands;
1+
using ArcadeManager.Console.Commands;
42
using ArcadeManager.Console.Settings;
53
using Spectre.Console;
64
using Spectre.Console.Cli;
@@ -11,9 +9,7 @@ public static class Program
119
{
1210
public static int Main(string[] args)
1311
{
14-
System.Console.ReadLine();
15-
16-
var app = new CommandApp();
12+
var app = new CommandApp(new TypeRegistrar());
1713

1814
app.Configure(config =>
1915
{
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using ArcadeManager;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Spectre.Console.Cli;
5+
6+
namespace ArcadeManager.Console;
7+
8+
// copied from github.com/spectreconsole/examples/blob/main/examples/Cli/Injection/Infrastructure/TypeRegistrar.cs
9+
public sealed class TypeRegistrar : ITypeRegistrar
10+
{
11+
private readonly IServiceCollection builder;
12+
13+
public TypeRegistrar()
14+
{
15+
builder = new ServiceCollection();
16+
17+
// environment
18+
builder.AddSingleton<IEnvironment, ConsoleEnvironment>();
19+
20+
// infrastructure
21+
builder.AddSingleton<Infrastructure.IWebClientFactory, Infrastructure.WebClientFactory>();
22+
builder.AddSingleton<Infrastructure.IFileSystem, Infrastructure.FileSystem>();
23+
builder.AddSingleton<Infrastructure.IDatFile, Infrastructure.DatFile>();
24+
25+
// services
26+
builder.AddSingleton<Services.IDownloader, Services.Downloader>();
27+
builder.AddSingleton<Services.ICsv, Services.Csv>();
28+
builder.AddSingleton<Services.IOverlays, Services.Overlays>();
29+
builder.AddSingleton<Services.IRoms, Services.Roms>();
30+
builder.AddSingleton<Services.IUpdater, Services.Updater>();
31+
builder.AddSingleton<Services.ILocalizer, Services.Localizer>();
32+
builder.AddSingleton<Services.IWizard, Services.Wizard>();
33+
builder.AddSingleton<Services.IDatChecker, Services.DatChecker>();
34+
builder.AddSingleton<Services.IServiceProvider, Services.ServiceProvider>();
35+
36+
builder.AddSingleton<IMessageHandler, ConsoleMessageHandler>();
37+
}
38+
39+
public ITypeResolver Build()
40+
{
41+
return new TypeResolver(builder.BuildServiceProvider());
42+
}
43+
44+
public void Register(Type service, Type implementation)
45+
{
46+
builder.AddSingleton(service, implementation);
47+
}
48+
49+
public void RegisterInstance(Type service, object implementation)
50+
{
51+
builder.AddSingleton(service, implementation);
52+
}
53+
54+
public void RegisterLazy(Type service, Func<object> factory)
55+
{
56+
ArgumentNullException.ThrowIfNull(factory);
57+
58+
builder.AddSingleton(service, (provider) => factory());
59+
}
60+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using Spectre.Console.Cli;
2+
3+
namespace ArcadeManager.Console;
4+
5+
// copied from github.com/spectreconsole/examples/blob/main/examples/Cli/Injection/Infrastructure/TypeResolver.cs
6+
public sealed class TypeResolver : ITypeResolver, IDisposable
7+
{
8+
private readonly IServiceProvider _provider;
9+
10+
public TypeResolver(IServiceProvider provider)
11+
{
12+
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
13+
}
14+
15+
public object? Resolve(Type? type)
16+
{
17+
if (type == null)
18+
{
19+
return null;
20+
}
21+
22+
return _provider.GetService(type);
23+
}
24+
25+
public void Dispose()
26+
{
27+
if (_provider is IDisposable disposable)
28+
{
29+
disposable.Dispose();
30+
}
31+
}
32+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using ArcadeManager.Infrastructure;
2+
using ArcadeManager.Models;
3+
4+
namespace ArcadeManager;
5+
6+
/// <summary>
7+
/// Settings manager
8+
/// </summary>
9+
/// <remarks>
10+
/// Initializes a new instance of the <see cref="SettingsManager"/> class.
11+
/// </remarks>
12+
/// <param name="fileName">Name of the file.</param>
13+
public class SettingsManager(string fileName)
14+
{
15+
private readonly string _filePath = GetLocalFilePath(fileName);
16+
17+
/// <summary>
18+
/// Loads the settings.
19+
/// </summary>
20+
/// <returns>The settings</returns>
21+
public Settings LoadSettings() =>
22+
File.Exists(_filePath) ?
23+
Serializer.Deserialize<Settings>(File.ReadAllText(_filePath)) :
24+
null;
25+
26+
/// <summary>
27+
/// Saves the settings.
28+
/// </summary>
29+
/// <param name="settings">The settings.</param>
30+
public void SaveSettings(Settings settings)
31+
{
32+
string json = Serializer.Serialize(settings);
33+
34+
var fi = new FileInfo(_filePath);
35+
if (!Directory.Exists(fi.DirectoryName))
36+
{
37+
Directory.CreateDirectory(fi.DirectoryName);
38+
}
39+
40+
File.WriteAllText(_filePath, json);
41+
}
42+
43+
/// <summary>
44+
/// Gets the local file path.
45+
/// </summary>
46+
/// <param name="fileName">Name of the file.</param>
47+
/// <returns>The local file path</returns>
48+
private static string GetLocalFilePath(string fileName)
49+
{
50+
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
51+
return Path.Combine(appData, fileName);
52+
}
53+
}

src/ArcadeManager/ArcadeManagerEnvironment.cs

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -137,50 +137,4 @@ public void SettingsIgnoredVersionAdd(string version) {
137137
public bool SettingsIgnoredVersionHas(string version) {
138138
return settings.IgnoredVersions.Contains(version);
139139
}
140-
141-
/// <summary>
142-
/// Settings manager
143-
/// </summary>
144-
/// <remarks>
145-
/// Initializes a new instance of the <see cref="SettingsManager"/> class.
146-
/// </remarks>
147-
/// <param name="fileName">Name of the file.</param>
148-
internal class SettingsManager(string fileName)
149-
{
150-
private readonly string _filePath = GetLocalFilePath(fileName);
151-
152-
/// <summary>
153-
/// Loads the settings.
154-
/// </summary>
155-
/// <returns>The settings</returns>
156-
public Settings LoadSettings() =>
157-
File.Exists(_filePath) ?
158-
Serializer.Deserialize<Settings>(File.ReadAllText(_filePath)) :
159-
null;
160-
161-
/// <summary>
162-
/// Saves the settings.
163-
/// </summary>
164-
/// <param name="settings">The settings.</param>
165-
public void SaveSettings(Settings settings) {
166-
string json = Serializer.Serialize(settings);
167-
168-
var fi = new FileInfo(_filePath);
169-
if (!Directory.Exists(fi.DirectoryName)) {
170-
Directory.CreateDirectory(fi.DirectoryName);
171-
}
172-
173-
File.WriteAllText(_filePath, json);
174-
}
175-
176-
/// <summary>
177-
/// Gets the local file path.
178-
/// </summary>
179-
/// <param name="fileName">Name of the file.</param>
180-
/// <returns>The local file path</returns>
181-
private static string GetLocalFilePath(string fileName) {
182-
string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
183-
return Path.Combine(appData, fileName);
184-
}
185-
}
186-
}
140+
}

0 commit comments

Comments
 (0)