using GlitchyEngine.Core; using System; using Bon; using Bon.Integrated; using System.Reflection; using System.IO; namespace GlitchyEngine.Content; [BonTarget] abstract class Asset : RefCounter { internal AssetHandle _handle = .Invalid; private append String _identifier; internal IContentManager _contentManager; /// Gets the identifier of this asset. /// @remarks The identifier is the name with which the asset was registered in the content manager. /// This identifier can be used to request the Asset from the content manager. public StringView Identifier { get => _identifier; set => _identifier.Set(value); } /// If true the asset is completely loaded. If false it is only partially loaded (if at all). public bool Complete { get; internal set; } // TODO: do we need unmanaged assets? Probably not... /// 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), ((.)new => AssetSerialize, new => AssetDeserialize)); } protected this() { Content.ManageAsset(this); } //protected ~this() //{ // TODO: crash when _contentManager is deleted first... // TODO: unregister from content manager //_contentManager?.UnmanageAsset(this); //} static void AssetSerialize(BonWriter writer, ValueView value, BonEnvironment environment, SerializeValueState state) { Log.EngineLogger.Assert(value.type == typeof(Asset)); var handle = value.Get()._handle; Serialize.Value(writer, handle, environment); //AssetHandle.[Friend]AssetSerialize(writer, ValueView(typeof(AssetHandle), &handle), environment, state); //writer.String(identifier); } static Result AssetDeserialize(BonReader reader, ValueView value, BonEnvironment environment, DeserializeValueState state) { Log.EngineLogger.Assert(value.type == typeof(Asset)); Try!(Deserialize.Value(reader, let handle, environment)); //String identifier = scope .(); //Deserialize.String!(reader, ref identifier, environment); AssetHandle loadedHandle = Content.LoadAsset(handle); if (loadedHandle == .Invalid) { value.Assign(null); return .Ok; } Asset asset = Content.GetAsset(handle); if (asset != null) { Asset oldAsset = value.Get(); oldAsset.ReleaseRef(); value.Assign(asset); return .Ok; } else { Deserialize.Error!("Invalid resource path", reader, value.type); } /*String identifier = scope .(); Deserialize.String!(reader, ref identifier, environment); AssetHandle handle = Content.LoadAsset(identifier); if (handle == .Invalid) { value.Assign(null); return .Ok; } Asset asset = Content.GetAsset(handle); if (asset != null) { Asset oldAsset = value.Get(); oldAsset.ReleaseRef(); value.Assign(asset); return .Ok; } else { Deserialize.Error!("Invalid resource path", reader, value.type); }*/ } //gBonEnv.typeHandlers.Add(typeof(Resource<>), // ((.)new => ResourceSerialize, (.)new => ResourceDeserialize)); }