diff --git a/ANX.Framework/Storage/StorageContainer.cs b/ANX.Framework/Storage/StorageContainer.cs index a6fd9658..d94c0795 100644 --- a/ANX.Framework/Storage/StorageContainer.cs +++ b/ANX.Framework/Storage/StorageContainer.cs @@ -57,7 +57,6 @@ namespace ANX.Framework.Storage public class StorageContainer : IDisposable { private DirectoryInfo baseDirectory; - private PlayerIndex player; public event EventHandler Disposing; @@ -65,30 +64,8 @@ namespace ANX.Framework.Storage { StorageDevice = device; DisplayName = displayName; - this.player = player; - string myDocsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); - string playerPath; - switch (player) - { - case PlayerIndex.One: - playerPath = "Player1"; - break; - case PlayerIndex.Two: - playerPath = "Player2"; - break; - case PlayerIndex.Three: - playerPath = "Player3"; - break; - case PlayerIndex.Four: - playerPath = "Player4"; - break; - default: - playerPath = "AllPlayers"; - break; - } - - baseDirectory = new DirectoryInfo(Path.Combine(myDocsPath, displayName, playerPath)); + baseDirectory = new DirectoryInfo(Path.Combine(device.StoragePath, displayName)); baseDirectory.Create(); //fails silently if directory exists } @@ -166,14 +143,11 @@ namespace ANX.Framework.Storage return File.Open(GetTestFullPath(file), fileMode, fileAccess, fileShare); } - public string DisplayName - { get; protected set; } + public string DisplayName { get; protected set; } - public StorageDevice StorageDevice - { get; protected set; } + public StorageDevice StorageDevice { get; protected set; } - public bool IsDisposed - { get; protected set; } + public bool IsDisposed { get; protected set; } public void Dispose() { diff --git a/ANX.Framework/Storage/StorageDevice.cs b/ANX.Framework/Storage/StorageDevice.cs index 64ee00a5..9f18d130 100644 --- a/ANX.Framework/Storage/StorageDevice.cs +++ b/ANX.Framework/Storage/StorageDevice.cs @@ -1,5 +1,6 @@ #region Using Statements using System; +using System.IO; #endregion // Using Statements @@ -54,70 +55,165 @@ namespace ANX.Framework.Storage { public sealed class StorageDevice { + private static Func openDeviceDelegate = null; + + private DriveInfo storageDrive; + private Func openContainerDelegate = null; + public static event EventHandler DeviceChanged; + internal StorageDevice(string storagePath) + { + StoragePath = Path.GetFullPath(storagePath); + storageDrive = new DriveInfo(Path.GetPathRoot(storagePath).Substring(0, 1)); + } + public IAsyncResult BeginOpenContainer(string displayName, AsyncCallback callback, Object state) { - throw new NotImplementedException(); + //See comments of OpenStorageDevice + if (openContainerDelegate != null) + throw new InvalidOperationException("There is currently a StorageContainer request pending. Please let this request finish."); + + openContainerDelegate = new Func(OpenStorageContainer); + return openContainerDelegate.BeginInvoke(displayName, callback, state); } - public static IAsyncResult BeginShowSelector(AsyncCallback callback, Object state) - { - throw new NotImplementedException(); - } + public static IAsyncResult BeginShowSelector(AsyncCallback callback, Object state) //We can't use optional parameters, because they can only be used as last! + { return BeginShowSelector(PlayerIndex.One, 0, 0, callback, state); } public static IAsyncResult BeginShowSelector(int sizeInBytes, int directoryCount, AsyncCallback callback, Object state) - { - throw new NotImplementedException(); - } + { return BeginShowSelector(PlayerIndex.One, sizeInBytes, directoryCount, callback, state); } public static IAsyncResult BeginShowSelector(PlayerIndex player, AsyncCallback callback, Object state) - { - throw new NotImplementedException(); - } + { return BeginShowSelector(player, 0, 0, callback, state); } public static IAsyncResult BeginShowSelector(PlayerIndex player, int sizeInBytes, int directoryCount, AsyncCallback callback, Object state) { - throw new NotImplementedException(); + //See comments of OpenStorageDevice + if (openDeviceDelegate != null) + throw new InvalidOperationException("There is currently a StorageDevice request pending. Please let this request finish."); + + openDeviceDelegate = new Func(OpenStorageDevice); + return openDeviceDelegate.BeginInvoke(player, sizeInBytes, directoryCount, callback, state); } public void DeleteContainer(string titleName) { - throw new NotImplementedException(); + if(string.IsNullOrEmpty(titleName)) + throw new ArgumentNullException("titleName"); + + try + { + Directory.Delete(Path.Combine(StoragePath, titleName), true); + } + catch (IOException e) + { + throw new InvalidOperationException("A IOException occured while deleting the container. See inner Exception.", e); + } } public StorageContainer EndOpenContainer(IAsyncResult result) { - throw new NotImplementedException(); + if (openContainerDelegate == null) + throw new InvalidOperationException("There is operation pending that could be ended."); + + StorageContainer container = openContainerDelegate.EndInvoke(result); + openContainerDelegate = null; + return container; } public static StorageDevice EndShowSelector(IAsyncResult result) { - throw new NotImplementedException(); + if (openDeviceDelegate == null) + throw new InvalidOperationException("There is operation pending that could be ended."); + + StorageDevice device = openDeviceDelegate.EndInvoke(result); + openDeviceDelegate = null; + return device; } public long FreeSpace { get { - throw new NotImplementedException(); + try + { + return storageDrive.AvailableFreeSpace; + } + catch (IOException) + { + return -1; + } } } public bool IsConnected - { - get - { - throw new NotImplementedException(); - } - } + { get { return storageDrive.IsReady; } } public long TotalSpace { get { - throw new NotImplementedException(); + try + { + return storageDrive.TotalSize; + } + catch (IOException) + { + return -1; + } } } + + /// + /// The path this storage device is currently pointing to. + /// + internal string StoragePath { get; private set; } + + /// + /// The player this device is currently assosiated with. + /// + internal PlayerIndex PlayerIndex { get; private set; } + + /// + /// Private Helper Method that does the real work of *OpenStorageDevice. + /// + /// We invoke this Method async using a delegate to have a IAsyncResult that we can return. + /// This Method will return nearly instant, but XNA requires to have Begin/End-Methods. + /// Currently, there is only one "device", the HDD. Saves are placed in /My Documents/SavedGames. We don't care about the size or + /// directory count, the HDD will should enough space anyway ;) + private static StorageDevice OpenStorageDevice(PlayerIndex player, int sizeInBytes, int directoryCount) + { + string playerPath; + switch (player) + { + case PlayerIndex.One: + playerPath = "Player1"; + break; + case PlayerIndex.Two: + playerPath = "Player2"; + break; + case PlayerIndex.Three: + playerPath = "Player3"; + break; + case PlayerIndex.Four: + playerPath = "Player4"; + break; + default: + playerPath = "AllPlayers"; + break; + } + + string myDocsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "SavedGames", playerPath); + return new StorageDevice(myDocsPath); + } + + /// + /// See comment for OpenStorageDevice. + /// + private StorageContainer OpenStorageContainer(string displayName) + { + return new StorageContainer(this, this.PlayerIndex, displayName); + } } } diff --git a/ANX.Framework/Storage/StorageDeviceNotConnectedException.cs b/ANX.Framework/Storage/StorageDeviceNotConnectedException.cs index 0301389f..72640f28 100644 --- a/ANX.Framework/Storage/StorageDeviceNotConnectedException.cs +++ b/ANX.Framework/Storage/StorageDeviceNotConnectedException.cs @@ -58,27 +58,19 @@ namespace ANX.Framework.Storage { public StorageDeviceNotConnectedException() : base() - { - - } + { } protected StorageDeviceNotConnectedException(SerializationInfo info, StreamingContext context) : base(info, context) - { - - } + { } public StorageDeviceNotConnectedException(string message) : base(message) - { - - } + { } public StorageDeviceNotConnectedException(string message, Exception innerException) : base(message, innerException) - { - - } + { } } }