79 lines
2.5 KiB
C#
79 lines
2.5 KiB
C#
using System.Reflection;
|
|
using System.Text;
|
|
|
|
namespace SlaveEngine.Assets;
|
|
|
|
public sealed class ResourceManager {
|
|
|
|
public ResourceManager(string basePath) {
|
|
if (!Path.Exists(basePath))
|
|
throw new DirectoryNotFoundException($"The base path '{basePath}' does not exist.");
|
|
BasePath = basePath;
|
|
Instance = this;
|
|
}
|
|
|
|
public static ResourceManager? Instance { get; private set; }
|
|
public string BasePath { get; private set; }
|
|
|
|
private readonly List<AssetProcessor> _assetProcessors = new();
|
|
private readonly Dictionary<string, string> _assetIndex = new();
|
|
private readonly Dictionary<string, Asset> _assetCache = new();
|
|
|
|
public void Initialize() {
|
|
ScanDirectory(BasePath);
|
|
}
|
|
|
|
private void ScanDirectory(string directory) {
|
|
foreach (var file in Directory.GetFiles(directory, "*.spart")) {
|
|
try {
|
|
var id = ReadAssetIdFromSpart(file);
|
|
_assetIndex[id] = file;
|
|
} catch {
|
|
// skip corrupt files
|
|
}
|
|
}
|
|
}
|
|
|
|
public T? GetAsset<T>(string id) where T : Asset {
|
|
if (_assetCache.TryGetValue(id, out var cached))
|
|
return (T)cached;
|
|
|
|
if (!_assetIndex.TryGetValue(id, out var path))
|
|
return null;
|
|
|
|
var ext = Path.GetExtension(path);
|
|
var processor = GetProcessorForExtension(ext);
|
|
if (processor == null)
|
|
return null;
|
|
|
|
var fileInfo = new AssetFileInfo {
|
|
Filename = Path.GetFileNameWithoutExtension(path),
|
|
FilePath = path
|
|
};
|
|
|
|
var asset = processor.Process(fileInfo, File.ReadAllBytes(path));
|
|
_assetCache[id] = asset;
|
|
return (T)asset;
|
|
}
|
|
|
|
public IReadOnlyCollection<string> GetAssetIds() => _assetIndex.Keys;
|
|
|
|
public void RegisterProcessor(AssetProcessor processor) {
|
|
if (_assetProcessors.All(p => p.GetType() != processor.GetType()))
|
|
_assetProcessors.Add(processor);
|
|
}
|
|
|
|
private AssetProcessor? GetProcessorForExtension(string extension) =>
|
|
_assetProcessors.FirstOrDefault(p => p.GetType()
|
|
.GetCustomAttribute<AssetProcessorAttribute>()?.ManagedExtensions
|
|
.Contains(extension) == true);
|
|
|
|
private static string ReadAssetIdFromSpart(string path) {
|
|
using var stream = File.OpenRead(path);
|
|
using var reader = new BinaryReader(stream);
|
|
reader.ReadBytes(8);
|
|
var len = reader.ReadInt32();
|
|
return Encoding.UTF8.GetString(reader.ReadBytes(len));
|
|
}
|
|
}
|