mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Ensure more FS classes are updated for 13.1.0
- FsSrv.Impl.IResultConvertDirectory - FsSrv.Impl.IResultConvertFile - FsSrv.Impl.IResultConvertFileSystem - FsSrv.Impl.SaveDataExtraDataAccessorCacheManager - FsSrv.Impl.SaveDataExtraDataResultConvertAccessor - FsSrv.Impl.SaveDataResultConvert - FsSrv.Impl.SaveDataResultConvertDirectory - FsSrv.Impl.SaveDataResultConvertFile - FsSrv.Impl.SaveDataResultConvertFileSystem - FsSrv.Impl.StorageInterfaceAdapter - FsSystem.ISaveDataCommitTimeStampGetter - FsSystem.ISaveDataExtraDataAccessor - FsSystem.ISaveDataFileSystemCacheManager - FsSystem.SaveDataFileSystemCacheManager - FsSystem.SaveDataFileSystemCacheRegisterBase
This commit is contained in:
parent
32ffda1d3f
commit
e969554639
11 changed files with 132 additions and 71 deletions
|
@ -6,6 +6,11 @@ using LibHac.Fs.Fsa;
|
|||
namespace LibHac.FsSrv.Impl;
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
/// <summary>
|
||||
/// Wraps an <see cref="IFile"/>, converting its returned <see cref="Result"/>s to different
|
||||
/// <see cref="Result"/>s based on the <see cref="ConvertResult"/> function.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public abstract class IResultConvertFile : IFile
|
||||
{
|
||||
protected UniqueRef<IFile> BaseFile;
|
||||
|
@ -56,6 +61,11 @@ public abstract class IResultConvertFile : IFile
|
|||
}
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
/// <summary>
|
||||
/// Wraps an <see cref="IDirectory"/>, converting its returned <see cref="Result"/>s to different
|
||||
/// <see cref="Result"/>s based on the <see cref="ConvertResult"/> function.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public abstract class IResultConvertDirectory : IDirectory
|
||||
{
|
||||
protected UniqueRef<IDirectory> BaseDirectory;
|
||||
|
@ -85,6 +95,11 @@ public abstract class IResultConvertDirectory : IDirectory
|
|||
}
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
/// <summary>
|
||||
/// Wraps an <see cref="IFileSystem"/>, converting its returned <see cref="Result"/>s to different
|
||||
/// <see cref="Result"/>s based on the <see cref="ConvertResult"/> function.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public abstract class IResultConvertFileSystem : IFileSystem
|
||||
{
|
||||
protected SharedRef<IFileSystem> BaseFileSystem;
|
||||
|
@ -145,6 +160,8 @@ public abstract class IResultConvertFileSystem : IFileSystem
|
|||
return ConvertResult(BaseFileSystem.Get.GetEntryType(out entryType, path));
|
||||
}
|
||||
|
||||
// Note: The original code uses templates to determine which type of IFile/IDirectory to return. To make things
|
||||
// easier in C# these two functions have been made abstract functions.
|
||||
protected abstract override Result DoOpenFile(ref UniqueRef<IFile> outFile, in Path path, OpenMode mode);
|
||||
|
||||
protected abstract override Result DoOpenDirectory(ref UniqueRef<IDirectory> outDirectory, in Path path,
|
||||
|
@ -192,4 +209,4 @@ public abstract class IResultConvertFileSystem : IFileSystem
|
|||
}
|
||||
|
||||
protected abstract Result ConvertResult(Result result);
|
||||
}
|
||||
}
|
|
@ -10,8 +10,13 @@ namespace LibHac.FsSrv.Impl;
|
|||
/// <summary>
|
||||
/// Holds the <see cref="ISaveDataExtraDataAccessor"/>s for opened save data file systems.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class SaveDataExtraDataAccessorCacheManager : ISaveDataExtraDataAccessorCacheObserver
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds a single cached extra data accessor identified by its save data ID and save data space ID.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
[NonCopyable]
|
||||
private struct Cache : IDisposable
|
||||
{
|
||||
|
@ -19,8 +24,7 @@ public class SaveDataExtraDataAccessorCacheManager : ISaveDataExtraDataAccessorC
|
|||
private readonly SaveDataSpaceId _spaceId;
|
||||
private readonly ulong _saveDataId;
|
||||
|
||||
public Cache(in SharedRef<ISaveDataExtraDataAccessor> accessor, SaveDataSpaceId spaceId,
|
||||
ulong saveDataId)
|
||||
public Cache(in SharedRef<ISaveDataExtraDataAccessor> accessor, SaveDataSpaceId spaceId, ulong saveDataId)
|
||||
{
|
||||
_accessor = new WeakRef<ISaveDataExtraDataAccessor>(in accessor);
|
||||
_spaceId = spaceId;
|
||||
|
@ -49,7 +53,7 @@ public class SaveDataExtraDataAccessorCacheManager : ISaveDataExtraDataAccessorC
|
|||
public SaveDataExtraDataAccessorCacheManager()
|
||||
{
|
||||
_accessorList = new LinkedList<Cache>();
|
||||
_mutex.Initialize();
|
||||
_mutex = new SdkRecursiveMutexType();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -138,4 +142,4 @@ public class SaveDataExtraDataAccessorCacheManager : ISaveDataExtraDataAccessorC
|
|||
{
|
||||
return new UniqueLockRef<SdkRecursiveMutexType>(ref _mutex);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,10 @@ using LibHac.FsSystem;
|
|||
|
||||
namespace LibHac.FsSrv.Impl;
|
||||
|
||||
/// <summary>
|
||||
/// Contains functions for converting internal save data <see cref="Result"/>s to external <see cref="Result"/>s.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public static class SaveDataResultConvert
|
||||
{
|
||||
private static Result ConvertCorruptedResult(Result result)
|
||||
|
@ -13,19 +17,19 @@ public static class SaveDataResultConvert
|
|||
if (ResultFs.IntegrityVerificationStorageCorrupted.Includes(result))
|
||||
{
|
||||
if (ResultFs.IncorrectIntegrityVerificationMagicCode.Includes(result))
|
||||
return ResultFs.IncorrectSaveDataIntegrityVerificationMagicCode.Value;
|
||||
return ResultFs.IncorrectSaveDataIntegrityVerificationMagicCode.LogConverted(result);
|
||||
|
||||
if (ResultFs.InvalidZeroHash.Includes(result))
|
||||
return ResultFs.InvalidSaveDataZeroHash.Value;
|
||||
return ResultFs.InvalidSaveDataZeroHash.LogConverted(result);
|
||||
|
||||
if (ResultFs.NonRealDataVerificationFailed.Includes(result))
|
||||
return ResultFs.SaveDataNonRealDataVerificationFailed.Value;
|
||||
return ResultFs.SaveDataNonRealDataVerificationFailed.LogConverted(result);
|
||||
|
||||
if (ResultFs.ClearedRealDataVerificationFailed.Includes(result))
|
||||
return ResultFs.ClearedSaveDataRealDataVerificationFailed.Value;
|
||||
return ResultFs.ClearedSaveDataRealDataVerificationFailed.LogConverted(result);
|
||||
|
||||
if (ResultFs.UnclearedRealDataVerificationFailed.Includes(result))
|
||||
return ResultFs.UnclearedSaveDataRealDataVerificationFailed.Value;
|
||||
return ResultFs.UnclearedSaveDataRealDataVerificationFailed.LogConverted(result);
|
||||
|
||||
Assert.SdkAssert(false);
|
||||
}
|
||||
|
@ -33,16 +37,16 @@ public static class SaveDataResultConvert
|
|||
if (ResultFs.HostFileSystemCorrupted.Includes(result))
|
||||
{
|
||||
if (ResultFs.HostEntryCorrupted.Includes(result))
|
||||
return ResultFs.SaveDataHostEntryCorrupted.Value;
|
||||
return ResultFs.SaveDataHostEntryCorrupted.LogConverted(result);
|
||||
|
||||
if (ResultFs.HostFileDataCorrupted.Includes(result))
|
||||
return ResultFs.SaveDataHostFileDataCorrupted.Value;
|
||||
return ResultFs.SaveDataHostFileDataCorrupted.LogConverted(result);
|
||||
|
||||
if (ResultFs.HostFileCorrupted.Includes(result))
|
||||
return ResultFs.SaveDataHostFileCorrupted.Value;
|
||||
return ResultFs.SaveDataHostFileCorrupted.LogConverted(result);
|
||||
|
||||
if (ResultFs.InvalidHostHandle.Includes(result))
|
||||
return ResultFs.InvalidSaveDataHostHandle.Value;
|
||||
return ResultFs.InvalidSaveDataHostHandle.LogConverted(result);
|
||||
|
||||
Assert.SdkAssert(false);
|
||||
}
|
||||
|
@ -50,25 +54,25 @@ public static class SaveDataResultConvert
|
|||
if (ResultFs.DatabaseCorrupted.Includes(result))
|
||||
{
|
||||
if (ResultFs.InvalidAllocationTableBlock.Includes(result))
|
||||
return ResultFs.InvalidSaveDataAllocationTableBlock.Value;
|
||||
return ResultFs.InvalidSaveDataAllocationTableBlock.LogConverted(result);
|
||||
|
||||
if (ResultFs.InvalidKeyValueListElementIndex.Includes(result))
|
||||
return ResultFs.InvalidSaveDataKeyValueListElementIndex.Value;
|
||||
return ResultFs.InvalidSaveDataKeyValueListElementIndex.LogConverted(result);
|
||||
|
||||
if (ResultFs.InvalidAllocationTableChainEntry.Includes(result))
|
||||
return ResultFs.InvalidSaveDataAllocationTableChainEntry.Value;
|
||||
return ResultFs.InvalidSaveDataAllocationTableChainEntry.LogConverted(result);
|
||||
|
||||
if (ResultFs.InvalidAllocationTableOffset.Includes(result))
|
||||
return ResultFs.InvalidSaveDataAllocationTableOffset.Value;
|
||||
return ResultFs.InvalidSaveDataAllocationTableOffset.LogConverted(result);
|
||||
|
||||
if (ResultFs.InvalidAllocationTableBlockCount.Includes(result))
|
||||
return ResultFs.InvalidSaveDataAllocationTableBlockCount.Value;
|
||||
return ResultFs.InvalidSaveDataAllocationTableBlockCount.LogConverted(result);
|
||||
|
||||
if (ResultFs.InvalidKeyValueListEntryIndex.Includes(result))
|
||||
return ResultFs.InvalidSaveDataKeyValueListEntryIndex.Value;
|
||||
return ResultFs.InvalidSaveDataKeyValueListEntryIndex.LogConverted(result);
|
||||
|
||||
if (ResultFs.InvalidBitmapIndex.Includes(result))
|
||||
return ResultFs.InvalidSaveDataBitmapIndex.Value;
|
||||
return ResultFs.InvalidSaveDataBitmapIndex.LogConverted(result);
|
||||
|
||||
Assert.SdkAssert(false);
|
||||
}
|
||||
|
@ -76,7 +80,7 @@ public static class SaveDataResultConvert
|
|||
if (ResultFs.ZeroBitmapFileCorrupted.Includes(result))
|
||||
{
|
||||
if (ResultFs.IncompleteBlockInZeroBitmapHashStorageFile.Includes(result))
|
||||
return ResultFs.IncompleteBlockInZeroBitmapHashStorageFileSaveData.Value;
|
||||
return ResultFs.IncompleteBlockInZeroBitmapHashStorageFileSaveData.LogConverted(result);
|
||||
|
||||
Assert.SdkAssert(false);
|
||||
}
|
||||
|
@ -84,13 +88,13 @@ public static class SaveDataResultConvert
|
|||
return result;
|
||||
}
|
||||
|
||||
public static Result ConvertSaveFsDriverPublicResult(Result result)
|
||||
public static Result ConvertSaveFsDriverPrivateResult(Result result)
|
||||
{
|
||||
if (result.IsSuccess())
|
||||
return result;
|
||||
|
||||
if (ResultFs.UnsupportedVersion.Includes(result))
|
||||
return ResultFs.UnsupportedSaveDataVersion.Value;
|
||||
return ResultFs.UnsupportedSaveDataVersion.LogConverted(result);
|
||||
|
||||
if (ResultFs.IntegrityVerificationStorageCorrupted.Includes(result) ||
|
||||
ResultFs.BuiltInStorageCorrupted.Includes(result) ||
|
||||
|
@ -105,21 +109,21 @@ public static class SaveDataResultConvert
|
|||
return result;
|
||||
|
||||
if (ResultFs.NotFound.Includes(result))
|
||||
return ResultFs.PathNotFound.Value;
|
||||
return ResultFs.PathNotFound.LogConverted(result);
|
||||
|
||||
if (ResultFs.AllocationTableFull.Includes(result))
|
||||
return ResultFs.UsableSpaceNotEnough.Value;
|
||||
return ResultFs.UsableSpaceNotEnough.LogConverted(result);
|
||||
|
||||
if (ResultFs.AlreadyExists.Includes(result))
|
||||
return ResultFs.PathAlreadyExists.Value;
|
||||
return ResultFs.PathAlreadyExists.LogConverted(result);
|
||||
|
||||
if (ResultFs.InvalidOffset.Includes(result))
|
||||
return ResultFs.OutOfRange.Value;
|
||||
return ResultFs.OutOfRange.LogConverted(result);
|
||||
|
||||
if (ResultFs.IncompatiblePath.Includes(result) ||
|
||||
ResultFs.FileNotFound.Includes(result))
|
||||
{
|
||||
return ResultFs.PathNotFound.Value;
|
||||
return ResultFs.PathNotFound.LogConverted(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -130,6 +134,7 @@ public static class SaveDataResultConvert
|
|||
/// Wraps an <see cref="IFile"/>, converting its returned <see cref="Result"/>s
|
||||
/// to save-data-specific <see cref="Result"/>s.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class SaveDataResultConvertFile : IResultConvertFile
|
||||
{
|
||||
public SaveDataResultConvertFile(ref UniqueRef<IFile> baseFile) : base(ref baseFile)
|
||||
|
@ -138,7 +143,7 @@ public class SaveDataResultConvertFile : IResultConvertFile
|
|||
|
||||
protected override Result ConvertResult(Result result)
|
||||
{
|
||||
return SaveDataResultConvert.ConvertSaveFsDriverPublicResult(result);
|
||||
return SaveDataResultConvert.ConvertSaveFsDriverPrivateResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,6 +151,7 @@ public class SaveDataResultConvertFile : IResultConvertFile
|
|||
/// Wraps an <see cref="IDirectory"/>, converting its returned <see cref="Result"/>s
|
||||
/// to save-data-specific <see cref="Result"/>s.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class SaveDataResultConvertDirectory : IResultConvertDirectory
|
||||
{
|
||||
public SaveDataResultConvertDirectory(ref UniqueRef<IDirectory> baseDirectory) : base(ref baseDirectory)
|
||||
|
@ -154,7 +160,7 @@ public class SaveDataResultConvertDirectory : IResultConvertDirectory
|
|||
|
||||
protected override Result ConvertResult(Result result)
|
||||
{
|
||||
return SaveDataResultConvert.ConvertSaveFsDriverPublicResult(result);
|
||||
return SaveDataResultConvert.ConvertSaveFsDriverPrivateResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,6 +168,7 @@ public class SaveDataResultConvertDirectory : IResultConvertDirectory
|
|||
/// Wraps an <see cref="IFileSystem"/>, converting its returned <see cref="Result"/>s
|
||||
/// to save-data-specific <see cref="Result"/>s.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class SaveDataResultConvertFileSystem : IResultConvertFileSystem
|
||||
{
|
||||
public SaveDataResultConvertFileSystem(ref SharedRef<IFileSystem> baseFileSystem)
|
||||
|
@ -192,7 +199,7 @@ public class SaveDataResultConvertFileSystem : IResultConvertFileSystem
|
|||
|
||||
protected override Result ConvertResult(Result result)
|
||||
{
|
||||
return SaveDataResultConvert.ConvertSaveFsDriverPublicResult(result);
|
||||
return SaveDataResultConvert.ConvertSaveFsDriverPrivateResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,6 +207,7 @@ public class SaveDataResultConvertFileSystem : IResultConvertFileSystem
|
|||
/// Wraps an <see cref="ISaveDataExtraDataAccessor"/>, converting its returned <see cref="Result"/>s
|
||||
/// to save-data-specific <see cref="Result"/>s.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class SaveDataExtraDataResultConvertAccessor : ISaveDataExtraDataAccessor
|
||||
{
|
||||
private SharedRef<ISaveDataExtraDataAccessor> _accessor;
|
||||
|
@ -217,19 +225,19 @@ public class SaveDataExtraDataResultConvertAccessor : ISaveDataExtraDataAccessor
|
|||
public Result WriteExtraData(in SaveDataExtraData extraData)
|
||||
{
|
||||
Result rc = _accessor.Get.WriteExtraData(in extraData);
|
||||
return SaveDataResultConvert.ConvertSaveFsDriverPublicResult(rc);
|
||||
return SaveDataResultConvert.ConvertSaveFsDriverPrivateResult(rc);
|
||||
}
|
||||
|
||||
public Result CommitExtraData(bool updateTimeStamp)
|
||||
{
|
||||
Result rc = _accessor.Get.CommitExtraData(updateTimeStamp);
|
||||
return SaveDataResultConvert.ConvertSaveFsDriverPublicResult(rc);
|
||||
return SaveDataResultConvert.ConvertSaveFsDriverPrivateResult(rc);
|
||||
}
|
||||
|
||||
public Result ReadExtraData(out SaveDataExtraData extraData)
|
||||
{
|
||||
Result rc = _accessor.Get.ReadExtraData(out extraData);
|
||||
return SaveDataResultConvert.ConvertSaveFsDriverPublicResult(rc);
|
||||
return SaveDataResultConvert.ConvertSaveFsDriverPrivateResult(rc);
|
||||
}
|
||||
|
||||
public void RegisterCacheObserver(ISaveDataExtraDataAccessorCacheObserver observer, SaveDataSpaceId spaceId,
|
||||
|
@ -237,4 +245,4 @@ public class SaveDataExtraDataResultConvertAccessor : ISaveDataExtraDataAccessor
|
|||
{
|
||||
_accessor.Get.RegisterCacheObserver(observer, spaceId, saveDataId);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,10 @@ using IStorageSf = LibHac.FsSrv.Sf.IStorage;
|
|||
|
||||
namespace LibHac.FsSrv.Impl;
|
||||
|
||||
/// <summary>
|
||||
/// Wraps an <see cref="IStorage"/> to allow interfacing with it via the <see cref="IStorageSf"/> interface over IPC.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class StorageInterfaceAdapter : IStorageSf
|
||||
{
|
||||
private SharedRef<IStorage> _baseStorage;
|
||||
|
@ -32,6 +36,9 @@ public class StorageInterfaceAdapter : IStorageSf
|
|||
if (destination.Size < 0)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
if (destination.Size < size)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
Result rc = Result.Success;
|
||||
|
||||
for (int tryNum = 0; tryNum < maxTryCount; tryNum++)
|
||||
|
@ -54,6 +61,9 @@ public class StorageInterfaceAdapter : IStorageSf
|
|||
if (source.Size < 0)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
if (source.Size < size)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
using var scopedPriorityChanger = new ScopedThreadPriorityChangerByAccessPriority(
|
||||
ScopedThreadPriorityChangerByAccessPriority.AccessMode.Write);
|
||||
|
||||
|
@ -99,4 +109,4 @@ public class StorageInterfaceAdapter : IStorageSf
|
|||
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
namespace LibHac.FsSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Gets Unix timestamps used to update a save data's commit time.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public interface ISaveDataCommitTimeStampGetter
|
||||
{
|
||||
Result Get(out long timeStamp);
|
||||
}
|
||||
}
|
|
@ -3,10 +3,14 @@ using LibHac.Fs;
|
|||
|
||||
namespace LibHac.FsSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Provides read/write access to a save data file system's extra data.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public interface ISaveDataExtraDataAccessor : IDisposable
|
||||
{
|
||||
Result WriteExtraData(in SaveDataExtraData extraData);
|
||||
Result CommitExtraData(bool updateTimeStamp);
|
||||
Result ReadExtraData(out SaveDataExtraData extraData);
|
||||
void RegisterCacheObserver(ISaveDataExtraDataAccessorCacheObserver observer, SaveDataSpaceId spaceId, ulong saveDataId);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,16 @@
|
|||
using System;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSrv.Impl;
|
||||
|
||||
namespace LibHac.FsSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Used when adding an <see cref="ISaveDataExtraDataAccessor"/> to the
|
||||
/// <see cref="SaveDataExtraDataAccessorCacheManager"/>. When an extra data accessor is disposed, the accessor will
|
||||
/// use this interface to notify the cache manager that it should be removed from the extra data cache.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public interface ISaveDataExtraDataAccessorCacheObserver : IDisposable
|
||||
{
|
||||
void Unregister(SaveDataSpaceId spaceId, ulong saveDataId);
|
||||
}
|
||||
}
|
|
@ -4,10 +4,14 @@ using LibHac.Fs;
|
|||
|
||||
namespace LibHac.FsSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Provides a mechanism for caching save data file systems.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public interface ISaveDataFileSystemCacheManager : IDisposable
|
||||
{
|
||||
bool GetCache(ref SharedRef<SaveDataFileSystemHolder> outFileSystem, SaveDataSpaceId spaceId, ulong saveDataId);
|
||||
void Register(ref SharedRef<SaveDataFileSystemHolder> fileSystem);
|
||||
void Register(ref SharedRef<ApplicationTemporaryFileSystem> fileSystem);
|
||||
void Unregister(SaveDataSpaceId spaceId, ulong saveDataId);
|
||||
}
|
||||
}
|
|
@ -5,8 +5,17 @@ using LibHac.Os;
|
|||
|
||||
namespace LibHac.FsSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Manages a list of cached save data file systems. Each file system is registered and retrieved
|
||||
/// based on its save data ID and save data space ID.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class SaveDataFileSystemCacheManager : ISaveDataFileSystemCacheManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds a single cached file system identified by its save data ID and save data space ID.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
[NonCopyable]
|
||||
private struct Cache
|
||||
{
|
||||
|
@ -26,9 +35,9 @@ public class SaveDataFileSystemCacheManager : ISaveDataFileSystemCacheManager
|
|||
return _fileSystem.HasValue && _spaceId == spaceId && _saveDataId == saveDataId;
|
||||
}
|
||||
|
||||
public void Move(ref SharedRef<SaveDataFileSystemHolder> outFileSystem)
|
||||
public SharedRef<SaveDataFileSystemHolder> Move()
|
||||
{
|
||||
outFileSystem.SetByMove(ref _fileSystem);
|
||||
return SharedRef<SaveDataFileSystemHolder>.CreateMove(ref _fileSystem);
|
||||
}
|
||||
|
||||
public void Register(ref SharedRef<SaveDataFileSystemHolder> fileSystem)
|
||||
|
@ -52,7 +61,7 @@ public class SaveDataFileSystemCacheManager : ISaveDataFileSystemCacheManager
|
|||
|
||||
public SaveDataFileSystemCacheManager()
|
||||
{
|
||||
_mutex.Initialize();
|
||||
_mutex = new SdkRecursiveMutexType();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -77,11 +86,12 @@ public class SaveDataFileSystemCacheManager : ISaveDataFileSystemCacheManager
|
|||
Assert.SdkAssert(_cachedFileSystems is null);
|
||||
|
||||
_maxCachedFileSystemCount = maxCacheCount;
|
||||
if (maxCacheCount <= 0)
|
||||
return Result.Success;
|
||||
if (maxCacheCount > 0)
|
||||
{
|
||||
// Note: The original checks for overflow here
|
||||
_cachedFileSystems = new Cache[maxCacheCount];
|
||||
}
|
||||
|
||||
// Note: The original checks for overflow here
|
||||
_cachedFileSystems = new Cache[maxCacheCount];
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
|
@ -96,7 +106,9 @@ public class SaveDataFileSystemCacheManager : ISaveDataFileSystemCacheManager
|
|||
{
|
||||
if (_cachedFileSystems[i].IsCached(spaceId, saveDataId))
|
||||
{
|
||||
_cachedFileSystems[i].Move(ref outFileSystem);
|
||||
using SharedRef<SaveDataFileSystemHolder> cachedFs = _cachedFileSystems[i].Move();
|
||||
outFileSystem.SetByMove(ref cachedFs.Ref());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -156,4 +168,4 @@ public class SaveDataFileSystemCacheManager : ISaveDataFileSystemCacheManager
|
|||
{
|
||||
return new UniqueLockRef<SdkRecursiveMutexType>(ref _mutex);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using InlineIL;
|
||||
using System.Runtime.CompilerServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Diag;
|
||||
using LibHac.Fs;
|
||||
|
@ -14,6 +14,7 @@ namespace LibHac.FsSystem;
|
|||
/// </summary>
|
||||
/// <typeparam name="T">The type of the base file system. Must be one of <see cref="SaveDataFileSystem"/>,
|
||||
/// <see cref="ApplicationTemporaryFileSystem"/> or <see cref="DirectorySaveDataFileSystem"/>.</typeparam>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class SaveDataFileSystemCacheRegisterBase<T> : IFileSystem where T : IFileSystem
|
||||
{
|
||||
private SharedRef<T> _baseFileSystem;
|
||||
|
@ -36,11 +37,11 @@ public class SaveDataFileSystemCacheRegisterBase<T> : IFileSystem where T : IFil
|
|||
{
|
||||
if (typeof(T) == typeof(SaveDataFileSystemHolder))
|
||||
{
|
||||
_cacheManager.Register(ref GetBaseFileSystemNormal());
|
||||
_cacheManager.Register(ref Unsafe.As<SharedRef<T>, SharedRef<SaveDataFileSystemHolder>>(ref _baseFileSystem));
|
||||
}
|
||||
else if (typeof(T) == typeof(ApplicationTemporaryFileSystem))
|
||||
{
|
||||
_cacheManager.Register(ref GetBaseFileSystemTemp());
|
||||
_cacheManager.Register(ref Unsafe.As<SharedRef<T>, SharedRef<ApplicationTemporaryFileSystem>>(ref _baseFileSystem));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -48,23 +49,6 @@ public class SaveDataFileSystemCacheRegisterBase<T> : IFileSystem where T : IFil
|
|||
}
|
||||
}
|
||||
|
||||
// Hack around not being able to use Unsafe.As on ref structs
|
||||
private ref SharedRef<SaveDataFileSystemHolder> GetBaseFileSystemNormal()
|
||||
{
|
||||
IL.Emit.Ldarg_0();
|
||||
IL.Emit.Ldflda(new FieldRef(typeof(SaveDataFileSystemCacheRegisterBase<T>), nameof(_baseFileSystem)));
|
||||
IL.Emit.Ret();
|
||||
throw IL.Unreachable();
|
||||
}
|
||||
|
||||
private ref SharedRef<ApplicationTemporaryFileSystem> GetBaseFileSystemTemp()
|
||||
{
|
||||
IL.Emit.Ldarg_0();
|
||||
IL.Emit.Ldflda(new FieldRef(typeof(SaveDataFileSystemCacheRegisterBase<T>), nameof(_baseFileSystem)));
|
||||
IL.Emit.Ret();
|
||||
throw IL.Unreachable();
|
||||
}
|
||||
|
||||
protected override Result DoOpenFile(ref UniqueRef<IFile> outFile, in Path path, OpenMode mode)
|
||||
{
|
||||
return _baseFileSystem.Get.OpenFile(ref outFile, path, mode);
|
||||
|
|
|
@ -6,6 +6,13 @@ using LibHac.Fs.Fsa;
|
|||
|
||||
namespace LibHac.FsSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Holds a file system for adding to the save data file system cache.
|
||||
/// </summary>
|
||||
/// <remarks> Nintendo uses concrete types in <see cref="ISaveDataFileSystemCacheManager"/> instead of an interface.
|
||||
/// This class allows <see cref="DirectorySaveDataFileSystem"/> to be cached in a way that changes the original
|
||||
/// design as little as possible.
|
||||
/// </remarks>
|
||||
public class SaveDataFileSystemHolder : ForwardingFileSystem
|
||||
{
|
||||
public SaveDataFileSystemHolder(ref SharedRef<IFileSystem> baseFileSystem) : base(ref baseFileSystem)
|
||||
|
@ -49,4 +56,4 @@ public class SaveDataFileSystemHolder : ForwardingFileSystem
|
|||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue