fixup fleet summaries

This commit is contained in:
Torben Nehmer 2024-10-19 20:05:12 +02:00
parent 5a933d7aea
commit 43810cbb61
4 changed files with 103 additions and 64 deletions

View File

@ -87,4 +87,5 @@ public class Fleet
public Race? Owner { get; set; } public Race? Owner { get; set; }
#endregion #endregion
} }

View File

@ -2,7 +2,7 @@ using System;
namespace StarsAssistant.Model; namespace StarsAssistant.Model;
public class FleetSummary public class FleetSummaryByDestination
{ {
public string Destination { get; set; } = string.Empty; public string Destination { get; set; } = string.Empty;
public int TotalIronium { get; set; } public int TotalIronium { get; set; }

View File

@ -28,79 +28,93 @@ public class FleetManager : IEnableLogger, IDisposable
/// <summary> /// <summary>
/// Fleet data summarized by destination, will be chaned to _fleets /// Fleet data summarized by destination, will be chaned to _fleets
/// </summary> /// </summary>
private SourceCache<FleetSummary, string> _fleetSummaries = new(fs => fs.Destination); 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();
/// <summary> /// <summary>
/// Public accessor to the continously updated fleet summaries. /// Public accessor to the continously updated fleet summaries.
/// </summary> /// </summary>
public IObservableCache<FleetSummary, string> FleetSummaries => _fleetSummaries.AsObservableCache(); // public IObservableCache<FleetSummaryByDestination, string> FleetSummariesByDestination => _fleetSummaries.AsObservableCache();
/// <summary> /// <summary>
/// Disposal tracking /// Disposal tracking
/// </summary> /// </summary>
private IDisposable _fleetSummariesSubscription; // private IDisposable _fleetSummariesSubscription;
public FleetManager() public FleetManager()
{ {
CreateFleetSummariesLink(); // CreateFleetSummariesLink();
} }
[MemberNotNull(nameof(_fleetSummariesSubscription))] // [MemberNotNull(nameof(_fleetSummariesSubscription))]
protected void CreateFleetSummariesLink() // protected void CreateFleetSummariesLink()
{ // {
_fleetSummariesSubscription = _fleets.Connect() // /*
.Filter(fleet => fleet.TrueDestination != "-- ") // _fleetSummariesSubscription = _fleets.Connect()
.GroupOn(fleet => fleet.TrueDestination) // .Filter(fleet => fleet.TrueDestination != "-- ")
.Log(this, $"{DateTime.Now.ToLongTimeString()} fleetWatcher", grp => $"{grp.TotalChanges} detected") // .Log(this, $"{DateTime.Now.ToLongTimeString()} fleetWatcher filter", fleet => $"{fleet}")
.Transform(group => new FleetSummary // // .AutoRefreshOnObservable(fleet => fleet.WhenAnyValue(
{ // // f => f.Ironium, f => f.Boranium, f => f.Germanium, f => f.Colonists))
Destination = group.GroupKey, // .Log(this, $"{DateTime.Now.ToLongTimeString()} fleetWatcher refresh", fleet => $"{fleet}")
TotalIronium = group.List.Items.Sum(f => f.Ironium), // .GroupOn(fleet => fleet.TrueDestination)
TotalBoranium = group.List.Items.Sum(f => f.Boranium), // .Log(this, $"{DateTime.Now.ToLongTimeString()} fleetWatcher group", grp => $"{grp.TotalChanges} detected")
TotalGermanium = group.List.Items.Sum(f => f.Germanium), // .Transform(group => new FleetSummaryByDestination
TotalColonists = group.List.Items.Sum(f => f.Colonists) // {
}) // Destination = group.GroupKey,
.AddKey(fs => fs.Destination) // TotalIronium = group.List.Items.Sum(f => f.Ironium),
.Log(this, "FleetManager _fleetSummaries update", changes => // TotalBoranium = group.List.Items.Sum(f => f.Boranium),
$"{changes.Adds} adds, {changes.Updates} updates, {changes.Removes} removes" // TotalGermanium = group.List.Items.Sum(f => f.Germanium),
) // TotalColonists = group.List.Items.Sum(f => f.Colonists)
.PopulateInto(_fleetSummaries) // })
;
/* // .AddKey(fs => fs.Destination)
// Demo only // .Log(this, "FleetManager _fleetSummaries update", changes =>
var sourceCache = new SourceCache<FleetSummary, string>(fs => fs.Destination); // $"{changes.Adds} adds, {changes.Updates} updates, {changes.Removes} removes"
var tmp = fleetSummaries // )
.AddKey(fs => fs.Destination) // .PopulateInto(_fleetSummaries)
.PopulateInto(sourceCache); // ;
// */
// /*
// // Demo only
// var sourceCache = new SourceCache<FleetSummaryByDestination, string>(fs => fs.Destination);
// var tmp = fleetSummaries
// .AddKey(fs => fs.Destination)
// .PopulateInto(sourceCache);
_fleetSummaries // _fleetSummaries
.ObserveOn(RxApp.MainThreadScheduler) // .ObserveOn(RxApp.MainThreadScheduler)
.Bind(out summaries) // .Bind(out summaries)
.DisposeMany() // .DisposeMany()
.Subscribe(); // .Subscribe();
d1 = summaries // d1 = summaries
.Subscribe(Observer.Create<FleetSummary>(f => // .Subscribe(Observer.Create<FleetSummaryByDestination>(f =>
{ // {
this.Log().Debug($"FleetSummary observed: {f}"); // this.Log().Debug($"FleetSummaryByDestination observed: {f}");
} // }
)); // ));
d2 = _fleetSummaries
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(x =>
{
var lst = x.ToList();
foreach (var f in lst)
{
this.Log().Debug($"Reason {f.Reason}, Type {f.Type}: {f.Item.Current}");
}
}
);
*/
}
// d2 = _fleetSummaries
// .ObserveOn(RxApp.MainThreadScheduler)
// .Subscribe(x =>
// {
// var lst = x.ToList();
// foreach (var f in lst)
// {
// this.Log().Debug($"Reason {f.Reason}, Type {f.Type}: {f.Item.Current}");
// }
// }
// );
// */
// }
/// <summary> /// <summary>
/// Load the fleet records from the database and push them into our source cache. /// Load the fleet records from the database and push them into our source cache.
/// If the data has been freshly imported, call PostProcessImportedData first. /// If the data has been freshly imported, call PostProcessImportedData first.
@ -108,6 +122,8 @@ public class FleetManager : IEnableLogger, IDisposable
public void InitFromDatabase() public void InitFromDatabase()
{ {
using var db = Locator.Current.GetService<StarsDatabase>()!; using var db = Locator.Current.GetService<StarsDatabase>()!;
// Load the full list
var allFleets = db.Fleet.ToList(); var allFleets = db.Fleet.ToList();
_fleets.Edit(innerCache => _fleets.Edit(innerCache =>
{ {
@ -115,6 +131,25 @@ public class FleetManager : IEnableLogger, IDisposable
innerCache.Add(allFleets); innerCache.Add(allFleets);
} }
); );
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);
}
);
} }
/// <summary> /// <summary>
@ -166,8 +201,8 @@ public class FleetManager : IEnableLogger, IDisposable
{ {
if (disposing) if (disposing)
{ {
_fleetSummariesSubscription.Dispose(); // _fleetSummariesSubscription.Dispose();
_fleetSummaries.Dispose(); _fleetSummariesByDestination.Dispose();
_fleets.Dispose(); _fleets.Dispose();
} }
} }

View File

@ -7,6 +7,7 @@ using ReactiveUI;
using ReactiveUI.SourceGenerators; using ReactiveUI.SourceGenerators;
using StarsAssistant.Services; using StarsAssistant.Services;
using Splat; using Splat;
using StarsAssistant.Model;
namespace StarsAssistant.ViewModels; namespace StarsAssistant.ViewModels;
@ -14,13 +15,15 @@ public partial class PlayerPlanetViewModel : ViewModelBase
{ {
private readonly Model.Planet Planet; private readonly Model.Planet Planet;
private Game Game; private readonly Services.Game Game;
private readonly IObservable<Change<FleetSummaryByDestination, string>> _fleetSummaryChanges;
public PlayerPlanetViewModel(Model.Planet planet) public PlayerPlanetViewModel(Model.Planet planet)
{ {
Game = Locator.Current.GetService<Game>()!; Game = Locator.Current.GetService<Services.Game>()!;
if (planet.OwnerId != Game.Player.Name) if (planet.OwnerId != Services.Game.Player.Name)
throw new InvalidOperationException("PlayerPlanet ViewModels can only be created for player planets."); throw new InvalidOperationException("PlayerPlanet ViewModels can only be created for player planets.");
Planet = planet; Planet = planet;
@ -58,13 +61,13 @@ public partial class PlayerPlanetViewModel : ViewModelBase
FleetManager fm = Locator.Current.GetService<FleetManager>()!; FleetManager fm = Locator.Current.GetService<FleetManager>()!;
var fleetSummaryChanges = fm.FleetSummaries _fleetSummaryChanges = fm.FleetSummariesByDestination
.Connect() .Connect()
.Watch(Name) .Watch(Name)
.Log(this, "fleetSummaryChange", change => $"{Name}: {change.Reason}: {change.Previous} => {change.Current}") .Log(this, "fleetSummaryChange", change => $"{Name}: {change.Reason}: {change.Previous} => {change.Current}")
; ;
_populationEnRouteHelper = fleetSummaryChanges _populationEnRouteHelper = _fleetSummaryChanges
.Select(change => change.Reason != ChangeReason.Remove ? change.Current.TotalColonists : 0) .Select(change => change.Reason != ChangeReason.Remove ? change.Current.TotalColonists : 0)
.Log(this, "PopulationEnRoute", pop => $"{Name}: {pop}") .Log(this, "PopulationEnRoute", pop => $"{Name}: {pop}")
.ToProperty(this, vm => vm.PopulationEnRoute) .ToProperty(this, vm => vm.PopulationEnRoute)