sa/Stars Assistant/Services/FleetManager.cs

145 lines
4.6 KiB
C#
Raw Normal View History

2024-10-02 18:18:00 +00:00
using System;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
2024-10-02 18:18:00 +00:00
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Reactive;
2024-10-02 18:18:00 +00:00
using System.Reactive.Linq;
using System.Text.RegularExpressions;
using Avalonia.Controls.Platform;
2024-10-02 18:18:00 +00:00
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
2024-10-02 18:18:00 +00:00
using Splat;
using StarsAssistant.Model;
using StarsAssistant.ViewModels;
namespace StarsAssistant.Services;
public class FleetManager : IEnableLogger, IDisposable
2024-10-02 18:18:00 +00:00
{
protected Services.Game Game = Locator.Current.GetService<Services.Game>()!;
/// <summary>
/// SourceList for fleets read from the game files
2024-10-02 18:18:00 +00:00
/// </summary>
2024-10-05 16:47:53 +00:00
private SourceList<Fleet> _fleets = new();
2024-10-02 18:18:00 +00:00
/// <summary>
/// Fleet data summarized by destination, will be chaned to _fleets
/// </summary>
2024-10-19 18:05:12 +00:00
private SourceCache<FleetSummaryByDestination, string> _fleetSummariesByDestination = new(fs => fs.Destination);
/// <summary>
/// Extract a readonly Cache for all fleet summaries tracked by the
/// fleet manager.
/// </summary>
public IObservableCache<FleetSummaryByDestination, string> FleetSummariesByDestination
=> _fleetSummariesByDestination.AsObservableCache();
public FleetManager()
{
2024-10-19 18:05:12 +00:00
// CreateFleetSummariesLink();
}
2024-10-04 17:05:23 +00:00
2024-10-02 18:18:00 +00:00
/// <summary>
/// Load the fleet records from the database and push them into our source cache.
/// If the data has been freshly imported, call PostProcessImportedData first.
/// </summary>
public void InitFromDatabase()
{
using var db = Locator.Current.GetService<StarsDatabase>()!;
2024-10-19 18:05:12 +00:00
// Load the full list
2024-10-02 18:18:00 +00:00
var allFleets = db.Fleet.ToList();
2024-10-04 17:05:23 +00:00
_fleets.Edit(innerCache =>
{
innerCache.Clear();
2024-10-05 16:47:53 +00:00
innerCache.Add(allFleets);
2024-10-04 17:05:23 +00:00
}
);
2024-10-19 18:05:12 +00:00
var summaries = from f in allFleets
group f by f.TrueDestination into grp
select new FleetSummaryByDestination
{
Destination = grp.Key,
TotalIronium = grp.Sum(f => f.Ironium),
TotalBoranium = grp.Sum(f => f.Boranium),
TotalGermanium = grp.Sum(f => f.Germanium),
TotalColonists = grp.Sum(f => f.Colonists)
};
var cacheKeys = _fleetSummariesByDestination.Keys.ToList();
var summariesToDelete = cacheKeys.Except(summaries.Select(sum => sum.Destination));
_fleetSummariesByDestination.Edit(innerCache => {
innerCache.RemoveKeys(summariesToDelete);
innerCache.AddOrUpdate(summaries);
}
);
2024-10-02 18:18:00 +00:00
}
/// <summary>
/// Helper to fill up missing data from the original import. Tries to deduce
/// missing properties using heuristics.
/// </summary>
public static void PostProcessImportedData()
{
using var db = Locator.Current.GetService<StarsDatabase>()!;
// Check for all cases where we're targeting another fleet instead of
// a planet. Update the DB accordingly.
var playerFleets = from flt in db.Fleet
where flt.OwnerFileId == Game.Player.PlayerFileId
select flt;
Regex shipPattern = new ($@"^{Regex.Escape(Game.Player.Name)} (?<ShipType>.+) #\d+$");
foreach (Fleet flt in playerFleets)
{
if (flt.Destination != "-- ")
{
var trueDest = db.Fleet
.FirstOrDefault(f => f.FleetName == $"{Game.Player.Name} {flt.Destination}"
&& f.Planet != String.Empty);
flt.TrueDestination = trueDest?.Planet ?? flt.Destination;
}
else
{
flt.TrueDestination = flt.Planet;
2024-10-02 18:18:00 +00:00
}
Match m = shipPattern.Match(flt.FleetName);
if (m.Success)
flt.ShipTypeGuess = m.Groups[1].Value;
flt.Colonists *= 100;
db.Update(flt);
2024-10-02 18:18:00 +00:00
}
db.SaveChanges();
}
/// <summary>
/// Handle disposal of all subscriptions and dependencies.
/// </summary>/
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
2024-10-19 18:05:12 +00:00
_fleetSummariesByDestination.Dispose();
_fleets.Dispose();
}
}
/// <summary>
/// Boilerplate disposal
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
2024-10-02 18:18:00 +00:00
}