sa/Stars Assistant/Services/CSVDataLoader.cs

108 lines
3.6 KiB
C#
Raw Normal View History

using System;
2024-09-17 18:20:42 +00:00
using System.IO;
using System.Reactive.Linq;
using System.Text.RegularExpressions;
using ReactiveUI;
using Splat;
2024-09-17 18:20:42 +00:00
using StarsAssistant.Helpers;
namespace StarsAssistant.Services;
public partial class CSVDataLoader : IEnableLogger
{
/// <summary>
/// Reference to the game metadata, retrieved by DI
/// </summary>
2024-09-17 18:20:42 +00:00
protected Services.Game Game = Locator.Current.GetService<Services.Game>()!;
2024-09-22 16:54:16 +00:00
/// <summary>
/// Regex to match fs watcher results to Stars file types.
/// </summary>
/// <returns>Precompiled RegEx</returns>
[GeneratedRegex(@".*\.(?<type>[pf])(?<player>\d)+$")]
private static partial Regex MyRegex();
2024-09-22 16:54:16 +00:00
/// <summary>
/// RegEx Instance to match Stars file types.
/// </summary>
protected Regex FileTypeRegEx = MyRegex();
2024-09-22 16:54:16 +00:00
/// <summary>
/// Instance of the FSWatcher, to which we subscribe.
/// </summary>
protected IObservable<FileSystemEventArgs> Watcher;
/// <summary>
/// Active subscription to FsWatcher.
/// </summary>
protected IDisposable? Subscription;
2024-09-17 18:20:42 +00:00
2024-09-22 16:54:16 +00:00
/// <summary>
/// Construct the instance and prepare our FS Watcher.
/// </summary>
public CSVDataLoader()
2024-09-17 18:20:42 +00:00
{
// string[] filters = { "*.p*", "*.f*", "*.map" };
2024-09-22 16:54:16 +00:00
Watcher = FsWatcher
2024-10-02 18:18:00 +00:00
.ObserveFileSystem(Game.GamePath, [ Game.PlanetFileSearchPattern, Game.FleetFileSearchPattern ])
.ThrottleAndDistinct(2, RxApp.TaskpoolScheduler)
.Log(this, $"{DateTime.Now.ToLongTimeString()} FsEvent", fsEvent => $"{fsEvent.FullPath} {fsEvent.ChangeType}")
.ObserveOn(RxApp.TaskpoolScheduler);
}
2024-09-22 16:54:16 +00:00
/// <summary>
/// Start the CSV watcher, and capture our disposable, so that we can shut
/// down the watcher if needed.
/// </summary>
public void StartCSVWatcher()
{
if (Subscription != null)
throw new InvalidOperationException("CSV Watcher is active, can't start it again.");
Subscription = Watcher.Subscribe(fsEvent => this.LoadFile(fsEvent.FullPath));
}
/// <summary>
/// Subscription to File Processing, called by our subscription to the watcher.
/// </summary>
/// <param name="fileName">The File to process</param>
protected void LoadFile(string fileName)
{
Match m = FileTypeRegEx.Match(fileName);
if (! m.Success)
2024-09-17 18:20:42 +00:00
{
this.Log().Error($"Failed to parse {fileName} to identify what we are looking at. Ignoring file.");
return;
}
string type = m.Groups["type"].Value;
string player = m.Groups["player"].Value;
this.Log().Debug($"Got file type {type} for player {player}");
2024-09-22 16:54:16 +00:00
switch (type)
{
case "p":
2024-10-02 18:18:00 +00:00
var planetLoader = new CSV.PlanetLoader();
planetLoader.ImportForRace(Services.Game.Player);
2024-09-26 20:18:50 +00:00
2024-10-02 18:18:00 +00:00
PlanetManager planetManager = Locator.Current.GetService<PlanetManager>()!;
planetManager.InitFromDatabase();
break;
case "f":
var fleetLoader = new CSV.FleetLoader();
fleetLoader.ImportForRace(Services.Game.Player);
FleetManager.PostProcessImportedData();
FleetManager fleetManager = Locator.Current.GetService<FleetManager>()!;
fleetManager.InitFromDatabase();
2024-09-22 16:54:16 +00:00
break;
default:
this.Log().Warn($"Planet loader got unknown file type ${type}. Ignoring file.");
break;
}
2024-09-17 18:20:42 +00:00
}
}