1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-12-25 17:59:24 +01:00

raw content manager

This commit is contained in:
Ellpeck 2020-04-22 00:30:55 +02:00
parent c16c2ef693
commit 99d286d834
8 changed files with 166 additions and 14 deletions

View file

@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace MLEM.Content {
public class RawContentManager : ContentManager, IGameComponent {
private static readonly RawContentReader[] Readers = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetExportedTypes())
.Where(t => t.IsSubclassOf(typeof(RawContentReader)) && !t.IsAbstract)
.Select(t => t.GetConstructor(Type.EmptyTypes).Invoke(null))
.Cast<RawContentReader>().ToArray();
private readonly List<IDisposable> disposableAssets = new List<IDisposable>();
public readonly GraphicsDevice GraphicsDevice;
public RawContentManager(IServiceProvider serviceProvider, string rootDirectory = "Content") :
base(serviceProvider, rootDirectory) {
if (serviceProvider.GetService(typeof(IGraphicsDeviceService)) is IGraphicsDeviceService s)
this.GraphicsDevice = s.GraphicsDevice;
}
public override T Load<T>(string assetName) {
if (this.LoadedAssets.TryGetValue(assetName, out var ret) && ret is T t)
return t;
return this.Read<T>(assetName, default);
}
private static RawContentReader GetReader<T>() {
var reader = Readers.FirstOrDefault(r => r.CanRead(typeof(T)));
if (reader == null)
throw new ContentLoadException($"{typeof(T)} has no RawContentReader");
return reader;
}
protected override void ReloadAsset<T>(string originalAssetName, T currentAsset) {
this.Read(originalAssetName, currentAsset);
}
private T Read<T>(string assetName, T existing) {
var reader = GetReader<T>();
foreach (var ext in reader.GetFileExtensions()) {
var file = new FileInfo(Path.Combine(this.RootDirectory, $"{assetName}.{ext}"));
if (!file.Exists)
continue;
using (var stream = file.OpenRead()) {
var read = reader.Read(this, assetName, stream, existing);
if (!(read is T t))
throw new ContentLoadException($"{reader} returned non-{typeof(T)} for asset {assetName}");
this.LoadedAssets[assetName] = t;
if (t is IDisposable d)
this.disposableAssets.Add(d);
return t;
}
}
throw new ContentLoadException($"Asset {assetName} not found");
}
public override void Unload() {
foreach (var d in this.disposableAssets)
d.Dispose();
this.disposableAssets.Clear();
base.Unload();
}
public void Initialize() {
}
}
}

View file

@ -0,0 +1,28 @@
using System;
using System.IO;
namespace MLEM.Content {
public abstract class RawContentReader {
public abstract bool CanRead(Type t);
public abstract object Read(RawContentManager manager, string assetPath, Stream stream, object existing);
public abstract string[] GetFileExtensions();
}
public abstract class RawContentReader<T> : RawContentReader {
public override bool CanRead(Type t) {
return typeof(T).IsAssignableFrom(t);
}
public override object Read(RawContentManager manager, string assetPath, Stream stream, object existing) {
return this.Read(manager, assetPath, stream, (T) existing);
}
protected abstract T Read(RawContentManager manager, string assetPath, Stream stream, T existing);
}
}

View file

@ -0,0 +1,17 @@
using System;
using System.IO;
using Microsoft.Xna.Framework.Media;
namespace MLEM.Content {
public class SongReader : RawContentReader<Song> {
protected override Song Read(RawContentManager manager, string assetPath, Stream stream, Song existing) {
return Song.FromUri(Path.GetFileNameWithoutExtension(assetPath), new Uri(assetPath));
}
public override string[] GetFileExtensions() {
return new[] {"ogg", "wav", "mp3"};
}
}
}

View file

@ -0,0 +1,16 @@
using System.IO;
using Microsoft.Xna.Framework.Audio;
namespace MLEM.Content {
public class SoundEffectReader : RawContentReader<SoundEffect> {
protected override SoundEffect Read(RawContentManager manager, string assetPath, Stream stream, SoundEffect existing) {
return SoundEffect.FromStream(stream);
}
public override string[] GetFileExtensions() {
return new[] {"ogg", "wav", "mp3"};
}
}
}

View file

@ -0,0 +1,21 @@
using System.IO;
using Microsoft.Xna.Framework.Graphics;
namespace MLEM.Content {
public class Texture2DReader : RawContentReader<Texture2D> {
protected override Texture2D Read(RawContentManager manager, string assetPath, Stream stream, Texture2D existing) {
if (existing != null) {
existing.Reload(stream);
return existing;
} else {
return Texture2D.FromStream(manager.GraphicsDevice, stream);
}
}
public override string[] GetFileExtensions() {
return new[] {"png", "bmp", "gif", "jpg", "tif", "dds"};
}
}
}

View file

@ -24,18 +24,6 @@
#begin Test.json
/copy:Test.json
#begin Textures/Test.png
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:Textures/Test.png
#begin Tiled/Map.tmx
/importer:TiledMapImporter
/processor:TiledMapProcessor

View file

@ -4,6 +4,7 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using MLEM.Cameras;
using MLEM.Content;
using MLEM.Data;
using MLEM.Extended.Extensions;
using MLEM.Extended.Tiled;
@ -27,6 +28,7 @@ namespace Sandbox {
private TiledMap map;
private IndividualTiledMapRenderer mapRenderer;
private TiledMapCollisions collisions;
private RawContentManager rawContent;
public GameImpl() {
this.IsMouseVisible = true;
@ -38,6 +40,8 @@ namespace Sandbox {
protected override void LoadContent() {
base.LoadContent();
this.Components.Add(this.rawContent = new RawContentManager(this.Services));
this.map = LoadContent<TiledMap>("Tiled/Map");
this.mapRenderer = new IndividualTiledMapRenderer(this.map);
this.collisions = new TiledMapCollisions(this.map);
@ -50,7 +54,7 @@ namespace Sandbox {
MaxScale = 4
};
var tex = LoadContent<Texture2D>("Textures/Test");
var tex = this.rawContent.Load<Texture2D>("Textures/Test");
var font = new GenericSpriteFont(LoadContent<SpriteFont>("Fonts/TestFont"));
this.UiSystem.Style = new UntexturedStyle(this.SpriteBatch) {
Font = font,

View file

@ -22,7 +22,9 @@
<ItemGroup>
<MonoGameContentReference Include="Content\Content.mgcb" />
<Content Include="Content\*\**" />
<Content Include="Content\*\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>