// Copyright (c) Wojciech Figat. All rights reserved. #pragma once #include "Asset.h" #include "Engine/Core/ISerializable.h" #include "Engine/Serialization/Json.h" /// /// Base class for all Json-format assets. /// /// API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API JsonAssetBase : public Asset { DECLARE_SCRIPTING_TYPE_NO_SPAWN(JsonAssetBase); protected: String _path; bool _isVirtualDocument = false; bool _isResaving = false; protected: /// /// Initializes a new instance of the class. /// /// The object initialization parameters. /// The asset object information. explicit JsonAssetBase(const SpawnParams& params, const AssetInfo* info); public: /// /// The parsed json document. /// ISerializable::SerializeDocument Document; /// /// The data node (reference from Document or Document itself). /// ISerializable::DeserializeStream* Data; /// /// The data type name from the header. Allows to recognize the data type. /// API_FIELD(ReadOnly) String DataTypeName; /// /// The serialized data engine build number. Can be used to convert/upgrade data between different formats across different engine versions. /// API_FIELD(ReadOnly) int32 DataEngineBuild; /// /// The Json data (as string). /// API_PROPERTY() String GetData() const; /// /// The Json data (as string). /// API_PROPERTY() void SetData(const StringView& value); /// /// Initializes the virtual Json asset with custom data. /// /// Can be used only for virtual assets created at runtime. /// The data type name from the header. Allows to recognize the data type. /// The Json with serialized data. /// True if failed, otherwise false. API_FUNCTION() bool Init(const StringView& dataTypeName, const StringAnsiView& dataJson); #if USE_EDITOR /// /// Parses Json string to find any object references inside it. It can produce list of references to assets and/or scene objects. Supported only in Editor. /// /// The Json string. /// The output list of object IDs references by the asset (appended, not cleared). API_FUNCTION() static void GetReferences(const StringAnsiView& json, API_PARAM(Out) Array& assets); /// /// Saves this asset to the Json Writer buffer (both ID, Typename header and Data contents). Supported only in Editor. /// /// The output Json Writer to write asset. /// True if cannot save data, otherwise false. bool Save(JsonWriter& writer) const; #endif protected: // Gets the serialized Json data (from runtime state). virtual void OnGetData(rapidjson_flax::StringBuffer& buffer) const; public: // [Asset] StringView GetPath() const override; uint64 GetMemoryUsage() const override; #if USE_EDITOR void GetReferences(Array& assets, Array& files) const override; bool Save(const StringView& path = StringView::Empty) override; #endif protected: // [Asset] LoadResult loadAsset() override; void unload(bool isReloading) override; #if USE_EDITOR void onRename(const StringView& newPath) override; bool saveInternal(JsonWriter& writer) const; #endif }; /// /// Generic type of Json-format asset. It provides the managed representation of this resource data so it can be accessed via C# API. /// /// API_CLASS(NoSpawn) class FLAXENGINE_API JsonAsset : public JsonAssetBase { DECLARE_ASSET_HEADER(JsonAsset); private: ScriptingType::Dtor _dtor; bool _isAfterReload = false; public: /// /// The scripting type of the deserialized unmanaged object instance (e.g. PhysicalMaterial). /// ScriptingTypeHandle InstanceType; /// /// The deserialized unmanaged object instance (e.g. PhysicalMaterial). Might be null if asset was loaded before binary module with that asset was loaded (use GetInstance for this case). /// void* Instance; /// /// Gets the deserialized native object instance of the given type. Returns null if asset is not loaded or loaded object has different type. /// /// The asset instance object or null. template T* GetInstance() const { const_cast(this)->CreateInstance(); const ScriptingTypeHandle& type = T::TypeInitializer; return Instance && type.IsAssignableFrom(InstanceType) ? (T*)Instance : nullptr; } public: // [JsonAssetBase] uint64 GetMemoryUsage() const override; protected: // [JsonAssetBase] void OnGetData(rapidjson_flax::StringBuffer& buffer) const override; LoadResult loadAsset() override; void unload(bool isReloading) override; void onLoaded_MainThread() override; private: bool CreateInstance(); void DeleteInstance(); #if USE_EDITOR void OnScriptsReloadStart(); void OnScriptsReloaded(); #endif };