using System; using System.Collections.Generic; using System.IO; using Microsoft.Xna.Framework.Content; namespace Awesome { public class SharedContentManager : ContentManager { static CommonContentManager Common; List loadedAssets; public SharedContentManager(IServiceProvider serviceProvider, string rootDirectory) : base(serviceProvider, rootDirectory) { EnsureSharedInitialized(); loadedAssets = new List(); } static void EnsureSharedInitialized() { if (Common == null) Common = new CommonContentManager(ServiceProvider, RootDirectory); } internal static string GetCleanPath(string path) { int num2; path = path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); for (int i = 1; i < path.Length; i = Math.Max(num2 - 1, 1)) { i = path.IndexOf(@"\..\", i); if (i < 0) { return path; } num2 = path.LastIndexOf(Path.DirectorySeparatorChar, i - 1) + 1; path = path.Remove(num2, (i - num2) + @"\..\".Length); } return path; } public override T Load(string assetName) { assetName = GetCleanPath(assetName); loadedAssets.Add(assetName); return Common.Load(assetName); } public override void Unload() { if (loadedAssets == null) throw new ObjectDisposedException(typeof(SharedContentManager).Name); Common.Unload(this); loadedAssets = null; base.Unload(); } class CommonContentManager : ContentManager { readonly Dictionary references; public CommonContentManager(IServiceProvider serviceProvider, string rootDirectory) : base(serviceProvider, rootDirectory) { references = new Dictionary(); } public override T Load(string assetName) { assetName = GetCleanPath(assetName); ReferencedAsset refAsset; if (!references.TryGetValue(assetName, out refAsset)) { refAsset = new ReferencedAsset { Asset = ReadAsset(assetName, null) }; references.Add(assetName, refAsset); } refAsset.References++; return (T)refAsset.Asset; } public void Unload(SharedContentManager container) { foreach (var assetName in container.loadedAssets) { var refAsset = references[assetName]; refAsset.References--; if (refAsset.References == 0) { if (refAsset.Asset is IDisposable) (refAsset.Asset as IDisposable).Dispose(); references.Remove(assetName); } } } class ReferencedAsset { public object Asset; public int References; } } } }