Skip to content

Commit

Permalink
Merge pull request #2248 from Nexus-Mods/loadorder-v1
Browse files Browse the repository at this point in the history
Load Order v1 (REDmods, simple list ui)
  • Loading branch information
Al12rs authored Nov 20, 2024
2 parents 9db6f9d + bdcf269 commit f579f02
Show file tree
Hide file tree
Showing 323 changed files with 2,070 additions and 521 deletions.
4 changes: 2 additions & 2 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<PackageVersion Include="FetchBannerlordVersion" Version="1.0.6.46" />
<PackageVersion Include="NLog" Version="5.2.8" />
<PackageVersion Include="Noggog.CSharpExt" Version="2.67.3" />
<PackageVersion Include="ObservableCollections" Version="2.2.0" />
<PackageVersion Include="ObservableCollections" Version="3.3.2" />
<PackageVersion Include="ObservableCollections.R3" Version="3.3.2" />
<PackageVersion Include="QoiSharp" Version="1.0.0" />
<PackageVersion Include="R3" Version="1.2.9" />
Expand Down Expand Up @@ -138,4 +138,4 @@
<PackageVersion Include="Splat.Microsoft.Extensions.Logging" Version="15.2.22" />
<PackageVersion Include="TransparentValueObjects" Version="1.0.2" />
</ItemGroup>
</Project>
</Project>
6 changes: 6 additions & 0 deletions NexusMods.App.sln
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Abstractions.Reso
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Abstractions.Resources.Resilience", "src\Abstractions\NexusMods.Abstractions.Resources.Resilience\NexusMods.Abstractions.Resources.Resilience.csproj", "{04219A58-C99C-4C3B-A477-5E4B29D1F275}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.Abstractions.UI", "src\Abstractions\NexusMods.Abstractions.UI\NexusMods.Abstractions.UI.csproj", "{A7417BB1-7E2C-413A-A999-546F021F683B}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.DataModel.SchemaVersions", "src\NexusMods.DataModel.SchemaVersions\NexusMods.DataModel.SchemaVersions.csproj", "{79E13AD1-187B-42F7-BDC3-EF8ABA308973}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NexusMods.DataModel.SchemaVersions.Tests", "tests\NexusMods.DataModel.SchemaVersions.Tests\NexusMods.DataModel.SchemaVersions.Tests.csproj", "{A5A2932D-B3EF-480B-BEBC-793F6FC90EDE}"
Expand Down Expand Up @@ -704,6 +705,10 @@ Global
{04219A58-C99C-4C3B-A477-5E4B29D1F275}.Debug|Any CPU.Build.0 = Debug|Any CPU
{04219A58-C99C-4C3B-A477-5E4B29D1F275}.Release|Any CPU.ActiveCfg = Release|Any CPU
{04219A58-C99C-4C3B-A477-5E4B29D1F275}.Release|Any CPU.Build.0 = Release|Any CPU
{A7417BB1-7E2C-413A-A999-546F021F683B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7417BB1-7E2C-413A-A999-546F021F683B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7417BB1-7E2C-413A-A999-546F021F683B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7417BB1-7E2C-413A-A999-546F021F683B}.Release|Any CPU.Build.0 = Release|Any CPU
{79E13AD1-187B-42F7-BDC3-EF8ABA308973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{79E13AD1-187B-42F7-BDC3-EF8ABA308973}.Debug|Any CPU.Build.0 = Debug|Any CPU
{79E13AD1-187B-42F7-BDC3-EF8ABA308973}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -840,6 +845,7 @@ Global
{BE8C17C4-E3B0-4D07-8CD0-0D15C3CCA9D5} = {0CB73565-1207-4A56-A79F-6A8E9BBD795C}
{D3BA5B5A-668A-443B-872C-3116CBB0BC0D} = {0CB73565-1207-4A56-A79F-6A8E9BBD795C}
{04219A58-C99C-4C3B-A477-5E4B29D1F275} = {0CB73565-1207-4A56-A79F-6A8E9BBD795C}
{A7417BB1-7E2C-413A-A999-546F021F683B} = {0CB73565-1207-4A56-A79F-6A8E9BBD795C}
{79E13AD1-187B-42F7-BDC3-EF8ABA308973} = {E7BAE287-D505-4D6D-A090-665A64309B2D}
{A5A2932D-B3EF-480B-BEBC-793F6FC90EDE} = {52AF9D62-7D5B-4AD0-BA12-86F2AA67428B}
{8D7E82BB-2F8D-455A-AF12-C486D9EC3B77} = {70D38D24-79AE-4600-8E83-17F3C11BA81F}
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/NexusMods.Benchmarks/Benchmarks/Sorting.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using BenchmarkDotNet.Attributes;
using NexusMods.Abstractions.DataModel.Entities;
using NexusMods.Abstractions.DataModel.Entities.Sorting;
using NexusMods.Abstractions.Loadouts;
using NexusMods.Abstractions.Loadouts.Sorting;
using NexusMods.Benchmarks.Interfaces;
using NexusMods.DataModel.Sorting;

Expand Down
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ nav:
- '00: Template': developers/games/0000-Template.md
- '01: Stardew Valley': developers/games/0001-StardewValley.md
- '02: Cyberpunk 2077': developers/games/0002-Cyberpunk2077.md
- '03: BaldursGate3': developers/games/0003-BaldursGate3.md
- '04: M&B2 Bannerlord': developers/games/0004-MountAndBlade2Bannerlord.md
- Misc:
- About Fomod: developers/misc/AboutFomod.md
- Comparison of File Management Systems: developers/misc/ComparisonOfFileManagementSystems.md
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using NexusMods.Abstractions.GameLocators.GameCapabilities;
using NexusMods.Abstractions.Games;
using NexusMods.MnemonicDB.Abstractions;
using NexusMods.Paths;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using NexusMods.Abstractions.Games;
using NexusMods.Paths;

namespace NexusMods.Abstractions.GameLocators;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using JetBrains.Annotations;
using NexusMods.Abstractions.GameLocators;

namespace NexusMods.Abstractions.Games;
namespace NexusMods.Abstractions.GameLocators;

/// <summary>
/// Additional store specific metadata for <see cref="GameLocatorResult"/>.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Collections.ObjectModel;
using NexusMods.Abstractions.Games;
using NexusMods.MnemonicDB.Abstractions;

namespace NexusMods.Abstractions.GameLocators;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using JetBrains.Annotations;
using NexusMods.Abstractions.GameLocators.Stores.EADesktop;

namespace NexusMods.Abstractions.Games.Stores.EADesktop;
namespace NexusMods.Abstractions.GameLocators.Stores.EADesktop;

/// <summary>
/// Metadata for games found that implement <see cref="IEADesktopGame"/>.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using JetBrains.Annotations;
using NexusMods.Abstractions.GameLocators.Stores.EGS;

namespace NexusMods.Abstractions.Games.Stores.EGS;
namespace NexusMods.Abstractions.GameLocators.Stores.EGS;

/// <summary>
/// Metadata for games found that implement <see cref="IEpicGame"/>.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using JetBrains.Annotations;
using NexusMods.Abstractions.GameLocators.Stores.GOG;

namespace NexusMods.Abstractions.Games.Stores.GOG;
namespace NexusMods.Abstractions.GameLocators.Stores.GOG;

/// <summary>
/// Metadata for games found that implement <see cref="IGogGame"/>.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using JetBrains.Annotations;
using NexusMods.Abstractions.GameLocators.Stores.Origin;

namespace NexusMods.Abstractions.Games.Stores.Origin;
namespace NexusMods.Abstractions.GameLocators.Stores.Origin;

/// <summary>
/// Metadata for games found that implement <see cref="IOriginGame"/>.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using JetBrains.Annotations;
using NexusMods.Abstractions.GameLocators.Stores.Steam;
using NexusMods.Paths;

namespace NexusMods.Abstractions.Games.Stores.Steam;
namespace NexusMods.Abstractions.GameLocators.Stores.Steam;

/// <summary>
/// Metadata for games found that implement <see cref="ISteamGame"/>.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using JetBrains.Annotations;
using NexusMods.Abstractions.GameLocators.Stores.Xbox;

namespace NexusMods.Abstractions.Games.Stores.Xbox;
namespace NexusMods.Abstractions.GameLocators.Stores.Xbox;

/// <summary>
/// Metadata for games found that implement <see cref="IXboxGame"/>.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using NexusMods.Abstractions.Games.Trees;
using NexusMods.Paths;
using NexusMods.Paths.Trees;
using NexusMods.Paths.Trees.Traits;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
using System.Runtime.CompilerServices;
using NexusMods.Abstractions.GameLocators;
using NexusMods.Paths;
using NexusMods.Paths.Trees;
using NexusMods.Paths.Trees.Traits;

namespace NexusMods.Abstractions.Games.Trees;
namespace NexusMods.Abstractions.GameLocators.Trees;

/// <summary>
/// Represents a tree node used for storing a game pathed location.
Expand Down
5 changes: 4 additions & 1 deletion src/Abstractions/NexusMods.Abstractions.Games/AGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ protected virtual ILoadoutSynchronizer MakeSynchronizer(IServiceProvider provide
public virtual ILibraryItemInstaller[] LibraryItemInstallers { get; } = [];

/// <inheritdoc/>
public virtual IDiagnosticEmitter[] DiagnosticEmitters { get; } = Array.Empty<IDiagnosticEmitter>();
public virtual IDiagnosticEmitter[] DiagnosticEmitters { get; } = [];

/// <inheritdoc/>
public virtual ISortableItemProviderFactory[] SortableItemProviderFactories { get; } = [];

/// <inheritdoc />
public virtual ILoadoutSynchronizer Synchronizer => _synchronizer.Value;
Expand Down
7 changes: 7 additions & 0 deletions src/Abstractions/NexusMods.Abstractions.Games/IGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using NexusMods.Abstractions.Loadouts.Synchronizers;
using NexusMods.MnemonicDB.Abstractions;


namespace NexusMods.Abstractions.Games;

/// <summary>
Expand Down Expand Up @@ -38,6 +39,12 @@ public interface IGame : ILocatableGame
/// </summary>
public IDiagnosticEmitter[] DiagnosticEmitters { get; }

/// <summary>
/// An array of all instances of <see cref="ISortableItemProviderFactory"/> supported
/// by the game.
/// </summary>
public ISortableItemProviderFactory[] SortableItemProviderFactories { get; }

/// <summary>
/// The synchronizer for this game.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Collections.ObjectModel;
using NexusMods.Abstractions.Loadouts;

namespace NexusMods.Abstractions.Games;

/// <summary>
/// A loadout specific provider and manager of sortable items.
/// </summary>
public interface ILoadoutSortableItemProvider
{
/// <summary>
/// The ISortableItemProviderFactory that created this provider
/// </summary>
public ISortableItemProviderFactory ParentFactory { get; }

/// <summary>
/// The id of the loadout that the sortable items are associated with
/// </summary>
public LoadoutId LoadoutId { get; }

/// <summary>
/// Observable collection of sorted sortable items in the sort order
/// </summary>
public ReadOnlyObservableCollection<ISortableItem> SortableItems { get; }

/// <summary>
/// Sets the relative position of a sortable item in the sort order
/// </summary>
/// <param name="sortableItem">item to move</param>
/// <param name="delta">positive or negative index delta</param>
Task SetRelativePosition(ISortableItem sortableItem, int delta);
}
40 changes: 40 additions & 0 deletions src/Abstractions/NexusMods.Abstractions.Games/ISortableItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using NexusMods.MnemonicDB.Abstractions;

namespace NexusMods.Abstractions.Games;

/// <summary>
/// An abstraction for a sortable item that can be moved around in a list relative to its siblings.
/// All items in the list will have a non-gaming sort index. If a item is moved the other items will
/// adjust to compensate for the positional change.
/// </summary>
public interface ISortableItem : IComparable<ISortableItem>
{
/// <summary>
/// Reference to the provider that manages this item
/// </summary>
public ILoadoutSortableItemProvider SortableItemProvider { get; }

/// <summary>
/// The index of the item in a sorted list of item as given by the provider
/// </summary>
public int SortIndex { get; set; }

/// <summary>
/// Name of the item for display purposes
/// </summary>
public string DisplayName { get; }

/// <summary>
/// The name of the winning mod containing the item
/// </summary>
public string ModName { get; set; }

/// <summary>
/// Represents whether the item is active in the sort order or not
/// An item is considered active if it is part of the sort order and will be loaded by the game
/// An item is considered inactive if it is for some reason not going to be loaded by the game,
/// e.g. it is disabled in the sort order, or parent mod is disabled.
/// </summary>
public bool IsActive { get; set; }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using NexusMods.Abstractions.Loadouts;

namespace NexusMods.Abstractions.Games;


/// <summary>
/// A factory for creating providers for sortable items for specific loadouts
/// </summary>
public interface ISortableItemProviderFactory
{
/// <summary>
/// Returns a provider of sortable items for a specific loadout
/// </summary>
ILoadoutSortableItemProvider GetLoadoutSortableItemProvider(LoadoutId loadoutId);


/// <summary>
/// Returns id of the type of the loadout
/// </summary>
Guid StaticSortOrderTypeId { get; }

/// <summary>
/// Display name for this sort order type
/// </summary>
string SortOrderName { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using NexusMods.Abstractions.UI;
using ReactiveUI;
using Unit = System.Reactive.Unit;

namespace NexusMods.Abstractions.Games;

/// <summary>
/// View model interface for a sortable item in the generic load order view
/// </summary>
public interface ISortableItemViewModel : IViewModelInterface
{
public ISortableItem SortableItem { get; }

public ReactiveCommand<Unit, Unit> MoveUp { get; }

public ReactiveCommand<Unit, Unit> MoveDown { get; }

public ReactiveCommand<int, Unit> MoveTo { get; }

public int SortIndex { get; }

public string DisplayName { get; }

public string GroupName { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using JetBrains.Annotations;
using NexusMods.Abstractions.Loadouts;
using NexusMods.MnemonicDB.Abstractions.Attributes;
using NexusMods.MnemonicDB.Abstractions.Models;

namespace NexusMods.Abstractions.Games;

/// <summary>
/// Represents an item that is sorted in a Load Order
/// This should not be used directly, but rather be extended by the game-specific implementation.
///
/// Each implementation should provide the game specific identifier used to map entries of the Load Order to items of the loadout.
/// E.g. the plugin name for Skyrim plugins, or the module uuid for BG3 pak files.
/// </summary>
[PublicAPI]
public partial class SortableEntry : IModelDefinition
{
private const string Namespace = "NexusMods.Loadouts.SortableEntry";

/// <summary>
/// Reference to the Load Order that this item is part of.
/// </summary>
public static readonly ReferenceAttribute<SortOrder> ParentSortOrder = new(Namespace, nameof(ParentSortOrder))
{
IsIndexed = true,
};

/// <summary>
/// The order in which this item should be loaded relative to other items in the Load Order.
/// </summary>
public static readonly Int32Attribute SortIndex = new(Namespace, nameof(SortIndex));

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@
<ProjectReference Include="..\NexusMods.Abstractions.Loadouts.Synchronizers\NexusMods.Abstractions.Loadouts.Synchronizers.csproj" />
<ProjectReference Include="..\NexusMods.Abstractions.Loadouts\NexusMods.Abstractions.Loadouts.csproj" />
<ProjectReference Include="..\NexusMods.Abstractions.NexusWebApi\NexusMods.Abstractions.NexusWebApi.csproj" />
<ProjectReference Include="..\NexusMods.Abstractions.UI\NexusMods.Abstractions.UI.csproj" />
<PackageReference Include="NexusMods.MnemonicDB.SourceGenerator" PrivateAssets="all" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
5 changes: 2 additions & 3 deletions src/Abstractions/NexusMods.Abstractions.Games/RunGameTool.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;
using CliWrap;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NexusMods.Abstractions.GameLocators;
using NexusMods.Abstractions.Games.Stores.GOG;
using NexusMods.Abstractions.Games.Stores.Steam;
using NexusMods.Abstractions.GameLocators.Stores.GOG;
using NexusMods.Abstractions.GameLocators.Stores.Steam;
using NexusMods.Abstractions.Jobs;
using NexusMods.Abstractions.Loadouts;
using NexusMods.Abstractions.NexusWebApi.Types.V2;
Expand Down
3 changes: 2 additions & 1 deletion src/Abstractions/NexusMods.Abstractions.Games/Services.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public static class Services
/// </summary>
public static IServiceCollection AddGames(this IServiceCollection services)
{
return services;
return services
.AddSortableEntryModel();
}
}
Loading

0 comments on commit f579f02

Please sign in to comment.