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 | #include "Resources/BsResourceManifest.h" |
4 | #include "Private/RTTI/BsResourceManifestRTTI.h" |
5 | #include "Serialization/BsFileSerializer.h" |
6 | #include "Error/BsException.h" |
7 | |
8 | namespace bs |
9 | { |
10 | ResourceManifest::ResourceManifest(const ConstructPrivately& dummy) |
11 | { |
12 | |
13 | } |
14 | |
15 | ResourceManifest::ResourceManifest(const String& name) |
16 | :mName(name) |
17 | { |
18 | |
19 | } |
20 | |
21 | SPtr<ResourceManifest> ResourceManifest::create(const String& name) |
22 | { |
23 | return bs_shared_ptr_new<ResourceManifest>(name); |
24 | } |
25 | |
26 | SPtr<ResourceManifest> ResourceManifest::createEmpty() |
27 | { |
28 | return bs_shared_ptr_new<ResourceManifest>(ConstructPrivately()); |
29 | } |
30 | |
31 | void ResourceManifest::registerResource(const UUID& uuid, const Path& filePath) |
32 | { |
33 | auto iterFind = mUUIDToFilePath.find(uuid); |
34 | |
35 | if(iterFind != mUUIDToFilePath.end()) |
36 | { |
37 | if (iterFind->second != filePath) |
38 | { |
39 | mFilePathToUUID.erase(iterFind->second); |
40 | |
41 | mUUIDToFilePath[uuid] = filePath; |
42 | mFilePathToUUID[filePath] = uuid; |
43 | } |
44 | } |
45 | else |
46 | { |
47 | auto iterFind2 = mFilePathToUUID.find(filePath); |
48 | if (iterFind2 != mFilePathToUUID.end()) |
49 | mUUIDToFilePath.erase(iterFind2->second); |
50 | |
51 | mUUIDToFilePath[uuid] = filePath; |
52 | mFilePathToUUID[filePath] = uuid; |
53 | } |
54 | } |
55 | |
56 | void ResourceManifest::unregisterResource(const UUID& uuid) |
57 | { |
58 | auto iterFind = mUUIDToFilePath.find(uuid); |
59 | |
60 | if(iterFind != mUUIDToFilePath.end()) |
61 | { |
62 | mFilePathToUUID.erase(iterFind->second); |
63 | mUUIDToFilePath.erase(uuid); |
64 | } |
65 | } |
66 | |
67 | bool ResourceManifest::uuidToFilePath(const UUID& uuid, Path& filePath) const |
68 | { |
69 | auto iterFind = mUUIDToFilePath.find(uuid); |
70 | |
71 | if(iterFind != mUUIDToFilePath.end()) |
72 | { |
73 | filePath = iterFind->second; |
74 | return true; |
75 | } |
76 | else |
77 | { |
78 | filePath = Path::BLANK; |
79 | return false; |
80 | } |
81 | } |
82 | |
83 | bool ResourceManifest::filePathToUUID(const Path& filePath, UUID& outUUID) const |
84 | { |
85 | auto iterFind = mFilePathToUUID.find(filePath); |
86 | |
87 | if(iterFind != mFilePathToUUID.end()) |
88 | { |
89 | outUUID = iterFind->second; |
90 | return true; |
91 | } |
92 | else |
93 | { |
94 | outUUID = UUID::EMPTY; |
95 | return false; |
96 | } |
97 | } |
98 | |
99 | bool ResourceManifest::uuidExists(const UUID& uuid) const |
100 | { |
101 | auto iterFind = mUUIDToFilePath.find(uuid); |
102 | |
103 | return iterFind != mUUIDToFilePath.end(); |
104 | } |
105 | |
106 | bool ResourceManifest::filePathExists(const Path& filePath) const |
107 | { |
108 | auto iterFind = mFilePathToUUID.find(filePath); |
109 | |
110 | return iterFind != mFilePathToUUID.end(); |
111 | } |
112 | |
113 | void ResourceManifest::save(const SPtr<ResourceManifest>& manifest, const Path& path, const Path& relativePath) |
114 | { |
115 | if(relativePath.isEmpty()) |
116 | { |
117 | FileEncoder fs(path); |
118 | fs.encode(manifest.get()); |
119 | } |
120 | else |
121 | { |
122 | SPtr<ResourceManifest> copy = create(manifest->mName); |
123 | |
124 | for (auto& elem : manifest->mFilePathToUUID) |
125 | { |
126 | if (!relativePath.includes(elem.first)) |
127 | { |
128 | BS_EXCEPT(InvalidStateException, "Path in resource manifest cannot be made relative to: \""+ |
129 | relativePath.toString() + "\". Path: \""+ elem.first.toString() + "\""); |
130 | } |
131 | |
132 | Path elementRelativePath = elem.first.getRelative(relativePath); |
133 | |
134 | copy->mFilePathToUUID[elementRelativePath] = elem.second; |
135 | } |
136 | |
137 | for (auto& elem : manifest->mUUIDToFilePath) |
138 | { |
139 | if (!relativePath.includes(elem.second)) |
140 | { |
141 | BS_EXCEPT(InvalidStateException, "Path in resource manifest cannot be made relative to: \""+ |
142 | relativePath.toString() + "\". Path: \""+ elem.second.toString() + "\""); |
143 | } |
144 | |
145 | Path elementRelativePath = elem.second.getRelative(relativePath); |
146 | |
147 | copy->mUUIDToFilePath[elem.first] = elementRelativePath; |
148 | } |
149 | |
150 | FileEncoder fs(path); |
151 | fs.encode(copy.get()); |
152 | } |
153 | } |
154 | |
155 | SPtr<ResourceManifest> ResourceManifest::load(const Path& path, const Path& relativePath) |
156 | { |
157 | FileDecoder fs(path); |
158 | SPtr<ResourceManifest> manifest = std::static_pointer_cast<ResourceManifest>(fs.decode()); |
159 | |
160 | if(relativePath.isEmpty()) |
161 | return manifest; |
162 | |
163 | SPtr<ResourceManifest> copy = create(manifest->mName); |
164 | |
165 | for(auto& elem : manifest->mFilePathToUUID) |
166 | { |
167 | Path absPath = elem.first.getAbsolute(relativePath); |
168 | copy->mFilePathToUUID[absPath] = elem.second; |
169 | } |
170 | |
171 | for(auto& elem : manifest->mUUIDToFilePath) |
172 | { |
173 | Path absPath = elem.second.getAbsolute(relativePath); |
174 | copy->mUUIDToFilePath[elem.first] = absPath; |
175 | } |
176 | |
177 | return copy; |
178 | } |
179 | |
180 | RTTITypeBase* ResourceManifest::getRTTIStatic() |
181 | { |
182 | return ResourceManifestRTTI::instance(); |
183 | } |
184 | |
185 | RTTITypeBase* ResourceManifest::getRTTI() const |
186 | { |
187 | return ResourceManifest::getRTTIStatic(); |
188 | } |
189 | } |