anx.framework/ANX.Framework/Content/ContentManager.cs
SND\AstrorEnales_cp 73b50ab6c3 - Translated the AlphaTest shader to GLSL (needs some more testing)
- Added a bunch of Development attributes
- Fixed a class file name that was different from the class name itself
2015-03-15 01:11:46 +01:00

218 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using ANX.Framework.NonXNA.PlatformSystem;
using ANX.Framework.NonXNA.Development;
// This file is part of the ANX.Framework created by the
// "ANX.Framework developer group" and released under the Ms-PL license.
// For details see: http://anxframework.codeplex.com/license
namespace ANX.Framework.Content
{
[Developer("GinieDP")]
[TestState(TestStateAttribute.TestState.Untested)]
public class ContentManager : IDisposable
{
#region Constants
public const string Extension = ".xnb";
#endregion
#region Private
private Dictionary<string, object> loadedAssets;
private List<IDisposable> disposableAssets;
private string rootDirectory;
private string rootDirectoryAbsolute;
private bool disposed;
private INativeContentManager nativeImplementation;
#endregion
#region Public
public IServiceProvider ServiceProvider
{
get;
private set;
}
public string RootDirectory
{
get
{
return rootDirectory;
}
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
if (this.loadedAssets.Count > 0)
{
throw new InvalidOperationException(
"Cannot change directory with assets loaded.");
}
rootDirectory = value;
rootDirectoryAbsolute = value;
if (Path.IsPathRooted(value) == false)
{
rootDirectoryAbsolute =
nativeImplementation.MakeRootDirectoryAbsolute(rootDirectory);
}
}
}
#endregion
#region Constructor
private ContentManager()
{
nativeImplementation = PlatformSystem.Instance.CreateContentManager();
loadedAssets =
new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
disposableAssets = new List<IDisposable>();
}
public ContentManager(IServiceProvider serviceProvider)
: this(serviceProvider, String.Empty)
{
}
public ContentManager(IServiceProvider serviceProvider, string rootDirectory)
: this()
{
if (serviceProvider == null)
{
throw new ArgumentNullException("serviceProvider");
}
if (rootDirectory == null)
{
throw new ArgumentNullException("rootDirectory");
}
this.RootDirectory = rootDirectory;
this.ServiceProvider = serviceProvider;
}
#endregion
#region Dispose
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
try
{
if (disposing && disposed == false)
{
this.Unload();
}
}
finally
{
this.disposed = true;
this.loadedAssets.Clear();
this.disposableAssets.Clear();
}
}
public virtual void Unload()
{
ThrowExceptionIfDisposed();
foreach (var asset in this.disposableAssets)
{
try
{
asset.Dispose();
}
catch { /* just swallow and keep going */ }
}
this.loadedAssets.Clear();
this.disposableAssets.Clear();
}
#endregion
#region Load
public virtual T Load<T>(string assetName)
{
ThrowExceptionIfDisposed();
if (assetName == null)
{
throw new ArgumentNullException("assetName");
}
assetName = TitleContainer.GetCleanPath(assetName);
object result;
if (this.loadedAssets.TryGetValue(assetName, out result))
{
if (!(result is T))
{
throw new ContentLoadException(
"requested asset type and loaded asset are from different type");
}
return (T)result;
}
T asset = ReadAsset<T>(assetName, null);
this.loadedAssets.Add(assetName, asset);
if (asset is IDisposable)
{
disposableAssets.Add(asset as IDisposable);
}
return asset;
}
#endregion
#region ReadAsset
protected T ReadAsset<T>(string assetName,
Action<IDisposable> recordDisposableObject)
{
if (assetName == null)
{
throw new ArgumentNullException("assetName");
}
using (Stream stream = OpenStream(assetName))
{
using (ContentReader reader = ContentReader.Create(this, stream, assetName))
{
return reader.ReadAsset<T>();
}
}
}
#endregion
#region OpenStream
protected virtual Stream OpenStream(string assetName)
{
try
{
string path = Path.Combine(rootDirectoryAbsolute, assetName + Extension);
return nativeImplementation.OpenStream(path);
}
catch (Exception ex)
{
throw new ContentLoadException(String.Format("failed to open stream for '{0}'", assetName), ex);
}
}
#endregion
#region ThrowExceptionIfDisposed
protected void ThrowExceptionIfDisposed()
{
if (disposed)
{
throw new ObjectDisposedException(ToString());
}
}
#endregion
}
}