Show More
Commit Description:
Various UI improvements.
Commit Description:
Various UI improvements.
References:
File last commit:
Show/Diff file:
Action:
FNA/src/Storage/StorageDevice.cs
356 lines | 8.0 KiB | text/x-csharp | CSharpLexer
356 lines | 8.0 KiB | text/x-csharp | CSharpLexer
r0 | #region License | |||
/* FNA - XNA4 Reimplementation for Desktop Platforms | ||||
* Copyright 2009-2020 Ethan Lee and the MonoGame Team | ||||
* | ||||
* Released under the Microsoft Public License. | ||||
* See LICENSE for details. | ||||
*/ | ||||
#endregion | ||||
#region Using Statements | ||||
using System; | ||||
using System.IO; | ||||
using System.Threading; | ||||
#endregion | ||||
namespace Microsoft.Xna.Framework.Storage | ||||
{ | ||||
/// <summary> | ||||
/// Exposes a storage device for storing user data. | ||||
/// </summary> | ||||
/// <remarks> | ||||
/// MSDN documentation contains related conceptual article: | ||||
/// http://msdn.microsoft.com/en-us/library/bb200105.aspx | ||||
/// </remarks> | ||||
public sealed class StorageDevice | ||||
{ | ||||
#region Public Properties | ||||
/// <summary> | ||||
/// Returns the amount of free space. | ||||
/// </summary> | ||||
public long FreeSpace | ||||
{ | ||||
get | ||||
{ | ||||
try | ||||
{ | ||||
// null drive means the OS denied info, so we get to guess! | ||||
if (drive == null) | ||||
{ | ||||
return long.MaxValue; | ||||
} | ||||
return drive.AvailableFreeSpace; | ||||
} | ||||
catch(Exception e) | ||||
{ | ||||
// Storage root was invalid or unavailable. | ||||
throw new StorageDeviceNotConnectedException( | ||||
"The storage device bound to the container is not connected.", | ||||
e | ||||
); | ||||
} | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Returns true if this StorageDevice path is accessible, false otherwise. | ||||
/// </summary> | ||||
public bool IsConnected | ||||
{ | ||||
get | ||||
{ | ||||
try | ||||
{ | ||||
// null drive means the OS denied info, so we get to guess! | ||||
if (drive == null) | ||||
{ | ||||
return true; | ||||
} | ||||
return drive.IsReady; | ||||
} | ||||
catch | ||||
{ | ||||
// The storageRoot path is invalid / has been removed. | ||||
return false; | ||||
} | ||||
} | ||||
} | ||||
/// <summary> | ||||
/// Returns the total size of device. | ||||
/// </summary> | ||||
public long TotalSpace | ||||
{ | ||||
get | ||||
{ | ||||
try | ||||
{ | ||||
// null drive means the OS denied info, so we get to guess! | ||||
if (drive == null) | ||||
{ | ||||
return long.MaxValue; | ||||
} | ||||
return drive.TotalSize; | ||||
} | ||||
catch(Exception e) | ||||
{ | ||||
// Storage root was invalid or unavailable. | ||||
throw new StorageDeviceNotConnectedException( | ||||
"The storage device bound to the container is not connected.", | ||||
e | ||||
); | ||||
} | ||||
} | ||||
} | ||||
#endregion | ||||
#region Private Variables | ||||
private PlayerIndex? devicePlayer; | ||||
#endregion | ||||
#region Private Static Variables | ||||
private static readonly string storageRoot = FNAPlatform.GetStorageRoot(); | ||||
private static readonly DriveInfo drive = FNAPlatform.GetDriveInfo(storageRoot); | ||||
#endregion | ||||
#region Events | ||||
/// <summary> | ||||
/// Fired when a device is removed or inserted. | ||||
/// </summary> | ||||
public static event EventHandler<EventArgs> DeviceChanged; | ||||
private void OnDeviceChanged() | ||||
{ | ||||
if (DeviceChanged != null) | ||||
{ | ||||
DeviceChanged(this, null); | ||||
} | ||||
} | ||||
#endregion | ||||
#region Private XNA Lies | ||||
private class NotAsyncLie : IAsyncResult | ||||
{ | ||||
public object AsyncState | ||||
{ | ||||
get; | ||||
private set; | ||||
} | ||||
public bool CompletedSynchronously | ||||
{ | ||||
get | ||||
{ | ||||
return true; | ||||
} | ||||
} | ||||
public bool IsCompleted | ||||
{ | ||||
get | ||||
{ | ||||
return true; | ||||
} | ||||
} | ||||
public WaitHandle AsyncWaitHandle | ||||
{ | ||||
get; | ||||
private set; | ||||
} | ||||
public NotAsyncLie(object state) | ||||
{ | ||||
AsyncState = state; | ||||
AsyncWaitHandle = new ManualResetEvent(true); | ||||
} | ||||
} | ||||
private class ShowSelectorLie : NotAsyncLie | ||||
{ | ||||
public readonly PlayerIndex? PlayerIndex; | ||||
public ShowSelectorLie(object state, PlayerIndex? playerIndex) : base(state) | ||||
{ | ||||
PlayerIndex = playerIndex; | ||||
} | ||||
} | ||||
private class OpenContainerLie : NotAsyncLie | ||||
{ | ||||
public readonly string DisplayName; | ||||
public OpenContainerLie(object state, string displayName) : base(state) | ||||
{ | ||||
DisplayName = displayName; | ||||
} | ||||
} | ||||
#endregion | ||||
#region Internal Constructors | ||||
internal StorageDevice(PlayerIndex? player) | ||||
{ | ||||
devicePlayer = player; | ||||
} | ||||
#endregion | ||||
#region Public OpenContainer Methods | ||||
/// <summary> | ||||
/// Begins the open for a StorageContainer. | ||||
/// </summary> | ||||
/// <returns>The open StorageContainer.</returns> | ||||
/// <param name="displayName">Name of file.</param> | ||||
/// <param name="callback">Method to call on completion.</param> | ||||
/// <param name="state">Request identifier object for callback (can be null).</param> | ||||
public IAsyncResult BeginOpenContainer( | ||||
string displayName, | ||||
AsyncCallback callback, | ||||
object state | ||||
) { | ||||
IAsyncResult result = new OpenContainerLie(state, displayName); | ||||
if (callback != null) | ||||
{ | ||||
callback(result); | ||||
} | ||||
return result; | ||||
} | ||||
/// <summary> | ||||
/// Ends the open container process. | ||||
/// </summary> | ||||
/// <returns>The open StorageContainer.</returns> | ||||
/// <param name="result">Result of BeginOpenContainer.</param> | ||||
public StorageContainer EndOpenContainer(IAsyncResult result) | ||||
{ | ||||
return new StorageContainer( | ||||
this, | ||||
(result as OpenContainerLie).DisplayName, | ||||
storageRoot, | ||||
devicePlayer | ||||
); | ||||
} | ||||
#endregion | ||||
#region Public ShowSelector Methods | ||||
/// <summary> | ||||
/// Begin process to display the StorageDevice selector UI. | ||||
/// </summary> | ||||
/// <returns>The show selector.</returns> | ||||
/// <param name="callback">Method to invoke when device is selected by player.</param> | ||||
/// <param name="state">Request identifier object for callback (can be null).</param> | ||||
public static IAsyncResult BeginShowSelector( | ||||
AsyncCallback callback, | ||||
object state | ||||
) { | ||||
return BeginShowSelector( | ||||
0, | ||||
0, | ||||
callback, | ||||
state | ||||
); | ||||
} | ||||
/// <summary> | ||||
/// Begin process to display the StorageDevice selector UI. | ||||
/// </summary> | ||||
/// <returns>The show selector.</returns> | ||||
/// <param name="player">The PlayerIndex. Only PlayerIndex.One is valid on Windows.</param> | ||||
/// <param name="callback">Method to invoke when device is selected by player.</param> | ||||
/// <param name="state">Request identifier object for callback (can be null).</param> | ||||
public static IAsyncResult BeginShowSelector( | ||||
PlayerIndex player, | ||||
AsyncCallback callback, | ||||
object state | ||||
) { | ||||
return BeginShowSelector( | ||||
player, | ||||
0, | ||||
0, | ||||
callback, | ||||
state | ||||
); | ||||
} | ||||
/// <summary> | ||||
/// Begin process to display the StorageDevice selector UI. | ||||
/// </summary> | ||||
/// <returns>The show selector.</returns> | ||||
/// <param name="sizeInBytes">Size (in bytes) of data to write.</param> | ||||
/// <param name="directoryCount">Number of directories to write.</param> | ||||
/// <param name="callback">Method to invoke when device is selected by player.</param> | ||||
/// <param name="state">Request identifier object for callback (can be null).</param> | ||||
public static IAsyncResult BeginShowSelector( | ||||
int sizeInBytes, | ||||
int directoryCount, | ||||
AsyncCallback callback, | ||||
object state | ||||
) { | ||||
IAsyncResult result = new ShowSelectorLie(state, null); | ||||
if (callback != null) | ||||
{ | ||||
callback(result); | ||||
} | ||||
return result; | ||||
} | ||||
/// <summary> | ||||
/// Begin process to display the StorageDevice selector UI. | ||||
/// </summary> | ||||
/// <returns>The show selector.</returns> | ||||
/// <param name="player">The PlayerIndex. Only PlayerIndex.One is valid on Windows.</param> | ||||
/// <param name="sizeInBytes">Size (in bytes) of data to write.</param> | ||||
/// <param name="directoryCount">Number of directories to write.</param> | ||||
/// <param name="callback">Method to invoke when device is selected by player.</param> | ||||
/// <param name="state">Request identifier object for callback (can be null).</param> | ||||
public static IAsyncResult BeginShowSelector( | ||||
PlayerIndex player, | ||||
int sizeInBytes, | ||||
int directoryCount, | ||||
AsyncCallback callback, | ||||
object state | ||||
) { | ||||
IAsyncResult result = new ShowSelectorLie(state, player); | ||||
if (callback != null) | ||||
{ | ||||
callback(result); | ||||
} | ||||
return result; | ||||
} | ||||
/// <summary> | ||||
/// Ends the show selector user interface display. | ||||
/// </summary> | ||||
/// <returns>The storage device.</returns> | ||||
/// <param name="result">The result of BeginShowSelector.</param> | ||||
public static StorageDevice EndShowSelector(IAsyncResult result) | ||||
{ | ||||
return new StorageDevice((result as ShowSelectorLie).PlayerIndex); | ||||
} | ||||
#endregion | ||||
#region Public StorageContainer Delete Method | ||||
public void DeleteContainer(string titleName) | ||||
{ | ||||
throw new NotImplementedException(); | ||||
} | ||||
#endregion | ||||
} | ||||
} | ||||