Skip to content

Commit 22d4438

Browse files
- More work on package loading.
- Implementing equality comparison for package dependencies.
1 parent 9d296da commit 22d4438

File tree

5 files changed

+114
-21
lines changed

5 files changed

+114
-21
lines changed

Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/DataInterfaceDefinitions.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,59 @@ public record DependencyInfo : IPackageDependencyInfo
5151
public ulong SteamWorkshopId { get; init; }
5252
public ContentPackage DependencyPackage { get; init; }
5353
public bool IsMissing { get; init; }
54+
public bool IsWorkshopInstallation { get; init; }
55+
56+
public virtual bool Equals(DependencyInfo other) => Equals(this, other);
57+
58+
public override int GetHashCode()
59+
{
60+
if (DependencyPackage is not null)
61+
return DependencyPackage.GetHashCode();
62+
if (SteamWorkshopId != 0)
63+
return SteamWorkshopId.GetHashCode();
64+
if (!PackageName.IsNullOrWhiteSpace() && !FolderPath.IsNullOrWhiteSpace())
65+
return string.Concat(PackageName, FolderPath).GetHashCode();
66+
if (!InternalName.IsNullOrWhiteSpace() && !FolderPath.IsNullOrWhiteSpace())
67+
return string.Concat(InternalName, FolderPath).GetHashCode();
68+
69+
return base.GetHashCode();
70+
}
71+
72+
public bool Equals(IPackageDependencyInfo x, IPackageDependencyInfo y)
73+
{
74+
if (x is null)
75+
return false;
76+
if (y is null)
77+
return false;
78+
if (x == y)
79+
return true;
80+
81+
if (x.DependencyPackage is not null && y.DependencyPackage is not null)
82+
return y.DependencyPackage == x.DependencyPackage;
83+
84+
if (!x.FolderPath.IsNullOrWhiteSpace()
85+
&& !y.FolderPath.IsNullOrWhiteSpace()
86+
&& y.FolderPath == x.FolderPath)
87+
return true;
88+
89+
if (!x.FolderPath.IsNullOrWhiteSpace() != !y.FolderPath.IsNullOrWhiteSpace())
90+
return false;
91+
92+
if (!x.PackageName.IsNullOrWhiteSpace()
93+
&& !y.PackageName.IsNullOrWhiteSpace()
94+
&& y.PackageName == x.PackageName)
95+
return true;
96+
97+
if (x.SteamWorkshopId != 0 && y.SteamWorkshopId == x.SteamWorkshopId)
98+
return true;
99+
100+
return false;
101+
}
102+
103+
public int GetHashCode(IPackageDependencyInfo obj)
104+
{
105+
throw new NotImplementedException();
106+
}
54107
}
55108

56109
public record LocalizationResourceInfo : ILocalizationResourceInfo

Barotrauma/BarotraumaShared/SharedSource/LuaCs/Data/IPackageDependencyInfo.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
using System.Collections.Immutable;
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using System.Collections.Immutable;
24

35
namespace Barotrauma.LuaCs.Data;
46

5-
public interface IPackageDependencyInfo : IPackageInfo
7+
public interface IPackageDependencyInfo : IPackageInfo,
8+
IEqualityComparer<IPackageDependencyInfo>
69
{
710
/// <summary>
811
/// Root folder of the content package.
@@ -25,6 +28,11 @@ public interface IPackageDependencyInfo : IPackageInfo
2528
/// This dependency was not found.
2629
/// </summary>
2730
public bool IsMissing { get; }
31+
32+
/// <summary>
33+
/// Whether the package is installed from the workshop. False means installation is from local mods.
34+
/// </summary>
35+
public bool IsWorkshopInstallation { get; }
2836
}
2937

3038
public interface IPackageDependenciesInfo

Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/IPackageManagementService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Collections.Immutable;
4+
using System.Diagnostics.CodeAnalysis;
45
using System.Globalization;
56
using Barotrauma.Extensions;
67
using Barotrauma.LuaCs.Data;
@@ -27,7 +28,7 @@ public interface IPackageManagementService : IService
2728
FluentResults.Result UnloadPackages();
2829
bool IsPackageLoaded(ContentPackage package);
2930
bool CheckDependencyLoaded(IPackageDependencyInfo info);
30-
bool CheckDependenciesLoaded(IEnumerable<IPackageDependencyInfo> infos, out IReadOnlyList<IPackageDependencyInfo> missingPackages);
31+
bool CheckDependenciesLoaded([NotNull]IEnumerable<IPackageDependencyInfo> infos, out ImmutableArray<IPackageDependencyInfo> missingPackages);
3132
bool CheckEnvironmentSupported(IPlatformInfo platform);
3233
}
3334

Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/PackageManagementService.cs

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.Collections.Immutable;
55
using System.Diagnostics;
6+
using System.Diagnostics.CodeAnalysis;
67
using System.Linq;
78
using System.Runtime.CompilerServices;
89
using System.Threading;
@@ -165,6 +166,8 @@ public FluentResults.Result ProcessQueuedPackages(bool rescanPackages = false, b
165166
/*
166167
* Helper functions
167168
*/
169+
170+
// register in the list so we can check against it.
168171
FluentResults.Result LoadPackageInfo(LoadablePackage package)
169172
{
170173
try
@@ -199,18 +202,42 @@ FluentResults.Result LoadPackageInfo(LoadablePackage package)
199202
}
200203

201204
/*
202-
* Return array: (Normal, MissingDeps)
205+
* Return array: (Normal, MissingDepsRes, MissingDeps)
203206
*/
204-
FluentResults.Result<(ImmutableArray<T>, ImmutableArray<T>)> GetLoadablePackages<T>(ImmutableArray<T> resources, bool errorForPacksMissingDeps = false)
207+
FluentResults.Result<(ImmutableArray<T>, ImmutableArray<T>, ImmutableArray<IPackageDependencyInfo>)> GetLoadablePackages<T>(ImmutableArray<T> resources, bool errorForPacksMissingDeps = false)
205208
where T : class, IPackageDependenciesInfo, IPackageInfo, IResourceInfo, IResourceCultureInfo
206209
{
207-
throw new NotImplementedException();
208210

209211
// filter optional resources (process later)
210212
// add back in optional packages that are required by other required packages
211213
// filter and log required packages that are missing dependencies
212214
// re-include optionals where dependencies are available
213215
// return both lists (A normal, B missingDeps).
216+
217+
HashSet<IPackageDependencyInfo> missingDeps = new();
218+
var missingDepsBuilder = ImmutableArray.CreateBuilder<T>();
219+
220+
var reqPacks = resources.Where(r => !r.Optional).Select(r => r.OwnerPackage).Distinct().ToImmutableHashSet();
221+
var optPack = resources.Where(r => r.Optional).Select(r => r.OwnerPackage).Distinct().ToImmutableHashSet();
222+
var req = resources
223+
.Where(r => !r.Optional)
224+
.Where(CheckEnvironmentSupported)
225+
.Where(r =>
226+
{
227+
if (r.Dependencies.Length == 0)
228+
return true;
229+
230+
if (CheckDependenciesLoaded(r.Dependencies, out var missingDepsList))
231+
return true;
232+
233+
missingDepsBuilder.Add(r);
234+
missingDeps.UnionWith(missingDepsList);
235+
return false;
236+
});
237+
var reqOptionals = resources.Where(r => r.Optional && optPack.Contains(r.OwnerPackage));
238+
var notReqOptionals = resources.Where(r => r.Optional && !optPack.Contains(r.OwnerPackage));
239+
240+
throw new NotImplementedException();
214241
}
215242

216243
FluentResults.Result<ImmutableArray<T>> SortByDependencies<T>(ImmutableArray<T> resources)
@@ -235,7 +262,11 @@ FluentResults.Result<ImmutableArray<T>> SortByDependencies<T>(ImmutableArray<T>
235262
public FluentResults.Result UnloadPackages()
236263
{
237264
if (!ModUtils.Environment.IsMainThread)
238-
throw new InvalidOperationException($"{nameof(UnloadPackages)}: This method can only be called on the main thread.");
265+
{
266+
return FluentResults.Result.Fail(
267+
new ExceptionalError(new InvalidOperationException($"{nameof(UnloadPackages)}: This method can only be called on the main thread."))
268+
.WithMetadata(MetadataType.ExceptionObject, this));
269+
}
239270

240271
var res = new FluentResults.Result();
241272
_contentPackagesModificationsLock.EnterWriteLock();
@@ -256,16 +287,15 @@ public FluentResults.Result UnloadPackages()
256287
public bool CheckDependencyLoaded(IPackageDependencyInfo info) =>
257288
info is not null && IsPackageLoaded(info.DependencyPackage);
258289

259-
public bool CheckDependenciesLoaded(IEnumerable<IPackageDependencyInfo> infos, out IReadOnlyList<IPackageDependencyInfo> missingPackages)
290+
public bool CheckDependenciesLoaded([NotNull]IEnumerable<IPackageDependencyInfo> infos, out ImmutableArray<IPackageDependencyInfo> missingPackages)
260291
{
261-
var missing = new List<IPackageDependencyInfo>();
262-
foreach (IPackageDependencyInfo info in infos)
263-
{
264-
if (!CheckDependencyLoaded(info))
265-
missing.Add(info);
266-
}
267-
missingPackages = missing;
268-
return missing.Count == 0;
292+
var missing = ImmutableArray.CreateBuilder<IPackageDependencyInfo>();
293+
missing.AddRange(infos
294+
.Where(i => i.DependencyPackage is not null)
295+
.DistinctBy(i => i.DependencyPackage)
296+
.Where(i => !CheckDependencyLoaded(i)));
297+
missingPackages = missing.MoveToImmutable();
298+
return missingPackages.Length == 0;
269299
}
270300

271301
public bool CheckEnvironmentSupported(IPlatformInfo platform)

Barotrauma/BarotraumaShared/SharedSource/LuaCs/Services/PackageService.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -644,11 +644,12 @@ private FluentResults.Result SanitationChecksEnumerable<T>(ImmutableArray<T> res
644644

645645
if (resourceInfo.Dependencies.IsDefaultOrEmpty)
646646
continue;
647-
648-
resourceInfo.Dependencies.ForEach(pdi =>
647+
648+
// ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator
649+
foreach (var pdi in resourceInfo.Dependencies)
649650
{
650-
// for clarification: assemblies passed to the function should always be loaded.
651-
// optional assemblies should be filtered out before the list is sent.
651+
// for clarification: all resources passed to the function should always be loaded.
652+
// unneeded optional resources should be filtered out before the list is sent.
652653
// left this as a reminder :)
653654
/*if (pdi.Optional)
654655
return;*/
@@ -659,7 +660,7 @@ private FluentResults.Result SanitationChecksEnumerable<T>(ImmutableArray<T> res
659660
.WithMetadata(MetadataType.ExceptionObject, this)
660661
.WithMetadata(MetadataType.RootObject, resourceInfo));
661662
}
662-
});
663+
}
663664

664665
// check runtime platform
665666
if (!_packageManagementService.CheckEnvironmentSupported(resourceInfo))

0 commit comments

Comments
 (0)