| 1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
| 2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
| 3 | #pragma once |
| 4 | |
| 5 | #include "BsPrerequisites.h" |
| 6 | #include "ThirdParty/json.hpp" |
| 7 | #include "GUI/BsGUIElementStyle.h" |
| 8 | |
| 9 | namespace bs |
| 10 | { |
| 11 | /** @addtogroup Resources-Engine-Internal |
| 12 | * @{ |
| 13 | */ |
| 14 | |
| 15 | class GUIElementStyleLoader; |
| 16 | |
| 17 | /** Provides various methods commonly used for managing builtin resources. */ |
| 18 | class BS_EXPORT BuiltinResourcesHelper |
| 19 | { |
| 20 | public: |
| 21 | /** Flags that can control asset import. */ |
| 22 | enum class AssetType |
| 23 | { |
| 24 | /** No flags, just import asset as normal. Each entry is expected to have an "UUID" and a "Path" field. */ |
| 25 | Normal, |
| 26 | /** |
| 27 | * Assumes imported assets are textures. Will generate sprite assets for each imported texture. Expects |
| 28 | * "TextureUUID", "Path" and "SpriteUUID" fields present in per-entry JSON. |
| 29 | */ |
| 30 | Sprite, |
| 31 | }; |
| 32 | |
| 33 | /** |
| 34 | * Iterates over all entires in the provided json file, imports the files linked by the entries them and stores them |
| 35 | * in the corresponding folder. Also registers the imported files in the provided manifest. |
| 36 | * |
| 37 | * @param[in] entries JSON array containing the entries to parse, with each entry containing |
| 38 | * data determine by set ImportMode. |
| 39 | * @param[in] importFlags A set of import flags (one for each entry) that specify which entries need to be |
| 40 | * imported. |
| 41 | * @param[in] inputFolder Folder in which to look for the input files. |
| 42 | * @param[in] outputFolder Folder in which to store the imported resources. |
| 43 | * @param[in] manifest Manifest in which to register the imported resources in. |
| 44 | * @param[in] mode Mode that controls how are files imported. |
| 45 | * @param[in] dependencies Optional map that be updated with any dependencies the imported assets depend on. |
| 46 | * @param[in] compress True if the imported asset should be compressed when saved to the disk. |
| 47 | * @param[in] mipmap True if mipmaps should be generated. |
| 48 | */ |
| 49 | static void (const nlohmann::json& entries, const Vector<bool>& importFlags, const Path& inputFolder, |
| 50 | const Path& outputFolder, const SPtr<ResourceManifest>& manifest, AssetType mode = AssetType::Normal, |
| 51 | nlohmann::json* dependencies = nullptr, bool compress = false, bool mipmap = false); |
| 52 | |
| 53 | /** |
| 54 | * Imports a font from the specified file. Imported font assets are saved in the output folder. All saved resources |
| 55 | * are registered in the provided resource manifest. |
| 56 | */ |
| 57 | static void importFont(const Path& inputFile, const String& outputName, const Path& outputFolder, |
| 58 | const Vector<UINT32>& fontSizes, bool antialiasing, const UUID& UUID, const SPtr<ResourceManifest>& manifest); |
| 59 | |
| 60 | /** |
| 61 | * Iterates over all the provided entries and generates a list of flags that determine should the asset be imported |
| 62 | * or not. This is done by comparing file modification dates with the last update time and/or checking if any |
| 63 | * dependencies require import. |
| 64 | * |
| 65 | * @param[in] entries JSON array containing entries to iterate over. |
| 66 | * @param[in] inputFolder Folder in which to look for the input files. |
| 67 | * @param[in] lastUpdateTime Timestamp of when the last asset import occurred. |
| 68 | * @param[in] forceImport If true, all entries will be marked for import. |
| 69 | * @param[in] dependencies Optional map of entries that map each entry in the @p entries array, to a list |
| 70 | * of dependencies. The dependencies will then also be checked for modifications |
| 71 | * and if modified the entry will be marked for reimport. |
| 72 | * @param[in] dependencyFolder Folder in which dependeny files reside. Only relevant if @p dependencies is |
| 73 | * provided. |
| 74 | * @return An array of the same size as the @p entries array, containing value true if |
| 75 | * an asset should be imported, or false otherwise. |
| 76 | */ |
| 77 | static Vector<bool> (const nlohmann::json& entries, const Path& inputFolder, |
| 78 | time_t lastUpdateTime, bool forceImport, const nlohmann::json* dependencies = nullptr, |
| 79 | const Path& dependencyFolder = Path::BLANK); |
| 80 | |
| 81 | /** |
| 82 | * Scans the provided folder for any files that are currently not part of the provided JSON entries. If some are |
| 83 | * found they are appended to the JSON entry array. Returns true if any new files were found, false otherwise. |
| 84 | * |
| 85 | * @param[in] folder Folder to check for new entries. |
| 86 | * @param[in] type Type of entries in the folder. Determines the type of JSON data generated. |
| 87 | * @param[in, out] entries Current data file entries. |
| 88 | */ |
| 89 | static bool (const Path& folder, AssetType type, nlohmann::json& entries); |
| 90 | |
| 91 | /** |
| 92 | * Updates the resource manifest from the UUID's and paths provided in the JSON. |
| 93 | * |
| 94 | * @param[in] folder Folder containing the imported assets the manifest will point to. |
| 95 | * @param[in] entries JSON entries detailing each asset. |
| 96 | * @param[in] manifest Manifest in which to register the assets in. |
| 97 | * @param[in] type Type of assets we're registering. |
| 98 | */ |
| 99 | static void (const Path& folder, const nlohmann::json& entries, |
| 100 | const SPtr<ResourceManifest>& manifest, AssetType type); |
| 101 | |
| 102 | /** Writes a timestamp with the current date and time in the specified file. */ |
| 103 | static void writeTimestamp(const Path& file); |
| 104 | |
| 105 | /** |
| 106 | * Checks all files in the specified folder for modifications compared to the time stored in the timestamp file. |
| 107 | * Timestamp file must have been saved using writeTimestamp(). Returns 0 if no changes, 1 if timestamp is out date, |
| 108 | * or 2 if timestamp doesn't exist. @p lastUpdateTime will contain the time stored in the timestamp, if it exist. |
| 109 | */ |
| 110 | static UINT32 checkForModifications(const Path& folder, const Path& timeStampFile, time_t& lastUpdateTime); |
| 111 | |
| 112 | /** Checks if the shader compiled properly and reports the problem if it hasn't. Returns true if shader is valid. */ |
| 113 | static bool verifyAndReportShader(const HShader& shader); |
| 114 | |
| 115 | /** Loads the shader at the specified path, updates its bytecode if required, and re-saves the shader file. */ |
| 116 | static void updateShaderBytecode(const Path& path); |
| 117 | |
| 118 | /** Constructs a GUIElementStyle from the provided JSON entry. */ |
| 119 | static GUIElementStyle (const nlohmann::json& entry, const GUIElementStyleLoader& loader); |
| 120 | }; |
| 121 | |
| 122 | /** |
| 123 | * Determines how are resources for GUIElementStyle loaded, when it is being decoded from a non-binary format that only |
| 124 | * stores resource names. |
| 125 | */ |
| 126 | class BS_EXPORT GUIElementStyleLoader |
| 127 | { |
| 128 | public: |
| 129 | virtual ~GUIElementStyleLoader() = default; |
| 130 | |
| 131 | /** Loads a font with the specified name. */ |
| 132 | virtual HFont loadFont(const String& name) const = 0; |
| 133 | |
| 134 | /** Loads a sprite texture with the specified name. */ |
| 135 | virtual HSpriteTexture loadTexture(const String& name) const = 0; |
| 136 | }; |
| 137 | |
| 138 | /** Handles loading of GUIELementStyle resources by retrieving them from the builtin resources folder. */ |
| 139 | class BS_EXPORT BuiltinResourceGUIElementStyleLoader final : public GUIElementStyleLoader |
| 140 | { |
| 141 | public: |
| 142 | BuiltinResourceGUIElementStyleLoader(const Path& fontPath, const Path& texturePath); |
| 143 | |
| 144 | /** Loads a font with the specified name. */ |
| 145 | HFont loadFont(const String& name) const override; |
| 146 | |
| 147 | /** Loads a sprite texture with the specified name. */ |
| 148 | HSpriteTexture loadTexture(const String& name) const override; |
| 149 | |
| 150 | private: |
| 151 | Path mFontPath; |
| 152 | Path mTexturePath; |
| 153 | }; |
| 154 | /** @} */ |
| 155 | } |
| 156 | |