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; }
#endregion
}

View File

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

View File

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

View File

@ -7,6 +7,7 @@ using ReactiveUI;
using ReactiveUI.SourceGenerators;
using StarsAssistant.Services;
using Splat;
using StarsAssistant.Model;
namespace StarsAssistant.ViewModels;
@ -14,13 +15,15 @@ public partial class PlayerPlanetViewModel : ViewModelBase
{
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)
{
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.");
Planet = planet;
@ -58,13 +61,13 @@ public partial class PlayerPlanetViewModel : ViewModelBase
FleetManager fm = Locator.Current.GetService<FleetManager>()!;
var fleetSummaryChanges = fm.FleetSummaries
_fleetSummaryChanges = fm.FleetSummariesByDestination
.Connect()
.Watch(Name)
.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)
.Log(this, "PopulationEnRoute", pop => $"{Name}: {pop}")
.ToProperty(this, vm => vm.PopulationEnRoute)