mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add documentation for SaveDataIndexer and related classes
This commit is contained in:
parent
730167785e
commit
9e57cc174e
6 changed files with 191 additions and 2 deletions
|
@ -3,23 +3,146 @@ using LibHac.Fs;
|
|||
|
||||
namespace LibHac.FsService
|
||||
{
|
||||
/// <summary>
|
||||
/// Indexes save data metadata, holding key-value pairs of types <see cref="SaveDataAttribute"/> and
|
||||
/// <see cref="SaveDataIndexerValue"/> respectively.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Each <see cref="SaveDataIndexerValue"/> value contains information about the save data
|
||||
/// including its size and current state, as well as its <see cref="SaveDataSpaceId"/> and save data
|
||||
/// ID which represent the save data's storage location on disk.
|
||||
/// </remarks>
|
||||
public interface ISaveDataIndexer : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Commit any changes made to the save data index.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result Commit();
|
||||
|
||||
/// <summary>
|
||||
/// Rollback any changes made to the save data index since the last commit.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result Rollback();
|
||||
|
||||
/// <summary>
|
||||
/// Remove all entries from the save data index and set the index to its initial state.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result Reset();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new key to the index and returns the save data ID assigned to it.
|
||||
/// The created value will only contain the assigned save data ID.
|
||||
/// Fails if the key already exists.
|
||||
/// </summary>
|
||||
/// <param name="saveDataId">If the method returns successfully, contains the
|
||||
/// save data ID assigned to the new entry.
|
||||
/// Save data IDs are assigned using a counter that is incremented for each added save.</param>
|
||||
/// <param name="key">The key to add.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result Publish(out ulong saveDataId, in SaveDataAttribute key);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the <see cref="SaveDataIndexerValue"/> for the specified <see cref="SaveDataAttribute"/> key.
|
||||
/// </summary>
|
||||
/// <param name="value">If the method returns successfully, contains the
|
||||
/// save data ID assigned to the new entry.</param>
|
||||
/// <param name="key">The key of the value to get.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result Get(out SaveDataIndexerValue value, in SaveDataAttribute key);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a key with a pre-specified static save data ID to the index.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Adding a save data ID that is already in the index is not allowed. Adding a static ID that might
|
||||
/// conflict with a future dynamically-assigned ID should be avoided, otherwise there will be two saves
|
||||
/// with the same ID.
|
||||
/// FileSystemProxy avoids this by setting the high bit on static IDs. e.g. 0x8000000000000015
|
||||
/// </remarks>
|
||||
/// <param name="key">The key to add.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result PutStaticSaveDataIdIndex(in SaveDataAttribute key);
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there are any non-reserved entry slots remaining in the index.
|
||||
/// </summary>
|
||||
/// <remarks>If the <see cref="ISaveDataIndexer"/> has a fixed number of entries, a portion of
|
||||
/// those entries may be reserved for internal use, </remarks>
|
||||
/// <returns><see langword="true"/> if there are any non-reserved entries remaining,
|
||||
/// otherwise <see langword="false"/>.</returns>
|
||||
bool IsRemainedReservedOnly();
|
||||
|
||||
/// <summary>
|
||||
/// Removes the save data with the specified save data ID from the index.
|
||||
/// </summary>
|
||||
/// <param name="saveDataId">The ID of the save to be removed.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result Delete(ulong saveDataId);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="SaveDataSpaceId"/> in the specified save data's value.
|
||||
/// </summary>
|
||||
/// <param name="saveDataId">The save data ID of the save data to modify.</param>
|
||||
/// <param name="spaceId">The new <see cref="SaveDataSpaceId"/> for the specified save data.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result SetSpaceId(ulong saveDataId, SaveDataSpaceId spaceId);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the size in the specified save data's value.
|
||||
/// </summary>
|
||||
/// <param name="saveDataId">The save data ID of the save data to modify.</param>
|
||||
/// <param name="size">The new size for the specified save data.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result SetSize(ulong saveDataId, long size);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="SaveDataState"/> in the specified save data's value.
|
||||
/// </summary>
|
||||
/// <param name="saveDataId">The save data ID of the save data to modify.</param>
|
||||
/// <param name="state">The new <see cref="SaveDataState"/> for the specified save data.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result SetState(ulong saveDataId, SaveDataState state);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key of the specified save data ID.
|
||||
/// </summary>
|
||||
/// <param name="key">If the method returns successfully, contains the <see cref="SaveDataAttribute"/>
|
||||
/// key of the specified save data ID.</param>
|
||||
/// <param name="saveDataId">The save data ID to locate.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result GetKey(out SaveDataAttribute key, ulong saveDataId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the specified save data ID.
|
||||
/// </summary>
|
||||
/// <param name="value">If the method returns successfully, contains the <see cref="SaveDataIndexerValue"/>
|
||||
/// value of the specified save data ID.</param>
|
||||
/// <param name="saveDataId">The save data ID to locate.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result GetValue(out SaveDataIndexerValue value, ulong saveDataId);
|
||||
|
||||
/// <summary>
|
||||
/// Sets a new value to a key that already exists in the index.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the value to set.</param>
|
||||
/// <param name="value">The new value to associate with the specified key.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result SetValue(in SaveDataAttribute key, in SaveDataIndexerValue value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of elements currently in the <see cref="SaveDataIndexer"/>.
|
||||
/// </summary>
|
||||
/// <returns>The current element count.</returns>
|
||||
int GetIndexCount();
|
||||
|
||||
/// <summary>
|
||||
/// Returns an <see cref="ISaveDataInfoReader"/> that iterates through the <see cref="SaveDataIndexer"/>.
|
||||
/// </summary>
|
||||
/// <param name="infoReader">If the method returns successfully, contains the created <see cref="ISaveDataInfoReader"/>.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result OpenSaveDataInfoReader(out ReferenceCountedDisposable<ISaveDataInfoReader> infoReader);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,24 @@
|
|||
using System;
|
||||
using LibHac.Fs;
|
||||
|
||||
namespace LibHac.FsService
|
||||
{
|
||||
/// <summary>
|
||||
/// Iterates through the <see cref="SaveDataInfo"/> of the save data
|
||||
/// in a single save data space.
|
||||
/// </summary>
|
||||
public interface ISaveDataInfoReader : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the next <see cref="SaveDataInfo"/> entries. This method will continue writing
|
||||
/// entries to <paramref name="saveDataInfoBuffer"/> until there is either no more space
|
||||
/// in the buffer, or until there are no more entries to iterate.
|
||||
/// </summary>
|
||||
/// <param name="readCount">If the method returns successfully, contains the number
|
||||
/// of <see cref="SaveDataInfo"/> written to <paramref name="saveDataInfoBuffer"/>.
|
||||
/// A value of 0 indicates that there are no more entries to iterate, or the buffer is too small.</param>
|
||||
/// <param name="saveDataInfoBuffer">The buffer in which to write the <see cref="SaveDataInfo"/>.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
Result Read(out long readCount, Span<byte> saveDataInfoBuffer);
|
||||
}
|
||||
}
|
|
@ -12,6 +12,16 @@ using LibHac.Kvdb;
|
|||
|
||||
namespace LibHac.FsService
|
||||
{
|
||||
/// <summary>
|
||||
/// Indexes metadata for persistent save data stored on disk, holding key-value pairs of types
|
||||
/// <see cref="SaveDataAttribute"/> and <see cref="SaveDataIndexerValue"/> respectively.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Each <see cref="SaveDataIndexer"/> manages one to two save data spaces.
|
||||
/// Each save data space is identified by a <see cref="SaveDataSpaceId"/>,
|
||||
/// and has its own unique storage location on disk.<br/>
|
||||
/// Based on FS 10.0.0 (nnSdk 10.4.0)
|
||||
/// </remarks>
|
||||
public class SaveDataIndexer : ISaveDataIndexer
|
||||
{
|
||||
private const int KvDatabaseCapacity = 0x1080;
|
||||
|
@ -92,6 +102,12 @@ namespace LibHac.FsService
|
|||
Debug.Assert(!sb.Overflowed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a <see cref="SaveDataInfo"/> from the provided <see cref="SaveDataAttribute"/> and <see cref="SaveDataIndexerValue"/>.
|
||||
/// </summary>
|
||||
/// <param name="info">When this method returns, contains the generated <see cref="SaveDataInfo"/>.</param>
|
||||
/// <param name="key">The key used to generate the <see cref="SaveDataInfo"/>.</param>
|
||||
/// <param name="value">The value used to generate the <see cref="SaveDataInfo"/>.</param>
|
||||
public static void GenerateSaveDataInfo(out SaveDataInfo info, in SaveDataAttribute key, in SaveDataIndexerValue value)
|
||||
{
|
||||
info = new SaveDataInfo
|
||||
|
@ -701,6 +717,10 @@ namespace LibHac.FsService
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mounts the storage for a <see cref="SaveDataIndexer"/>, and unmounts the storage
|
||||
/// when the <see cref="Mounter"/> is disposed;
|
||||
/// </summary>
|
||||
private ref struct Mounter
|
||||
{
|
||||
private FileSystemClient FsClient { get; set; }
|
||||
|
|
|
@ -4,6 +4,15 @@ using LibHac.Fs;
|
|||
|
||||
namespace LibHac.FsService
|
||||
{
|
||||
/// <summary>
|
||||
/// Indexes metadata for temporary save data, holding a key-value pair of types
|
||||
/// <see cref="SaveDataAttribute"/> and <see cref="SaveDataIndexerValue"/> respectively.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only one temporary save data may exist at a time. When a new
|
||||
/// save data is added to the index, the existing key-value pair is replaced.<br/>
|
||||
/// Based on FS 10.0.0 (nnSdk 10.4.0)
|
||||
/// </remarks>
|
||||
public class SaveDataIndexerLite : ISaveDataIndexer
|
||||
{
|
||||
private object Locker { get; } = new object();
|
||||
|
|
|
@ -7,6 +7,11 @@ using LibHac.FsService.Storage;
|
|||
|
||||
namespace LibHac.FsService
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes and holds <see cref="ISaveDataIndexer"/>s for each save data space.
|
||||
/// Creates accessors for individual SaveDataIndexers.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 10.0.0 (nnSdk 10.4.0)</remarks>
|
||||
internal class SaveDataIndexerManager : ISaveDataIndexerManager
|
||||
{
|
||||
private FileSystemClient FsClient { get; }
|
||||
|
@ -37,6 +42,18 @@ namespace LibHac.FsService
|
|||
_tempIndexer.Indexer = new SaveDataIndexerLite();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a <see cref="SaveDataIndexerAccessor"/> for the specified save data space.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The returned <see cref="SaveDataIndexerAccessor"/> will have exclusive access to the requested indexer.
|
||||
/// The accessor must be disposed after use.
|
||||
/// </remarks>
|
||||
/// <param name="accessor">If the method returns successfully, contains the created accessor.</param>
|
||||
/// <param name="neededInit">If the method returns successfully, contains <see langword="true"/>
|
||||
/// if the indexer needed to be initialized.</param>
|
||||
/// <param name="spaceId">The <see cref="SaveDataSpaceId"/> of the indexer to open.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
public Result OpenAccessor(out SaveDataIndexerAccessor accessor, out bool neededInit, SaveDataSpaceId spaceId)
|
||||
{
|
||||
neededInit = false;
|
||||
|
@ -200,6 +217,11 @@ namespace LibHac.FsService
|
|||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gives exclusive access to an <see cref="ISaveDataIndexer"/>.
|
||||
/// Releases the lock to the <see cref="ISaveDataIndexer"/> upon disposal.
|
||||
/// </summary>
|
||||
/// <remarks>Based on FS 10.0.0 (nnSdk 10.4.0)</remarks>
|
||||
public class SaveDataIndexerAccessor : IDisposable
|
||||
{
|
||||
public ISaveDataIndexer Indexer { get; }
|
||||
|
|
|
@ -10,8 +10,8 @@ namespace LibHac.FsSystem
|
|||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Transactional commits should be atomic as long as the <see cref="IFileSystem.RenameDirectory"/> function of the
|
||||
/// underlying <see cref="IFileSystem"/> is atomic.
|
||||
/// This class is based on nn::fssystem::DirectorySaveDataFileSystem in SDK 10.4.0 used in FS 10.0.0
|
||||
/// underlying <see cref="IFileSystem"/> is atomic.<br/>
|
||||
/// Based on FS 10.0.0 (nnSdk 10.4.0)
|
||||
/// </remarks>
|
||||
public class DirectorySaveDataFileSystem : IFileSystem
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue