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
9namespace 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 importAssets(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> generateImportFlags(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 updateJSON(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 updateManifest(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 loadGUIStyleFromJSON(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