Skip to content

Commit

Permalink
Apply load order to invalid refs report.
Browse files Browse the repository at this point in the history
Was finding it annoying how the order could change each time due to the parallel implementation. `AsOrdered` wasn't helping.

#107
  • Loading branch information
focustense committed Sep 5, 2021
1 parent f484aff commit 0768ead
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 4 deletions.
1 change: 1 addition & 0 deletions Focus.Apps.EasyNpc/Modules/MainModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<LoaderModel>();
builder.RegisterType<LoaderViewModel>();
builder.RegisterType<InvalidReferencesViewModel>();
builder.RegisterType<StartupReportViewModel>();
builder.RegisterType<MainViewModel>();
}
Expand Down
6 changes: 4 additions & 2 deletions Focus.Apps.EasyNpc/Reports/InvalidReferencesViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,18 @@ public InvalidReferenceViewModel(Npc npc, NpcOption option)

public class InvalidReferencesViewModel
{
public delegate InvalidReferencesViewModel Factory(Profile profile);

public IReadOnlyList<InvalidReferenceViewModel> Items { get; private init; }

public InvalidReferencesViewModel(Profile profile)
public InvalidReferencesViewModel(IGameSettings gameSettings, Profile profile)
{
Items = profile.Npcs
.AsParallel()
.AsOrdered()
.SelectMany(npc => npc.Options.Select(option => (npc, option)))
.Where(x => x.option.HasInvalidPaths)
.Select(x => new InvalidReferenceViewModel(x.npc, x.option))
.OrderByLoadOrder(x => x.Key, gameSettings.PluginLoadOrder)
.ToList()
.AsReadOnly();
}
Expand Down
5 changes: 3 additions & 2 deletions Focus.Apps.EasyNpc/Reports/StartupReportViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ public class StartupReportViewModel

public InvalidReferencesViewModel InvalidReferences { get; private init; }

public StartupReportViewModel(Profile profile)
public StartupReportViewModel(
InvalidReferencesViewModel.Factory invalidReferencesFactory, Profile profile)
{
InvalidReferences = new(profile);
InvalidReferences = invalidReferencesFactory(profile);
}
}
}
14 changes: 14 additions & 0 deletions Focus.Core/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace Focus
Expand All @@ -21,6 +22,19 @@ public static IEnumerable<string> NotNullOrEmpty(this IEnumerable<string?> seque
return sequence.Where(x => !string.IsNullOrEmpty(x))!;
}

public static IEnumerable<T> OrderByLoadOrder<T>(
this IEnumerable<T> sequence, Func<T, IRecordKey> keySelector, IEnumerable<string> loadOrder)
{
var loadOrderIndices = loadOrder
.Select((plugin, index) => (plugin, index))
.ToDictionary(x => x.plugin, x => x.index, StringComparer.CurrentCultureIgnoreCase);
return sequence
.Select(item => (item, key: keySelector(item)))
.OrderBy(x => loadOrderIndices.TryGetValue(x.key.BasePluginName, out var index) ? index : -1)
.ThenBy(x => int.TryParse(x.key.LocalFormIdHex, NumberStyles.HexNumber, null, out var id) ? id : -1)
.Select(x => x.item);
}

public static IEnumerable<T>? OrderBySafe<T, TKey>(this IEnumerable<T>? sequence, Func<T, TKey> keySelector)
{
// If we use null-projection inline, then C# interprets the final expression differently. This essentially
Expand Down

0 comments on commit 0768ead

Please sign in to comment.