Refactored EditorContentManager

This commit is contained in:
Simon Lübeß
2023-03-16 23:31:19 +01:00
parent b22f73a156
commit cfa046d2ea
2 changed files with 67 additions and 111 deletions
+1 -1
View File
@@ -121,7 +121,7 @@ class AssetHierarchy
fsw.StartRaisingEvents(); fsw.StartRaisingEvents();
} }
/// Gets the tree node for the given filePath or null, if the file/directory doesn't exist. /// Gets the tree node for the given filePath or .Err, if the file/directory doesn't exist.
/// @param filePath the path for which to return the tree node. /// @param filePath the path for which to return the tree node.
/// @remarks Do not hold a reference to the TreeNode because it can become invalid when the file hierarchy changes. /// @remarks Do not hold a reference to the TreeNode because it can become invalid when the file hierarchy changes.
public Result<TreeNode<AssetNode>> GetNodeFromPath(StringView filePath) public Result<TreeNode<AssetNode>> GetNodeFromPath(StringView filePath)
+64 -108
View File
@@ -11,68 +11,6 @@ using System.Linq;
namespace GlitchyEditor; namespace GlitchyEditor;
/*class PreviewImageManager
{
/// Thread that loads/generates preview images in the background
//private Thread _loaderThread;
/// Set to true to notify the loader to stop
//private bool _stopLoader;
private append Dictionary<String, Texture2D> _previewImages = .() ~ {
for (var v in _)
{
delete v.key;
v.value.ReleaseRef();
}
delete _;
};
public Texture2D GetPreviewImage(String assetName)
{
if (_previewImages.TryGetValue(assetName, let image))
{
return image..AddRef();
}
if (assetName.EndsWith(".png", .OrdinalIgnoreCase))
{
/*using (Texture2D texture = new Texture2D(assetName, true))
{
Texture2DDesc desc = .(128, 128, .R8G8B8A8_UNorm_SRGB)
{
Usage = .Immutable
};
Texture2D myActualTexture = new Texture2D(desc);
// TODO: Scale down texture (on GPU?)
}*/
Texture2D texture = new Texture2D(assetName, true);
if (texture.Width <= 128 && texture.Height <= 128)
{
}
if ( texture.MipLevels > 1)
{
}
_previewImages.Add(new String(assetName), texture);
return texture..AddRef();
}
else
{
Runtime.NotImplemented();
}
}
}*/
class EditorContentManager : IContentManager class EditorContentManager : IContentManager
{ {
private append String _contentDirectory = .(); private append String _contentDirectory = .();
@@ -296,16 +234,10 @@ class EditorContentManager : IContentManager
StringView oldIdentifier = asset.Identifier; StringView oldIdentifier = asset.Identifier;
// Find subasset name GetResourceAndSubassetName(oldIdentifier, let resourceName, let subassetName);
int poundIndex = oldIdentifier.IndexOf('#');
StringView resourceName = poundIndex == -1 ? oldIdentifier : oldIdentifier.Substring(0, poundIndex); String filePath = scope .();
StringView? subassetName = oldIdentifier.Substring(poundIndex + 1); GetResourceFilePath(resourceName, filePath);
String filePath = scope String(resourceName.Length + _contentDirectory.Length + 2);
Path.Combine(filePath, _contentDirectory, resourceName);
Path.Fixup(filePath);
//filePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); //filePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
@@ -321,8 +253,6 @@ class EditorContentManager : IContentManager
IAssetLoader assetLoader = GetAssetLoader(file); IAssetLoader assetLoader = GetAssetLoader(file);
Log.EngineLogger.AssertDebug(assetLoader != null);
Stream stream = GetStream(filePath); Stream stream = GetStream(filePath);
Asset loadedAsset = assetLoader.LoadAsset(stream, file.AssetConfig.Config, resourceName, subassetName, this); Asset loadedAsset = assetLoader.LoadAsset(stream, file.AssetConfig.Config, resourceName, subassetName, this);
@@ -346,23 +276,39 @@ class EditorContentManager : IContentManager
file.[Friend]_loadedAsset = loadedAsset; file.[Friend]_loadedAsset = loadedAsset;
} }
/// Returns the resource name and, if it exists, the subasset name.
private void GetResourceAndSubassetName(StringView identifier, out StringView resourceName, out StringView? subassetName)
{
// Find subasset name
int poundIndex = identifier.IndexOf('#');
resourceName = poundIndex == -1 ? identifier : identifier.Substring(0, poundIndex);
subassetName = identifier.Substring(poundIndex + 1);
}
private void GetResourceFilePath(StringView resourceName, String filePath)
{
Path.Combine(filePath, _contentDirectory, resourceName);
Path.Fixup(filePath);
}
public AssetHandle LoadAsset(StringView identifier) public AssetHandle LoadAsset(StringView identifier)
{ {
if (_identiferToHandle.TryGetValue(identifier, let asset)) // Todo: How strict should we be on paths?
String fixedIdentifier = scope String(identifier);
// TODO: Fixup is more of a filesystem thingy... we might want to use our own function
Path.Fixup(fixedIdentifier);
if (_identiferToHandle.TryGetValue(fixedIdentifier, let asset))
{ {
return asset; return asset;
} }
// Find subasset name GetResourceAndSubassetName(fixedIdentifier, let resourceName, let subassetName);
int poundIndex = identifier.IndexOf('#');
StringView resourceName = poundIndex == -1 ? identifier : identifier.Substring(0, poundIndex); String filePath = scope .();
StringView? subassetName = identifier.Substring(poundIndex + 1); GetResourceFilePath(resourceName, filePath);
String filePath = scope String(resourceName.Length + _contentDirectory.Length + 2);
Path.Combine(filePath, _contentDirectory, resourceName);
Path.Fixup(filePath);
//filePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); //filePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
@@ -378,6 +324,7 @@ class EditorContentManager : IContentManager
IAssetLoader assetLoader = GetAssetLoader(file); IAssetLoader assetLoader = GetAssetLoader(file);
// TODO: what are we supposed to do if we don't find a loader? Sure not crash...
Log.EngineLogger.AssertDebug(assetLoader != null); Log.EngineLogger.AssertDebug(assetLoader != null);
Stream stream = GetStream(filePath); Stream stream = GetStream(filePath);
@@ -389,14 +336,9 @@ class EditorContentManager : IContentManager
if (loadedAsset == null) if (loadedAsset == null)
return .Invalid; return .Invalid;
//String identifierString = new .(identifier); loadedAsset.Identifier = fixedIdentifier;
//_identifiers.Add(identifierString);
//_loadedAssets[identifierString] = loadedAsset;
loadedAsset.Identifier = identifier;
AssetHandle handle = ManageAsset(loadedAsset); AssetHandle handle = ManageAsset(loadedAsset);
// ManageAsset increases RefCount // ManageAsset increases RefCount, but this scope also holds a reference.
loadedAsset.ReleaseRef(); loadedAsset.ReleaseRef();
// Add to Identifier -> Handle map // Add to Identifier -> Handle map
@@ -428,25 +370,40 @@ class EditorContentManager : IContentManager
return assetLoader; return assetLoader;
} }
/// Saves the asset. public enum SaveAssetError
public Result<void> SaveAsset(Asset asset)
{ {
// Find subasset name case Unknown;
int poundIndex = asset.Identifier.IndexOf('#'); case Unsavable;
case PathNotFound;
}
StringView resourceName = poundIndex == -1 ? asset.Identifier : asset.Identifier.Substring(0, poundIndex); /// Saves the asset.
StringView? subassetName = asset.Identifier.Substring(poundIndex + 1); public Result<void, SaveAssetError> SaveAsset(Asset asset)
{
if (asset == null)
return .Err(.Unknown);
String filePath = scope String(resourceName.Length + _contentDirectory.Length + 2); if (asset.Identifier.IsWhiteSpace)
Path.Combine(filePath, _contentDirectory, resourceName); return .Err(.Unsavable);
Path.Fixup(filePath); GetResourceAndSubassetName(asset.Identifier, let resourceName, let subassetName);
//filePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); if (subassetName != null)
{
// TODO: should this ever be allowed? Couldn't we just save the entire asset?
// Would this ever be necessary?
Runtime.NotImplemented("Saving subassets is not currently allowed");
}
TreeNode<AssetNode> assetNode = Try!(AssetHierarchy.GetNodeFromPath(filePath)); String filePath = scope String();
GetResourceFilePath(resourceName, filePath);
AssetFile file = assetNode->AssetFile; Result<TreeNode<AssetNode>> assetNode = AssetHierarchy.GetNodeFromPath(filePath);
if (assetNode case .Err)
return .Err(.PathNotFound);
AssetFile file = assetNode.Get()->AssetFile;
IAssetLoader assetLoader = GetAssetLoader(file); IAssetLoader assetLoader = GetAssetLoader(file);
@@ -455,20 +412,22 @@ class EditorContentManager : IContentManager
if (assetSaver == null) if (assetSaver == null)
{ {
Log.EngineLogger.Error("The asset loader can't save!"); Log.EngineLogger.Error("The asset loader can't save!");
return .Err; return .Err(.Unsavable);
} }
Stream stream = OpenStream(filePath, false, true); Stream stream = OpenStream(filePath, false);
assetSaver.EditorSaveAsset(stream, asset, file.AssetConfig.Config, resourceName, subassetName, this); assetSaver.EditorSaveAsset(stream, asset, file.AssetConfig.Config, resourceName, subassetName, this);
// Trim off the end of the file.
stream.SetLength(stream.Position); stream.SetLength(stream.Position);
delete stream; delete stream;
return .Ok; return .Ok;
} }
private Stream OpenStream(StringView assetIdentifier, bool openOnly, bool truncate = false) private Stream OpenStream(StringView assetIdentifier, bool openOnly)
{ {
var assetIdentifier; var assetIdentifier;
@@ -484,9 +443,6 @@ class EditorContentManager : IContentManager
FileMode fileMode = openOnly ? FileMode.Open : FileMode.OpenOrCreate; FileMode fileMode = openOnly ? FileMode.Open : FileMode.OpenOrCreate;
/*if (truncate)
fileMode |= .Truncate;*/
var result = fs.Open(assetIdentifier, fileMode, openOnly ? .Read : .ReadWrite, .ReadWrite); var result = fs.Open(assetIdentifier, fileMode, openOnly ? .Read : .ReadWrite, .ReadWrite);
if (result case .Err) if (result case .Err)