diff --git a/GlitchyEditor/src/Assets/MaterialAssetLoader.bf b/GlitchyEditor/src/Assets/MaterialAssetLoader.bf index 45b3b23..b64c1f3 100644 --- a/GlitchyEditor/src/Assets/MaterialAssetLoader.bf +++ b/GlitchyEditor/src/Assets/MaterialAssetLoader.bf @@ -469,7 +469,7 @@ class MaterialAssetLoader : IAssetLoader, IAssetSaver //, IReloadingAssetLoader MaterialFile materialFile = scope .(); - materialFile.Effect = new String(material.Effect.Identifier); + materialFile.Effect = new String(material.Effect?.Identifier ?? ""); materialFile.Textures = new .(); materialFile.Variables = new .(); @@ -482,59 +482,59 @@ class MaterialAssetLoader : IAssetLoader, IAssetSaver //, IReloadingAssetLoader Effect effect = material.Effect; - if (effect == null) - return .Ok; - - for (let (name, arguments) in effect.[Friend]_variableDescriptions) + if (effect != null) { - VariableValue variableValue = .None; - - let variable = effect.Variables[name]; - - bool hasPreviewType = MaterialAssetPropertiesEditor.TryGetValue(arguments, "Type", var previewType); - - if (hasPreviewType && previewType.Get() == "Color") + for (let (name, arguments) in effect.[Friend]_variableDescriptions) { - Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1); - - if (variable.Columns == 3) + VariableValue variableValue = .None; + + let variable = effect.Variables[name]; + + bool hasPreviewType = MaterialAssetPropertiesEditor.TryGetValue(arguments, "Type", var previewType); + + if (hasPreviewType && previewType.Get() == "Color") { - material.GetVariable(variable.Name, var value); - - value = ColorRGB.LinearToSRGB((ColorRGB)value); - - //variantValue = new box value; - variableValue = .ColorRGB(value); + Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1); + + if (variable.Columns == 3) + { + material.GetVariable(variable.Name, var value); + + value = ColorRGB.LinearToSRGB((ColorRGB)value); + + //variantValue = new box value; + variableValue = .ColorRGB(value); + } + else if (variable.Columns == 4) + { + material.GetVariable(variable.Name, var value); + + value = ColorRGBA.LinearToSRGB((ColorRGBA)value); + + variableValue = .ColorRGBA(value); + } } - else if (variable.Columns == 4) + else if (variable.Type == .Float && variable.Rows == 1) { - material.GetVariable(variable.Name, var value); - - value = ColorRGBA.LinearToSRGB((ColorRGBA)value); - - variableValue = .ColorRGBA(value); + switch (variable.Columns) + { + case 1: + material.GetVariable(variable.Name, let value); + variableValue = .Float(value); + case 2: + material.GetVariable(variable.Name, let value); + variableValue = .Float2(value); + case 3: + material.GetVariable(variable.Name, let value); + variableValue = .Float3(value); + case 4: + material.GetVariable(variable.Name, let value); + variableValue = .Float4(value); + } } + + materialFile.Variables.Add(new String(name), variableValue); } - else if (variable.Type == .Float && variable.Rows == 1) - { - switch (variable.Columns) - { - case 1: - material.GetVariable(variable.Name, let value); - variableValue = .Float(value); - case 2: - material.GetVariable(variable.Name, let value); - variableValue = .Float2(value); - case 3: - material.GetVariable(variable.Name, let value); - variableValue = .Float3(value); - case 4: - material.GetVariable(variable.Name, let value); - variableValue = .Float4(value); - } - } - - materialFile.Variables.Add(new String(name), variableValue); } String text = scope .(); diff --git a/GlitchyEditor/src/EditorContentManager.bf b/GlitchyEditor/src/EditorContentManager.bf index dd2fc76..e5a9ce4 100644 --- a/GlitchyEditor/src/EditorContentManager.bf +++ b/GlitchyEditor/src/EditorContentManager.bf @@ -281,7 +281,7 @@ class EditorContentManager : IContentManager IAssetLoader assetLoader = GetAssetLoader(file); - Stream stream = GetStream(filePath); + Stream stream = GetStream(filePath, true); // TODO: Add async loading! Asset loadedAsset = assetLoader.LoadAsset(stream, file.AssetConfig.Config, resourceName, subassetName, this); @@ -488,10 +488,7 @@ class EditorContentManager : IContentManager Runtime.NotImplemented("Saving subassets is not currently allowed"); } - String filePath = scope String(); - GetResourceFilePath(resourceName, filePath); - - Result> assetNode = AssetHierarchy.GetNodeFromPath(filePath); + Result> assetNode = AssetHierarchy.GetNodeFromIdentifier(asset.Identifier); if (assetNode case .Err) return .Err(.PathNotFound); @@ -508,7 +505,7 @@ class EditorContentManager : IContentManager return .Err(.Unsavable); } - Stream stream = OpenStream(filePath, false); + Stream stream = GetStream(asset.Identifier, false); assetSaver.EditorSaveAsset(stream, asset, file.AssetConfig.Config, resourceName, subassetName, this); @@ -520,13 +517,81 @@ class EditorContentManager : IContentManager return .Ok; } - private Stream OpenStream(StringView fileName, bool openOnly) + /// Saves the asset. + public Result SaveAssetToFile(Asset asset, StringView fileName) + { + if (asset == null) + return .Err(.Unknown); + + //if (asset.Identifier.IsWhiteSpace) + // return .Err(.Unsavable); + + String fileAssetName = scope .(); + + Path.GetFileNameWithoutExtension(fileName, fileAssetName); + + StringView assetName = fileAssetName; + StringView? subassetName = null; + + if (!asset.Identifier.IsWhiteSpace) + GetResourceAndSubassetName(asset.Identifier, out assetName, out subassetName); + + //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"); + //} + + //Result> assetNode = AssetHierarchy.GetNodeFromIdentifier(asset.Identifier); + + //if (assetNode case .Err) + // return .Err(.PathNotFound); + + //AssetFile file = assetNode.Get()->AssetFile; + + String fileExtension = scope .(); + Path.GetExtension(fileName, fileExtension); + + IAssetLoader assetLoader = GetDefaultAssetLoader(fileExtension);//GetAssetLoader(asset.GetType()); + + if (assetLoader == null) + { + Log.EngineLogger.Error($"No asset loader found for extension {fileExtension}!"); + return .Err(.Unsavable); + } + + IAssetSaver assetSaver = assetLoader as IAssetSaver; + + if (assetSaver == null) + { + Log.EngineLogger.Error("The asset loader can't save!"); + return .Err(.Unsavable); + } + + Stream stream = OpenStream(fileName, false); + + var config = assetLoader.GetDefaultConfig(); + + assetSaver.EditorSaveAsset(stream, asset, config, assetName, subassetName, this); + + delete config; + + // Trim off the end of the file. + stream.SetLength(stream.Position); + + delete stream; + + return .Ok; + } + + private Stream OpenStream(StringView fileName, bool readOnly) { FileStream fs = new FileStream(); - FileMode fileMode = openOnly ? FileMode.Open : FileMode.OpenOrCreate; + FileMode fileMode = readOnly ? FileMode.Open : FileMode.OpenOrCreate; - var result = fs.Open(fileName, fileMode, openOnly ? .Read : .ReadWrite, .ReadWrite); + var result = fs.Open(fileName, fileMode, readOnly ? .Read : .ReadWrite, .ReadWrite); if (result case .Err) return null; @@ -535,7 +600,7 @@ class EditorContentManager : IContentManager } /// Returns a file stream for the given assetIdentifier - public Stream GetStream(StringView assetIdentifier) + public Stream GetStream(StringView assetIdentifier, bool readOnly) { String fixuppedIdentifier = scope .(assetIdentifier); AssetIdentifier.Fixup(fixuppedIdentifier); @@ -548,7 +613,7 @@ class EditorContentManager : IContentManager return null; } - return OpenStream(node->Value.Path, true); + return OpenStream(node->Value.Path, readOnly); } public AssetHandle ManageAsset(Asset asset) diff --git a/GlitchyEditor/src/EditorLayer.bf b/GlitchyEditor/src/EditorLayer.bf index e696525..c5e8c38 100644 --- a/GlitchyEditor/src/EditorLayer.bf +++ b/GlitchyEditor/src/EditorLayer.bf @@ -151,6 +151,14 @@ namespace GlitchyEditor SaveScene(newScene, path); } })); + + Editor.Instance.ContentBrowserWindow.RegisterAssetCreator(new AssetCreator("Material", "New Material.mat", new (path) => + { + using (Material newMaterial = new Material()) + { + _contentManager.SaveAssetToFile(newMaterial, path); + } + })); } private void InitGraphics() diff --git a/GlitchyEngine/src/Content/ContentManager.bf b/GlitchyEngine/src/Content/ContentManager.bf index 16c16ad..0a83026 100644 --- a/GlitchyEngine/src/Content/ContentManager.bf +++ b/GlitchyEngine/src/Content/ContentManager.bf @@ -135,7 +135,7 @@ namespace GlitchyEngine.Content void UnmanageAsset(AssetHandle asset); /// Returns a data stream for the given asset. - Stream GetStream(StringView assetIdentifier); + Stream GetStream(StringView assetIdentifier, bool openOnly = true); void RegisterAssetLoader() where T : new, class, IAssetLoader; void SetAsDefaultAssetLoader(params Span fileExtensions) where T : IAssetLoader; @@ -143,81 +143,4 @@ namespace GlitchyEngine.Content //Stream GetFile(String filename); } - - class RuntimeContentManager : IContentManager - { - public this() - { - Runtime.NotImplemented(); - } - - public AssetHandle LoadAsset(StringView assetIdentifier, bool blocking = false) - { - Runtime.NotImplemented(); - } - - public Asset GetAsset(Type assetType, AssetHandle handle) - { - Runtime.NotImplemented(); - } - - public AssetHandle ManageAsset(Asset asset) - { - Runtime.NotImplemented(); - } - - public void UnmanageAsset(AssetHandle asset) - { - Runtime.NotImplemented(); - } - - public Stream GetStream(StringView assetIdentifier) - { - Runtime.NotImplemented(); - } - - public void RegisterAssetLoader() where T : IAssetLoader where T : class where T : new - { - Runtime.NotImplemented(); - } - - public void SetAsDefaultAssetLoader(params Span fileExtensions) where T : IAssetLoader - { - Runtime.NotImplemented(); - } - /*private String _contentRoot; - - [AllowAppend] - public this(String contentRoot) - { - String cntRoot = append String(contentRoot); - _contentRoot = cntRoot; - - Runtime.Assert(Directory.Exists(contentRoot), "Content root directory doesn't exist."); - } - - public void GetFilePath(String outFilename, String filename) - { - Path.InternalCombine(outFilename, _contentRoot, filename); - } - - public Stream GetFile(String filename) - { - String fullpath = scope .(_contentRoot.Length + 1 + filename.Length); - GetFilePath(fullpath, filename); - - Log.EngineLogger.AssertDebug(File.Exists(fullpath), "File doesn't exist!"); - - FileStream stream = new FileStream(); - var result = stream.Open(fullpath, .Read, .Read); - - if (result case .Err(let error)) - { - Log.EngineLogger.Error($"Failed to open file \"{fullpath}\". Error: {error}"); - return null; - } - - return stream; - }*/ - } } \ No newline at end of file diff --git a/GlitchyEngine/src/Renderer/Material.bf b/GlitchyEngine/src/Renderer/Material.bf index e074f22..ca85c87 100644 --- a/GlitchyEngine/src/Renderer/Material.bf +++ b/GlitchyEngine/src/Renderer/Material.bf @@ -51,7 +51,7 @@ public class Material : Asset textureHandle = .Invalid; } - _textures[new String(name)] = (textureHandle, effectTexture.TextureDimension); + newTextures[new String(name)] = (textureHandle, effectTexture.TextureDimension); } DeleteDictionaryAndKeys!(_textures);