mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Fixup ProgramIndexMapInfoManager
This commit is contained in:
parent
9803634284
commit
814ae34642
4 changed files with 157 additions and 125 deletions
147
src/LibHac/FsSrv/Impl/ProgramIndexMapInfoManager.cs
Normal file
147
src/LibHac/FsSrv/Impl/ProgramIndexMapInfoManager.cs
Normal file
|
@ -0,0 +1,147 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Os;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSrv.Impl;
|
||||
|
||||
/// <summary>
|
||||
/// Keeps track of the program IDs and program indexes of each program in a multi-program application.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class ProgramIndexMapInfoManager : IDisposable
|
||||
{
|
||||
private LinkedList<ProgramIndexMapInfo> _mapEntries;
|
||||
private SdkMutexType _mutex;
|
||||
|
||||
public ProgramIndexMapInfoManager()
|
||||
{
|
||||
_mapEntries = new LinkedList<ProgramIndexMapInfo>();
|
||||
_mutex = new SdkMutexType();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters any previously registered program index map info and registers the provided map info.
|
||||
/// </summary>
|
||||
/// <param name="programIndexMapInfo">The program map info entries to register.</param>
|
||||
/// <returns><see cref="Result.Success"/>: The operation was successful.</returns>
|
||||
public Result Reset(ReadOnlySpan<ProgramIndexMapInfo> programIndexMapInfo)
|
||||
{
|
||||
using ScopedLock<SdkMutexType> scopedLock = ScopedLock.Lock(ref _mutex);
|
||||
|
||||
ClearImpl();
|
||||
|
||||
for (int i = 0; i < programIndexMapInfo.Length; i++)
|
||||
{
|
||||
var entry = new ProgramIndexMapInfo
|
||||
{
|
||||
ProgramId = programIndexMapInfo[i].ProgramId,
|
||||
MainProgramId = programIndexMapInfo[i].MainProgramId,
|
||||
ProgramIndex = programIndexMapInfo[i].ProgramIndex
|
||||
};
|
||||
|
||||
_mapEntries.AddLast(entry);
|
||||
}
|
||||
|
||||
// We skip running ClearImpl() if the allocation failed because we don't need to worry about that in C#
|
||||
|
||||
return Result.Success;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters all currently registered program index map info.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
using ScopedLock<SdkMutexType> scopedLock = ScopedLock.Lock(ref _mutex);
|
||||
|
||||
ClearImpl();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ProgramIndexMapInfo"/> associated with the specified program ID.
|
||||
/// </summary>
|
||||
/// <param name="programId">The program ID of the map info to get.</param>
|
||||
/// <returns>If the program ID was found, the <see cref="ProgramIndexMapInfo"/> associated
|
||||
/// with that ID; otherwise, <see langword="null"/>.</returns>
|
||||
public Optional<ProgramIndexMapInfo> Get(ProgramId programId)
|
||||
{
|
||||
using ScopedLock<SdkMutexType> scopedLock = ScopedLock.Lock(ref _mutex);
|
||||
|
||||
return GetImpl((in ProgramIndexMapInfo x) => x.ProgramId == programId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ProgramId"/> of the program with index <paramref name="programIndex"/> in the
|
||||
/// multi-program app <paramref name="programId"/> is part of.
|
||||
/// </summary>
|
||||
/// <param name="programId">A program ID in the multi-program app to query.</param>
|
||||
/// <param name="programIndex">The index of the program to get.</param>
|
||||
/// <returns>If the program exists, the ID of the program with the specified index,
|
||||
/// otherwise <see cref="ProgramId.InvalidId"/></returns>
|
||||
public ProgramId GetProgramId(ProgramId programId, byte programIndex)
|
||||
{
|
||||
using ScopedLock<SdkMutexType> scopedLock = ScopedLock.Lock(ref _mutex);
|
||||
|
||||
Optional<ProgramIndexMapInfo> programIndexMapInfo =
|
||||
GetImpl((in ProgramIndexMapInfo x) => x.ProgramId == programId);
|
||||
|
||||
if (!programIndexMapInfo.HasValue)
|
||||
return ProgramId.InvalidId;
|
||||
|
||||
Optional<ProgramIndexMapInfo> targetProgramIndexMapInfo = GetImpl((in ProgramIndexMapInfo x) =>
|
||||
x.MainProgramId == programIndexMapInfo.Value.MainProgramId && x.ProgramIndex == programIndex);
|
||||
|
||||
if (!targetProgramIndexMapInfo.HasValue)
|
||||
return ProgramId.InvalidId;
|
||||
|
||||
return targetProgramIndexMapInfo.Value.ProgramId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of currently registered programs,
|
||||
/// </summary>
|
||||
/// <returns>The number of registered programs.</returns>
|
||||
public int GetProgramCount()
|
||||
{
|
||||
using ScopedLock<SdkMutexType> scopedLock = ScopedLock.Lock(ref _mutex);
|
||||
|
||||
return _mapEntries.Count;
|
||||
}
|
||||
|
||||
private delegate bool EntrySelector(in ProgramIndexMapInfo candidate);
|
||||
|
||||
private Optional<ProgramIndexMapInfo> GetImpl(EntrySelector selector)
|
||||
{
|
||||
var returnValue = new Optional<ProgramIndexMapInfo>();
|
||||
|
||||
foreach (ProgramIndexMapInfo entry in _mapEntries)
|
||||
{
|
||||
if (selector(in entry))
|
||||
{
|
||||
returnValue.Set(default);
|
||||
|
||||
returnValue.Value.ProgramId = entry.ProgramId;
|
||||
returnValue.Value.MainProgramId = entry.MainProgramId;
|
||||
returnValue.Value.ProgramIndex = entry.ProgramIndex;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private void ClearImpl()
|
||||
{
|
||||
_mapEntries.Clear();
|
||||
}
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Util;
|
||||
|
||||
namespace LibHac.FsSrv;
|
||||
|
||||
/// <summary>
|
||||
/// Keeps track of the program IDs and program indexes of each program in a multi-program application.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 10.0.0 (nnSdk 10.4.0)</remarks>
|
||||
public class ProgramIndexMapInfoManager
|
||||
{
|
||||
private LinkedList<ProgramIndexMapInfo> MapEntries { get; } = new LinkedList<ProgramIndexMapInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters any previously registered program index map info and registers the provided map info.
|
||||
/// </summary>
|
||||
/// <param name="programIndexMapInfo">The program map info entries to register.</param>
|
||||
/// <returns><see cref="Result.Success"/>: The operation was successful.</returns>
|
||||
public Result Reset(ReadOnlySpan<ProgramIndexMapInfo> programIndexMapInfo)
|
||||
{
|
||||
lock (MapEntries)
|
||||
{
|
||||
ClearImpl();
|
||||
|
||||
for (int i = 0; i < programIndexMapInfo.Length; i++)
|
||||
{
|
||||
MapEntries.AddLast(programIndexMapInfo[i]);
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters all currently registered program index map info.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
lock (MapEntries)
|
||||
{
|
||||
ClearImpl();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ProgramIndexMapInfo"/> associated with the specified program ID.
|
||||
/// </summary>
|
||||
/// <param name="programId">The program ID of the map info to get.</param>
|
||||
/// <returns>If the program ID was found, the <see cref="ProgramIndexMapInfo"/> associated
|
||||
/// with that ID; otherwise, <see langword="null"/>.</returns>
|
||||
public Optional<ProgramIndexMapInfo> Get(ProgramId programId)
|
||||
{
|
||||
lock (MapEntries)
|
||||
{
|
||||
return GetImpl((in ProgramIndexMapInfo x) => x.ProgramId == programId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ProgramId"/> of the program with index <paramref name="programIndex"/> in the
|
||||
/// multi-program app <paramref name="programId"/> is part of.
|
||||
/// </summary>
|
||||
/// <param name="programId">A program ID in the multi-program app to query.</param>
|
||||
/// <param name="programIndex">The index of the program to get.</param>
|
||||
/// <returns>If the program exists, the ID of the program with the specified index,
|
||||
/// otherwise <see cref="ProgramId.InvalidId"/></returns>
|
||||
public ProgramId GetProgramId(ProgramId programId, byte programIndex)
|
||||
{
|
||||
lock (MapEntries)
|
||||
{
|
||||
Optional<ProgramIndexMapInfo> mainProgramMapInfo =
|
||||
GetImpl((in ProgramIndexMapInfo x) => x.ProgramId == programId);
|
||||
|
||||
if (!mainProgramMapInfo.HasValue)
|
||||
return ProgramId.InvalidId;
|
||||
|
||||
Optional<ProgramIndexMapInfo> requestedMapInfo = GetImpl((in ProgramIndexMapInfo x) =>
|
||||
x.MainProgramId == mainProgramMapInfo.Value.MainProgramId && x.ProgramIndex == programIndex);
|
||||
|
||||
if (!requestedMapInfo.HasValue)
|
||||
return ProgramId.InvalidId;
|
||||
|
||||
return requestedMapInfo.Value.ProgramId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of currently registered programs,
|
||||
/// </summary>
|
||||
/// <returns>The number of registered programs.</returns>
|
||||
public int GetProgramCount()
|
||||
{
|
||||
lock (MapEntries)
|
||||
{
|
||||
return MapEntries.Count;
|
||||
}
|
||||
}
|
||||
|
||||
private delegate bool EntrySelector(in ProgramIndexMapInfo candidate);
|
||||
|
||||
private Optional<ProgramIndexMapInfo> GetImpl(EntrySelector selector)
|
||||
{
|
||||
foreach (ProgramIndexMapInfo entry in MapEntries)
|
||||
{
|
||||
if (selector(in entry))
|
||||
{
|
||||
return new Optional<ProgramIndexMapInfo>(entry);
|
||||
}
|
||||
}
|
||||
|
||||
return new Optional<ProgramIndexMapInfo>();
|
||||
}
|
||||
|
||||
private void ClearImpl()
|
||||
{
|
||||
MapEntries.Clear();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Diag;
|
||||
|
||||
|
@ -36,6 +37,12 @@ public struct Optional<T>
|
|||
|
||||
public static implicit operator Optional<T>(in T value) => new Optional<T>(in value);
|
||||
|
||||
public void Set(T value)
|
||||
{
|
||||
_value = value;
|
||||
_hasValue = true;
|
||||
}
|
||||
|
||||
public void Set(in T value)
|
||||
{
|
||||
_value = value;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Shim;
|
||||
using LibHac.FsSrv;
|
||||
using LibHac.FsSrv.Impl;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Util;
|
||||
|
|
Loading…
Reference in a new issue