public SaveDataFileSystemCacheRegisterBase(ref ReferenceCountedDisposable <T> baseFileSystem,
                                                   ISaveDataFileSystemCacheManager cacheManager)
        {
            Assert.SdkRequires(typeof(T) == typeof(SaveDataFileSystem) ||
                               typeof(T) == typeof(ApplicationTemporaryFileSystem) ||
                               typeof(T) == typeof(DirectorySaveDataFileSystem));

            _baseFileSystem = Shared.Move(ref baseFileSystem);
            _cacheManager   = cacheManager;
        }
        public static ReferenceCountedDisposable <IFileSystem> CreateShared(
            ReferenceCountedDisposable <IFileSystem> baseFileSystem, ISaveDataFileSystemCacheManager cacheManager)
        {
            IFileSystem baseFsTarget = baseFileSystem.Target;

            switch (baseFsTarget)
            {
            case SaveDataFileSystem:
            {
                ReferenceCountedDisposable <SaveDataFileSystem> castedFs =
                    baseFileSystem.AddReference <SaveDataFileSystem>();

                return(new ReferenceCountedDisposable <IFileSystem>(
                           new SaveDataFileSystemCacheRegisterBase <SaveDataFileSystem>(ref castedFs, cacheManager)));
            }

            case ApplicationTemporaryFileSystem:
            {
                ReferenceCountedDisposable <ApplicationTemporaryFileSystem> castedFs =
                    baseFileSystem.AddReference <ApplicationTemporaryFileSystem>();

                return(new ReferenceCountedDisposable <IFileSystem>(
                           new SaveDataFileSystemCacheRegisterBase <ApplicationTemporaryFileSystem>(ref castedFs,
                                                                                                    cacheManager)));
            }

            case DirectorySaveDataFileSystem:
            {
                ReferenceCountedDisposable <DirectorySaveDataFileSystem> castedFs =
                    baseFileSystem.AddReference <DirectorySaveDataFileSystem>();

                return(new ReferenceCountedDisposable <IFileSystem>(
                           new SaveDataFileSystemCacheRegisterBase <DirectorySaveDataFileSystem>(ref castedFs,
                                                                                                 cacheManager)));
            }

            default:
                Assert.SdkAssert(false, "Invalid save data file system type.");
                return(null);
            }
        }
Beispiel #3
0
        public Result Create(out ReferenceCountedDisposable <IFileSystem> fileSystem,
                             out ReferenceCountedDisposable <ISaveDataExtraDataAccessor> extraDataAccessor,
                             ISaveDataFileSystemCacheManager cacheManager, ref ReferenceCountedDisposable <IFileSystem> baseFileSystem,
                             SaveDataSpaceId spaceId, ulong saveDataId, bool allowDirectorySaveData, bool useDeviceUniqueMac,
                             bool isJournalingSupported, bool isMultiCommitSupported, bool openReadOnly, bool openShared,
                             ISaveDataCommitTimeStampGetter timeStampGetter)
        {
            Span <byte> saveImageName = stackalloc byte[0x12];

            UnsafeHelpers.SkipParamInit(out fileSystem, out extraDataAccessor);

            Assert.SdkRequiresNotNull(cacheManager);

            var sb = new U8StringBuilder(saveImageName);

            sb.Append((byte)'/').AppendFormat(saveDataId, 'x', 16);

            Result rc = baseFileSystem.Target.GetEntryType(out DirectoryEntryType type, new U8Span(saveImageName));

            if (rc.IsFailure())
            {
                return(ResultFs.PathNotFound.Includes(rc) ? ResultFs.TargetNotFound.LogConverted(rc) : rc);
            }

            if (type == DirectoryEntryType.Directory)
            {
                if (!allowDirectorySaveData)
                {
                    return(ResultFs.InvalidSaveDataEntryType.Log());
                }

                SubdirectoryFileSystem subDirFs = null;
                ReferenceCountedDisposable <DirectorySaveDataFileSystem> saveFs = null;
                try
                {
                    subDirFs = new SubdirectoryFileSystem(ref baseFileSystem);

                    rc = subDirFs.Initialize(new U8Span(saveImageName));
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    saveFs = DirectorySaveDataFileSystem.CreateShared(Shared.Move(ref subDirFs), _fsServer.Hos.Fs);

                    rc = saveFs.Target.Initialize(timeStampGetter, _randomGenerator, isJournalingSupported,
                                                  isMultiCommitSupported, !openReadOnly);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    fileSystem        = saveFs.AddReference <IFileSystem>();
                    extraDataAccessor = saveFs.AddReference <ISaveDataExtraDataAccessor>();

                    return(Result.Success);
                }
                finally
                {
                    subDirFs?.Dispose();
                    saveFs?.Dispose();
                }
            }

            ReferenceCountedDisposable <IStorage> fileStorage = null;

            try
            {
                Optional <OpenType> openType =
                    openShared ? new Optional <OpenType>(OpenType.Normal) : new Optional <OpenType>();

                rc = _fsServer.OpenSaveDataStorage(out fileStorage, ref baseFileSystem, spaceId, saveDataId,
                                                   OpenMode.ReadWrite, openType);
                if (rc.IsFailure())
                {
                    return(rc);
                }

                if (!isJournalingSupported)
                {
                    throw new NotImplementedException();
                }

                // Todo: Properly handle shared storage
                fileSystem = new ReferenceCountedDisposable <IFileSystem>(new SaveDataFileSystem(_keySet,
                                                                                                 fileStorage.Target, IntegrityCheckLevel.ErrorOnInvalid, false));

                // Todo: ISaveDataExtraDataAccessor

                return(Result.Success);
            }
            finally
            {
                fileStorage?.Dispose();
            }
        }