mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Adjust opened SaveDataInfoReaders if the collection is modified
This commit is contained in:
parent
f0aac13fab
commit
04b123f16e
4 changed files with 67 additions and 3 deletions
|
@ -227,7 +227,7 @@ namespace LibHac.Fs.Shim
|
|||
}
|
||||
}
|
||||
|
||||
public struct SaveDataIterator
|
||||
public struct SaveDataIterator : IDisposable
|
||||
{
|
||||
private FileSystemClient FsClient { get; }
|
||||
private ISaveDataInfoReader Reader { get; }
|
||||
|
@ -259,5 +259,10 @@ namespace LibHac.Fs.Shim
|
|||
|
||||
return rc;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Reader?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace LibHac.FsService
|
||||
{
|
||||
public interface ISaveDataInfoReader
|
||||
public interface ISaveDataInfoReader : IDisposable
|
||||
{
|
||||
Result ReadSaveDataInfo(out long readCount, Span<byte> saveDataInfoBuffer);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
|
@ -26,6 +27,7 @@ namespace LibHac.FsService
|
|||
private bool IsKvdbLoaded { get; set; }
|
||||
private ulong LastPublishedId { get; set; }
|
||||
private int Version { get; set; }
|
||||
private List<SaveDataInfoReader> OpenedReaders { get; } = new List<SaveDataInfoReader>();
|
||||
|
||||
public SaveDataIndexer(FileSystemClient fsClient, string mountName, SaveDataSpaceId spaceId, ulong saveDataId)
|
||||
{
|
||||
|
@ -356,6 +358,8 @@ namespace LibHac.FsService
|
|||
|
||||
var reader = new SaveDataInfoReader(this);
|
||||
|
||||
OpenedReaders.Add(reader);
|
||||
|
||||
infoReader = reader;
|
||||
|
||||
return Result.Success;
|
||||
|
@ -490,10 +494,55 @@ namespace LibHac.FsService
|
|||
|
||||
private Result AdjustOpenedInfoReaders(ref SaveDataAttribute key)
|
||||
{
|
||||
// todo
|
||||
// If a new key is added or removed during iteration of the list,
|
||||
// make sure the current item of the iterator remains the same
|
||||
|
||||
// Todo: A more efficient way of doing this
|
||||
List<SaveDataAttribute> list = KvDatabase.ToList().Select(x => x.key).ToList();
|
||||
|
||||
int index = list.BinarySearch(key);
|
||||
|
||||
bool keyWasAdded = index >= 0;
|
||||
|
||||
if (!keyWasAdded)
|
||||
{
|
||||
// If the item was not found, List<T>.BinarySearch returns a negative number that
|
||||
// is the bitwise complement of the index of the next element that is larger than the item
|
||||
index = ~index;
|
||||
}
|
||||
|
||||
foreach (SaveDataInfoReader reader in OpenedReaders)
|
||||
{
|
||||
if (keyWasAdded)
|
||||
{
|
||||
// New key was inserted before the iterator's position
|
||||
// increment the position to compensate
|
||||
if(reader.Position >= index)
|
||||
{
|
||||
reader.Position++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The position should be decremented if the iterator's position is
|
||||
// after the key that came directly after the deleted key
|
||||
if (reader.Position > index)
|
||||
{
|
||||
reader.Position--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
private void CloseReader(SaveDataInfoReader reader)
|
||||
{
|
||||
bool wasRemoved = OpenedReaders.Remove(reader);
|
||||
|
||||
Debug.Assert(wasRemoved);
|
||||
}
|
||||
|
||||
private ref struct Mounter
|
||||
{
|
||||
private FileSystemClient FsClient { get; set; }
|
||||
|
@ -602,6 +651,11 @@ namespace LibHac.FsService
|
|||
return Result.Success;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Indexer?.CloseReader(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,11 @@ namespace LibHac.FsService
|
|||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Reader?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x50)]
|
||||
|
|
Loading…
Reference in a new issue