- Fixed resource data not returning into the correct context.

This commit is contained in:
Maplewheels
2026-01-25 14:50:29 -05:00
parent 8dc58445f9
commit d0f5cb87e7
2 changed files with 50 additions and 60 deletions
@@ -53,14 +53,14 @@ public sealed class ModConfigFileParserService :
// --- Assemblies // --- Assemblies
async Task<Result<IAssemblyResourceInfo>> IParserServiceAsync<ResourceParserInfo, IAssemblyResourceInfo>.TryParseResourceAsync(ResourceParserInfo src) async Task<Result<IAssemblyResourceInfo>> IParserServiceAsync<ResourceParserInfo, IAssemblyResourceInfo>.TryParseResourceAsync(ResourceParserInfo src)
{ {
using var lck = await _operationsLock.AcquireWriterLock(); using var lck = await _operationsLock.AcquireReaderLock();
IService.CheckDisposed(this); IService.CheckDisposed(this);
if (CheckThrowNullRefs(src, "Assembly") is { IsFailed: true } fail) if (CheckThrowNullRefs(src, "Assembly") is { IsFailed: true } fail)
return fail; return fail;
var runtimeEnv = GetRuntimeEnvironment(src.Element); var runtimeEnv = GetRuntimeEnvironment(src.Element);
var fileResults = await GetCheckedFiles(src.Element, src.Owner, ".dll"); var fileResults = await UnsafeGetCheckedFiles(src.Element, src.Owner, ".dll");
if (fileResults.IsFailed) if (fileResults.IsFailed)
return FluentResults.Result.Fail(fileResults.Errors); return FluentResults.Result.Fail(fileResults.Errors);
@@ -91,15 +91,14 @@ public sealed class ModConfigFileParserService :
async Task<Result<IConfigResourceInfo>> IParserServiceAsync<ResourceParserInfo, IConfigResourceInfo>.TryParseResourceAsync(ResourceParserInfo src) async Task<Result<IConfigResourceInfo>> IParserServiceAsync<ResourceParserInfo, IConfigResourceInfo>.TryParseResourceAsync(ResourceParserInfo src)
{ {
using var lck = await _operationsLock.AcquireReaderLock();
using var lck = await _operationsLock.AcquireWriterLock();
IService.CheckDisposed(this); IService.CheckDisposed(this);
if (CheckThrowNullRefs(src, "Config") is { IsFailed: true } fail) if (CheckThrowNullRefs(src, "Config") is { IsFailed: true } fail)
return fail; return fail;
var runtimeEnv = GetRuntimeEnvironment(src.Element); var runtimeEnv = GetRuntimeEnvironment(src.Element);
var fileResults = await GetCheckedFiles(src.Element, src.Owner, ".xml"); var fileResults = await UnsafeGetCheckedFiles(src.Element, src.Owner, ".xml");
if (fileResults.IsFailed) if (fileResults.IsFailed)
return FluentResults.Result.Fail(fileResults.Errors); return FluentResults.Result.Fail(fileResults.Errors);
@@ -126,14 +125,14 @@ public sealed class ModConfigFileParserService :
// --- Lua Scripts // --- Lua Scripts
async Task<Result<ILuaScriptResourceInfo>> IParserServiceAsync<ResourceParserInfo, ILuaScriptResourceInfo>.TryParseResourceAsync(ResourceParserInfo src) async Task<Result<ILuaScriptResourceInfo>> IParserServiceAsync<ResourceParserInfo, ILuaScriptResourceInfo>.TryParseResourceAsync(ResourceParserInfo src)
{ {
using var lck = await _operationsLock.AcquireWriterLock(); using var lck = await _operationsLock.AcquireReaderLock();
IService.CheckDisposed(this); IService.CheckDisposed(this);
if (CheckThrowNullRefs(src, "Lua") is { IsFailed: true } fail) if (CheckThrowNullRefs(src, "Lua") is { IsFailed: true } fail)
return fail; return fail;
var runtimeEnv = GetRuntimeEnvironment(src.Element); var runtimeEnv = GetRuntimeEnvironment(src.Element);
var fileResults = await GetCheckedFiles(src.Element, src.Owner, ".lua"); var fileResults = await UnsafeGetCheckedFiles(src.Element, src.Owner, ".lua");
if (fileResults.IsFailed) if (fileResults.IsFailed)
return FluentResults.Result.Fail(fileResults.Errors); return FluentResults.Result.Fail(fileResults.Errors);
@@ -174,34 +173,39 @@ public sealed class ModConfigFileParserService :
} }
// --- Helpers // --- Helpers
private async Task<Result<ImmutableArray<ContentPath>>> GetCheckedFiles(XElement srcElement, ContentPackage srcOwner, string fileExtension) private async Task<Result<ImmutableArray<ContentPath>>> UnsafeGetCheckedFiles(XElement srcElement, ContentPackage srcOwner, string fileExtension)
{ {
using var lck = await _operationsLock.AcquireWriterLock();
IService.CheckDisposed(this);
var builder = ImmutableArray.CreateBuilder<ContentPath>(); var builder = ImmutableArray.CreateBuilder<ContentPath>();
var filePath = srcElement.GetAttributeString("File", string.Empty); var filePath = srcElement.GetAttributeContentPath("File", srcOwner);
var folderPath = srcElement.GetAttributeString("Folder", string.Empty); var folderPath = srcElement.GetAttributeContentPath("Folder", srcOwner);
var res = new FluentResults.Result<ImmutableArray<ContentPath>>();
if (!filePath.IsNullOrWhiteSpace()) if (!filePath.IsNullOrWhiteSpace())
{ {
var cp = ContentPath.FromRaw(srcOwner, filePath); if (_storageService.FileExists(filePath.FullPath) is { IsSuccess: true, Value: true })
if (_storageService.FileExists(cp.FullPath) is { IsSuccess: true, Value: true })
{ {
builder.Add(cp); builder.Add(filePath);
}
else
{
res.WithError($"{srcOwner.Name}: The file '{filePath}' is missing!");
} }
} }
if (!folderPath.IsNullOrWhiteSpace()) if (!folderPath.IsNullOrWhiteSpace())
{ {
var cp = ContentPath.FromRaw(srcOwner, folderPath); if (_storageService.DirectoryExists(folderPath.FullPath) is { IsSuccess: true, Value: true })
if (_storageService.DirectoryExists(cp.FullPath) is { IsSuccess: true, Value: true })
{ {
var files = _storageService.FindFilesInPackage(cp.ContentPackage, cp.Value, fileExtension, true); var files = _storageService.FindFilesInPackage(srcOwner, folderPath.Value, fileExtension, true);
}
else
{
res.WithError($"{srcOwner.Name}: The folder '{filePath}' is missing!");
} }
} }
throw new NotImplementedException(); return res.WithValue(builder.ToImmutable());
} }
private (Platform Platform, Target Target) GetRuntimeEnvironment(XElement element) private (Platform Platform, Target Target) GetRuntimeEnvironment(XElement element)
{ {
@@ -96,15 +96,25 @@ public sealed class ModConfigService : IModConfigService
using var lck = await _operationsLock.AcquireReaderLock(); using var lck = await _operationsLock.AcquireReaderLock();
IService.CheckDisposed(this); IService.CheckDisposed(this);
var builder = new ConcurrentQueue<(ContentPackage Source, Result<IModConfigInfo> Config)>(); var builder = ImmutableArray.CreateBuilder<Task<Task<Result<IModConfigInfo>>>>(src.Length);
foreach (var srcItem in src)
await src.ParallelForEachAsync(async package =>
{ {
var res = await CreateConfigAsync(package); builder.Add(Task.Factory.StartNew(async Task<Result<IModConfigInfo>> () => await CreateConfigAsync(srcItem)));
builder.Enqueue((package, res)); }
}); var taskResults = await Task.WhenAll(builder.ToImmutable());
var returnResults = ImmutableArray.CreateBuilder<(ContentPackage Source, Result<IModConfigInfo> Config)>();
foreach (var taskResult in taskResults)
{
if (taskResult.IsFaulted)
{
ThrowHelper.ThrowInvalidOperationException($"{nameof(CreateConfigsAsync)}: Task failed: {taskResult.Exception?.Message}");
}
return builder.OrderBy(pkg => src.IndexOf(pkg.Source)).ToImmutableArray(); var r = await taskResult;
returnResults.Add((r.Value.Package, r));
}
return returnResults.ToImmutable();
} }
//--- Helpers //--- Helpers
@@ -117,42 +127,18 @@ public sealed class ModConfigService : IModConfigService
private async Task<Result<IModConfigInfo>> CreateFromConfigXmlAsync(ContentPackage owner, XElement src) private async Task<Result<IModConfigInfo>> CreateFromConfigXmlAsync(ContentPackage owner, XElement src)
{ {
ImmutableArray<IAssemblyResourceInfo> assemblyResources = default; var asmTask = Task.Factory.StartNew(async () => await GetAssembliesFromXml(owner, src));
ImmutableArray<IConfigResourceInfo> configResources = default; var cfgTask = Task.Factory.StartNew(async () => await GetConfigsFromXml(owner, src));
ImmutableArray<ILuaScriptResourceInfo> luaResources = default; var luaTask = Task.Factory.StartNew(async () => await GetLuaScriptsFromXml(owner, src));
var tasks = new[] await Task.WhenAll(asmTask, cfgTask, luaTask);
{
new Task<Task>(async () => assemblyResources = await GetAssembliesFromXml(owner, src)),
new Task<Task>(async () => configResources = await GetConfigsFromXml(owner, src)),
new Task<Task>(async () => luaResources = await GetLuaScriptsFromXml(owner, src)),
};
tasks.ForEach(t => t.Start());
var res = await Task.WhenAll(tasks);
bool isFaulted = false;
foreach (var task in res)
{
if (task.IsFaulted)
{
_logger.LogError($"{nameof(CreateFromConfigXmlAsync)}: {task.Exception?.ToString()}");
isFaulted = true;
}
}
if (isFaulted)
{
_logger.LogError($"{nameof(CreateFromConfigXmlAsync)}: Failed to process content package: {owner.Name}");
return FluentResults.Result.Fail($"{nameof(CreateFromConfigXmlAsync)}: Failed to process content package: {owner.Name}");
}
return FluentResults.Result.Ok<IModConfigInfo>(new ModConfigInfo() return FluentResults.Result.Ok<IModConfigInfo>(new ModConfigInfo()
{ {
Package = owner, Package = owner,
Assemblies = assemblyResources, Assemblies = await await asmTask,
Configs = configResources, Configs = await await cfgTask,
LuaScripts = luaResources LuaScripts = await await luaTask
}); });
async Task<ImmutableArray<ILuaScriptResourceInfo>> GetLuaScriptsFromXml(ContentPackage contentPackage, async Task<ImmutableArray<ILuaScriptResourceInfo>> GetLuaScriptsFromXml(ContentPackage contentPackage,