107 lines
3.5 KiB
C#
107 lines
3.5 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Reactive.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using ReactiveUI;
|
|
using Splat;
|
|
using StarsAssistant.Helpers;
|
|
|
|
namespace StarsAssistant.Services;
|
|
|
|
|
|
public partial class CSVDataLoader : IEnableLogger
|
|
{
|
|
/// <summary>
|
|
/// Reference to the game metadata, retrieved by DI
|
|
/// </summary>
|
|
protected Services.Game Game = Locator.Current.GetService<Services.Game>()!;
|
|
|
|
/// <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();
|
|
|
|
/// <summary>
|
|
/// RegEx Instance to match Stars file types.
|
|
/// </summary>
|
|
protected Regex FileTypeRegEx = MyRegex();
|
|
|
|
/// <summary>
|
|
/// Instance of the FSWatcher, to which we subscribe.
|
|
/// </summary>
|
|
protected IObservable<FileSystemEventArgs> Watcher;
|
|
|
|
/// <summary>
|
|
/// Active subscription to FsWatcher.
|
|
/// </summary>
|
|
protected IDisposable? Subscription;
|
|
|
|
/// <summary>
|
|
/// Construct the instance and prepare our FS Watcher.
|
|
/// </summary>
|
|
public CSVDataLoader()
|
|
{
|
|
// string[] filters = { "*.p*", "*.f*", "*.map" };
|
|
Watcher = FsWatcher
|
|
.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);
|
|
}
|
|
|
|
/// <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)
|
|
{
|
|
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}");
|
|
|
|
switch (type)
|
|
{
|
|
case "p":
|
|
var planetLoader = new CSV.PlanetLoader();
|
|
planetLoader.ImportForRace(Services.Game.Player);
|
|
|
|
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>()!;
|
|
break;
|
|
|
|
default:
|
|
this.Log().Warn($"Planet loader got unknown file type ${type}. Ignoring file.");
|
|
break;
|
|
}
|
|
}
|
|
}
|