Start of asset handles

This commit is contained in:
Simon Lübeß
2023-03-13 20:35:30 +01:00
parent ad14c9f6ed
commit c22d122921
10 changed files with 370 additions and 60 deletions
+2
View File
@@ -34,6 +34,8 @@ namespace GlitchyEngine
public bool IsMinimized => _isMinimized;
public GameTime GameTime => _gameTime;
[Inline]
public static Application Get() => s_Instance;
+10 -3
View File
@@ -10,6 +10,8 @@ namespace GlitchyEngine.Content;
[BonTarget]
class Asset : RefCounter
{
internal AssetHandle _handle;
private append String _identifier;
internal IContentManager _contentManager;
@@ -33,6 +35,8 @@ class Asset : RefCounter
/// Gets the content manager that manages this asset; or null if this asset isn't managed.
public IContentManager ContentManager => _contentManager;
public AssetHandle Handle => _handle;
static this
{
gBonEnv.typeHandlers.Add(typeof(Asset),
@@ -43,7 +47,7 @@ class Asset : RefCounter
{
// TODO: crash when _contentManager is deleted first...
// TODO: unregister from content manager
_contentManager?.UnmanageAsset(this);
//_contentManager?.UnmanageAsset(this);
}
static void AssetSerialize(BonWriter writer, ValueView value, BonEnvironment environment, SerializeValueState state)
@@ -56,7 +60,10 @@ class Asset : RefCounter
static Result<void> AssetDeserialize(BonReader reader, ValueView value, BonEnvironment environment, DeserializeValueState state)
{
Log.EngineLogger.Assert(value.type == typeof(Asset));
// TODO!!!
return .Err;
/*Log.EngineLogger.Assert(value.type == typeof(Asset));
String identifier = scope .();
@@ -75,7 +82,7 @@ class Asset : RefCounter
else
{
Deserialize.Error!("Invalid resource path", reader, value.type);
}
}*/
}
//gBonEnv.typeHandlers.Add(typeof(Resource<>),
+211
View File
@@ -0,0 +1,211 @@
using System;
using xxHash;
using System.Collections;
using System.Reflection;
using System.Diagnostics;
namespace GlitchyEngine.Content;
struct AssetHandle : uint64
{
/// Defines an asset that is invalid. E.g. because it couldn't be loaded.
public const AssetHandle Invalid = (.)0;
public this(StringView name)
{
this = (uint64)xxHash.ComputeHash(name);
}
[Inline]
public T Get<T>(IContentManager contentManager = null) where T : Asset
{
return Content.GetAsset<T>(this, contentManager);
}
}
struct AssetHandle<T> where T : Asset
{
private AssetHandle _handle;
private IContentManager _contentManager;
/*
* We don't increment/decrement the reference counter since we guarantee that we query for the asset every frame.
*/
private T _asset;
private uint8 _currentFrame;
public this(AssetHandle handle, IContentManager contentManager = null)
{
_handle = handle;
_contentManager = contentManager;
_asset = handle.Get<T>(contentManager);
_contentManager = _asset.ContentManager;
_currentFrame = (uint8)Application.Get().GameTime.FrameCount;
}
public T Get(IContentManager contentManager = null) mut
{
// We only care whether we are in a different frame -> we only compare the lower 8 bits.
uint8 actualFrame = (uint8)Application.Get().GameTime.FrameCount;
if (actualFrame != _currentFrame)
{
_asset = Content.GetAsset<T>(_handle, contentManager == null ? _contentManager : contentManager);
}
return _asset;
}
[Comptime, OnCompile(.TypeInit)]
static void Init()
{
for (var field in typeof(T).GetFields())
{
if (field.IsStatic || !field.IsPublic)
continue;
String modifier = field.IsPublic ? "public" : "private";
String code = scope $"""
{modifier} {field.FieldType} {field.Name}
{{
get mut
{{
return Get().{field.Name};
}}
set mut
{{
Get().{field.Name} = value;
}}
}}
""";
Compiler.EmitTypeBody(typeof(Self), code);
}
Dictionary<StringView, (MethodInfo? Getter, MethodInfo? Setter)> properties = scope .();
for (var method in typeof(T).GetMethods())
{
if (method.IsStatic || !method.IsPublic || method.IsConstructor || method.IsDestructor)
continue;
// Filter out destructors
if (method.Name == "~this")
continue;
if (method.Name.StartsWith("get__"))
{
StringView name = method.Name;
name.RemoveFromStart(5);
if (!properties.TryGetValue(name, var propertyInfo))
{
propertyInfo = default;
}
propertyInfo.Getter = method;
properties[name] = propertyInfo;
continue;
}
if (method.Name.StartsWith("set__"))
{
StringView name = method.Name;
name.RemoveFromStart(5);
if (!properties.TryGetValue(name, var propertyInfo))
{
propertyInfo = default;
}
propertyInfo.Setter = method;
properties[name] = propertyInfo;
continue;
}
String modifier = method.IsPublic ? "public" : "private";
String parameters = scope String();
String arguments = scope String();
for (int param < method.ParamCount)
{
Type paramType = method.GetParamType(param);
StringView paramName = method.GetParamName(param);
//String buffer = scope .();
//method.GetParamsDecl(buffer);
if (param != 0)
{
parameters.Append(", ");
arguments.Append(", ");
}
// TODO: Default value
parameters.AppendF($"{paramType} {paramName}");
/*if (!buffer.IsEmpty)
{
parameters.AppendF($" = {buffer}");
}*/
arguments.AppendF($" {paramName}");
}
String code = scope $"""
{modifier} {method.ReturnType} {method.Name}({parameters}) mut
{{
return Get().{method.Name}({arguments});
}}
""";
Compiler.EmitTypeBody(typeof(Self), code);
}
for (var (propertyName, property) in properties)
{
Type propertyType = property.Getter?.ReturnType ?? property.Setter?.GetParamType(0);
String getter = scope .();
String setter = scope .();
if (property.Getter != null)
{
getter.AppendF($"""
get mut
{{
return Get().{propertyName};
}}
""");
}
if (property.Setter != null)
{
getter.AppendF($"""
set mut
{{
Get().{propertyName} = value;
}}
""");
}
String code = scope $"""
public {propertyType} {propertyName}
{{
{getter}{setter}
}}
""";
Compiler.EmitTypeBody(typeof(Self), code);
}
}
}
+36 -11
View File
@@ -59,19 +59,30 @@ namespace GlitchyEngine.Content
Asset LoadAsset(Stream file, AssetLoaderConfig config, StringView assetIdentifier, StringView? subAsset, IContentManager contentManager);
}
static
static class Content
{
/// Loads the specified asset with the given contentManager or the current applications content manager.
public static T LoadAsset<T>(StringView assetIdentifier, IContentManager contentManager = null) where T : Asset
public static AssetHandle LoadAsset(StringView assetIdentifier, IContentManager contentManager = null)
{
var contentManager;
if (contentManager == null)
contentManager = Application.Get().ContentManager;
Asset asset = contentManager.LoadAsset(assetIdentifier);
AssetHandle handle = contentManager.LoadAsset(assetIdentifier);
Log.EngineLogger.AssertDebug(asset is T);
return handle;
}
/// Loads the specified asset with the given contentManager or the current applications content manager.
public static T GetAsset<T>(AssetHandle handle, IContentManager contentManager = null) where T : Asset
{
var contentManager;
if (contentManager == null)
contentManager = Application.Get().ContentManager;
Asset asset = contentManager.GetAsset(typeof(T), handle);
return (T)asset;
}
@@ -79,14 +90,23 @@ namespace GlitchyEngine.Content
interface IContentManager
{
/// Loads the given asset.
Asset LoadAsset(StringView assetIdentifier);
/// Loads the Asset with the given handle and returns the handle.
AssetHandle LoadAsset(StringView assetIdentifier);
/// Returns the asset for the given handle or null, if it isn't loaded.
Asset GetAsset(AssetHandle handle)
{
return GetAsset(null, handle);
}
/// Returns the asset for the given handle or the default asset of the given type.
Asset GetAsset(Type assetType, AssetHandle handle);
/// The content manager will manage the asset (e.g. provide it when LoadAsset is called with the assets identifier)
void ManageAsset(Asset asset);
AssetHandle ManageAsset(Asset asset);
/// The content manager will no longer manage the asset.
void UnmanageAsset(Asset asset);
void UnmanageAsset(AssetHandle asset);
// TODO: Maybe calling UnmanageAsset -> ManageAsset is enough....
/// Provides a method for the asset to tell its content manager that the identifer changed.
@@ -109,17 +129,22 @@ namespace GlitchyEngine.Content
Runtime.NotImplemented();
}
public Asset LoadAsset(StringView assetIdentifier)
public AssetHandle LoadAsset(StringView assetIdentifier)
{
Runtime.NotImplemented();
}
public void ManageAsset(Asset asset)
public Asset GetAsset(Type assetType, AssetHandle handle)
{
Runtime.NotImplemented();
}
public void UnmanageAsset(Asset asset)
public AssetHandle ManageAsset(Asset asset)
{
Runtime.NotImplemented();
}
public void UnmanageAsset(AssetHandle asset)
{
Runtime.NotImplemented();
}
@@ -20,11 +20,10 @@ namespace GlitchyEngine.Generators
outFileName.Append(name);
outText.AppendF(
$"""
namespace {Namespace}
namespace {Namespace};
struct {name}
{{
struct {name}
{{
}}
}}
""");
}
+15 -2
View File
@@ -134,7 +134,20 @@ public class Effect : Asset
BufferVariableCollection _variables ~ delete _;
typealias TextureEntry = (TextureViewBinding BoundTexture, ShaderTextureCollection.ResourceEntry* VsSlot, ShaderTextureCollection.ResourceEntry* PsSlot);
public struct TextureEntry
{
public TextureViewBinding BoundTexture;
public ShaderTextureCollection.ResourceEntry* VsSlot;
public ShaderTextureCollection.ResourceEntry* PsSlot;
public this(TextureViewBinding boundTexture, ShaderTextureCollection.ResourceEntry* vsSlot, ShaderTextureCollection.ResourceEntry* psSlot)
{
BoundTexture = boundTexture;
VsSlot = vsSlot;
PsSlot = psSlot;
}
}
Dictionary<String, TextureEntry> _textures ~ delete _;
public Dictionary<String, TextureEntry> Textures => _textures;
@@ -725,7 +738,7 @@ public class Effect : Asset
// Get existing entry or create new
if(!_textures.TryGetValue(shaderEntry.Name, out entry))
{
entry = (shaderEntry.BoundTexture, null, null);
entry = .(shaderEntry.BoundTexture, null, null);
entry.BoundTexture.AddRef();
}
+1
View File
@@ -2,6 +2,7 @@ using GlitchyEngine.Math;
using GlitchyEngine.World;
using System.Collections;
using System;
using GlitchyEngine.Content;
namespace GlitchyEngine.Renderer
{
+14 -10
View File
@@ -24,7 +24,7 @@ namespace GlitchyEngine.World
// Temporary target for camera. Needs to change as soon as we support multiple cameras
private RenderTargetGroup _cameraTarget ~ _.ReleaseRef();
private Effect _gammaCorrectEffect ~ _.ReleaseRef();
private AssetHandle _gammaCorrectEffect;
// Maps ids to the entities they represent.
private Dictionary<UUID, EcsEntity> _idToEntity = new .() ~ delete _;
@@ -76,7 +76,7 @@ namespace GlitchyEngine.World
DepthTargetDescription = .(.D24_UNorm_S8_UInt)
});
_gammaCorrectEffect = Content.LoadAsset<Effect>("Shaders/GammaCorrect.hlsl");//Application.Get().EffectLibrary.Load("content/Shaders/GammaCorrect.hlsl");
_gammaCorrectEffect = Content.LoadAsset("Shaders/GammaCorrect.hlsl");//Application.Get().EffectLibrary.Load("content/Shaders/GammaCorrect.hlsl");
}
public ~this()
@@ -268,11 +268,13 @@ namespace GlitchyEngine.World
RenderCommand.UnbindRenderTargets();
RenderCommand.SetRenderTargetGroup(finalTarget, false);
RenderCommand.BindRenderTargets();
_gammaCorrectEffect.SetTexture("Texture", _compositeTarget, 0);
Effect gammaEffect = Content.GetAsset<Effect>(_gammaCorrectEffect);
gammaEffect.SetTexture("Texture", _compositeTarget, 0);
// TODO: iiihhh
_gammaCorrectEffect.ApplyChanges();
_gammaCorrectEffect.Bind();
gammaEffect.ApplyChanges();
gammaEffect.Bind();
FullscreenQuad.Draw();
}
@@ -485,11 +487,13 @@ namespace GlitchyEngine.World
RenderCommand.UnbindRenderTargets();
RenderCommand.SetRenderTargetGroup(viewportTarget, false);
RenderCommand.BindRenderTargets();
_gammaCorrectEffect.SetTexture("Texture", _compositeTarget, 0);
Effect gammaEffect = Content.GetAsset<Effect>(_gammaCorrectEffect);
gammaEffect.SetTexture("Texture", _compositeTarget, 0);
// TODO: iiihhh
_gammaCorrectEffect.ApplyChanges();
_gammaCorrectEffect.Bind();
gammaEffect.ApplyChanges();
gammaEffect.Bind();
FullscreenQuad.Draw();
}