CSEngine
Loading...
Searching...
No Matches
AssetMgr.cpp
1//
2// Created by ounols on 19. 6. 6.
3//
4
5#include "AssetMgr.h"
6#include "../MacroDef.h"
7#include "../Util/AssetsDef.h"
8#include "../Util/MoreString.h"
9#include "../Util/SafeLog.h"
10#include "../Util/Loader/XML/XML.h"
11#include "EngineCore.h"
12#include "ResMgr.h"
13#include <iostream>
14#include <stack>
15
16#if defined(__linux__) || defined(__APPLE_CC__)
17
18#include <sys/types.h>
19#include <dirent.h>
20
21#elif _WIN32
22
23#include <windows.h>
24
25#endif
26#ifdef __ANDROID__
27#include <android/asset_manager.h>
28#include <android/asset_manager_jni.h>
29#include <android/log.h>
30#include <Manager/ResMgr.h>
31#include <Util/SafeLog.h>
32
33#endif
34using namespace CSE;
35
36AssetMgr::AssetMgr() = default;
37
38AssetMgr::~AssetMgr() {
39 Exterminate();
40}
41
42
43void AssetMgr::Exterminate() {
44 m_assets.clear();
45
46 for (auto& asset : m_assetsList) {
47 SAFE_DELETE(asset);
48 }
49
50#ifdef __ANDROID__
51 SAFE_DELETE(m_assetManager);
52#endif
53
54 zip_close(m_zip);
55 m_assetsList.clear();
56}
57
58void AssetMgr::LoadAssets(bool isPacked) {
59
60 if (!isPacked) {
61 ReadDirectory(CSE::NativeAssetsPath());
62 } else {
63 ReadPackage(CSE::NativeAssetsPath() + "Assets.zip");
64 }
65 SetType();
66}
67
68AssetMgr::AssetReference* AssetMgr::GetAsset(const std::string& name) const {
69
70 if (m_assets.count(name) > 0) return m_assets.at(name);
71
72 std::string lowerName = name;
73 make_lower(lowerName);
74 for (const auto& asset : m_assetsList) {
75 if (make_lower_copy(asset->name) == lowerName) return asset;
76 if (make_lower_copy(asset->id) == lowerName) return asset;
77 if (make_lower_copy(asset->name_path) == lowerName) return asset;
78 if (make_lower_copy(asset->name_full) == lowerName) return asset;
79 }
80 auto errorLog = "[Assets Warning] " + name + " does not exist.";
81 SafeLog::Log(errorLog.c_str());
82 return nullptr;
83}
84
85void AssetMgr::ReadDirectory(const std::string& path) {
86#ifdef __ANDROID__
87 return;
88 AAssetDir* assetDir = AAssetManager_openDir(m_assetManager, "");
89 const char* filename = (const char*)NULL;
90 SafeLog::Log("ReadDirectory");
91 while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
92 AAsset* asset = AAssetManager_open(m_assetManager, filename, AASSET_MODE_STREAMING);
93
94 std::string name = filename;
95 SafeLog::Log(name.c_str());
96 AssetReference* assetReference = CreateAsset(path, name);
97
98 AAsset_close(asset);
99 }
100 AAssetDir_close(assetDir);
101#elif defined(__linux__) || defined(__APPLE_CC__) //======================================
102
103 DIR* dirp = opendir(path.c_str());
104 struct dirent* dp;
105 while ((dp = readdir(dirp)) != nullptr) {
106
107 std::string name = dp->d_name;
108
109 if (dp->d_type == DT_DIR) {
110 if (name == "." || name == "..") continue;
111
112 ReadDirectory(path + name + '/');
113 continue;
114 }
115
116 AssetReference* asset = CreateAsset(path, name);
117 if (asset == nullptr) continue;
118 std::cout << "[pkg] " << asset->name << " (" << asset->extension << ")\n";
119 }
120 closedir(dirp);
121
122 return;
123
124#endif //================================================
125#ifdef _WIN32 //==========================================
126 WIN32_FIND_DATA data;
127 HANDLE hFind = FindFirstFile(std::string(path + '*').c_str(), &data);
128 if (hFind != INVALID_HANDLE_VALUE) {
129 do {
130 std::string name = data.cFileName;
131
132 if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
133 if (name == "." || name == "..") continue;
134
135 ReadDirectory(path + name + '/');
136 continue;
137 }
138
139 AssetReference* asset = CreateAsset(path, name);
140 if (asset == nullptr) continue;
141 std::cout << "[pkg] " << asset->name << " (" << asset->extension << ")\n";
142
143 } while (FindNextFile(hFind, &data) != 0);
144 FindClose(hFind);
145 }
146#endif //================================================
147}
148
149void AssetMgr::ReadPackage(const std::string& path) {
150#if defined(__ANDROID__) || defined(IOS)
151 if(m_zip == nullptr) {
152 SafeLog::Log(path.c_str());
153 m_package_raw = OpenNativeAssetsTxtFile(path);
154 m_zip = zip_stream_open(m_package_raw.c_str(), m_package_raw.length(), 0, 'r');
155 }
156#else
157 if (m_zip == nullptr) m_zip = zip_open(path.c_str(), 0, 'r');
158#endif
159 int zipSize = zip_entries_total(m_zip);
160 for (int i = 0; i < zipSize; ++i) {
161 zip_entry_openbyindex(m_zip, i);
162 {
163 const char* name = zip_entry_name(m_zip);
164 std::string name_str = name;
165 auto rFindIndex = name_str.rfind('/');
166 std::string name_cropped = name_str;
167 std::string path_str = "";
168 if (rFindIndex != std::string::npos) {
169 name_cropped = name_str.substr(rFindIndex + 1);
170 path_str = name_str.substr(0, rFindIndex + 1);
171 }
172 int isdir = zip_entry_isdir(m_zip);
173 if (isdir != 0) continue;
174 AssetReference* asset = CreateAsset(path_str, name_cropped);
175 if (asset == nullptr) continue;
176 std::cout << "(Packed)[pkg] " << asset->name << " (" << asset->extension << ")\n";
177 }
178 zip_entry_close(m_zip);
179 }
180}
181
183AssetMgr::CreateAsset(const std::string& path, const std::string& name_full, std::string name) {
184 auto asset = new AssetReference();
185 asset->path = path;
186 asset->name_path = path + name_full;
187 asset->id = "File:" + asset->name_path.substr(CSE::AssetsPath().size());
188 asset->name_full = name_full;
189
190 if (name.empty()) {
191 name = name_full;
192 auto name_strs = split(name, '.');
193 asset->extension = name_strs[name_strs.size() - 1];
194 asset->name = name.substr(0, name.rfind('.'));
195 } else {
196 asset->name = name;
197 }
198
199 // Ignore meta files
200 if (asset->extension == "meta") {
201 SAFE_DELETE(asset);
202 return nullptr;
203 }
204
205 asset->hash = GetAssetHash(asset->name_path);
206
207 m_assets.insert(std::pair<std::string, AssetReference*>(asset->hash, asset));
208 m_assetsList.push_back(asset);
209
210 return asset;
211}
212
213void AssetMgr::SetType() {
214
215 for (const auto asset : m_assetsList) {
216 std::string type_str = asset->extension;
217 make_lower(type_str);
218
219 //차후 확장자 리스트를 제작하여 최적화
220 //texture data
221 if (type_str == "jpg" || type_str == "png" || type_str == "dds" || type_str == "hdr") {
222 asset->type = TEX_2D;
223 asset->name += ".texture";
224 continue;
225 }
226
227 //cube map texture data
228 if (type_str == "cbmap") {
229 asset->type = TEX_CUBEMAP;
230 asset->name += ".textureCubeMap";
231 continue;
232 }
233
234 // framebuffer data
235 if (type_str == "framebuffer") {
236 asset->type = FRAMEBUFFER;
237 asset->name += ".frameBuffer";
238 continue;
239 }
240
241 //material data
242 if (type_str == "mat") {
243 asset->type = MATERIAL;
244 asset->name += ".material";
245 continue;
246 }
247
248 //DAE data
249 if (type_str == "dae") {
250 asset->type = DAE;
251 asset->name += ".prefab";
252 {
253 AppendSubName(CreateAsset(asset->name_path, asset->name_full, asset->name), "animation")->type = DAE;
254 AppendSubName(CreateAsset(asset->name_path, asset->name_full, asset->name), "skeleton")->type = DAE;
255 AppendSubName(CreateAsset(asset->name_path, asset->name_full, asset->name), "mesh")->type = DAE;
256 }
257 continue;
258 }
259
260 //script data
261 if (type_str == "nut") {
262 asset->type = SCRIPT;
263 asset->name += ".script";
264 continue;
265 }
266
267 //shader part data
268 if (type_str == "vert" || type_str == "vs") {
269 asset->type = SHADER;
270 asset->name += ".vert";
271 continue;
272 }
273 if (type_str == "frag" || type_str == "fs") {
274 asset->type = SHADER;
275 asset->name += ".frag";
276 continue;
277 }
278
279 //shader part data
280 if (type_str == "shader") {
281 asset->type = SHADER_HANDLE;
282 asset->name += ".shader";
283 continue;
284 }
285
286 //prefab data
287 if (type_str == "prefab") {
288 asset->type = PREFAB;
289 asset->name += ".prefab";
290 continue;
291 }
292
293 //scene data
294 if (type_str == "scene") {
295 asset->type = SCENE;
296 asset->name += ".scene";
297 continue;
298 }
299
300 //ini data
301 if (type_str == "ini") {
302 asset->type = INI;
303 asset->name += ".ini";
304 continue;
305 }
306
307 if (asset->type == NONE) {
308 //txt data
309 asset->type = TXT;
310 asset->name += ".text";
311 }
312
313 }
314
315}
316
317AssetMgr::AssetReference* AssetMgr::AppendSubName(AssetMgr::AssetReference* asset, const std::string& sub_name) {
318 std::string sub = '?' + sub_name;
319 asset->id += sub;
320 asset->name += sub;
321 return asset;
322}
323
324std::list<AssetMgr::AssetReference*> AssetMgr::GetAssets(TYPE type) const {
325 std::list<AssetReference*> result;
326
327 for (const auto& asset : m_assetsList) {
328 if (asset->type == type) {
329 result.push_back(asset);
330 }
331 }
332
333 return result;
334}
335
336std::string AssetMgr::LoadAssetFile(const std::string& path) {
337 if (Settings::IsAssetsPacked() == false)
338 return OpenNativeAssetsTxtFile(path);
339
340 std::string result;
341 std::string path_convert;
342 const auto& zip = CORE->GetResMgrCore()->m_assetManager->m_zip;
343 if (path.find("/../") != std::string::npos) {
344 auto path_split = split(path, '/');
345 std::stack<std::string> path_stack;
346 for (const auto& part : path_split) {
347 if (part == "..") {
348 path_stack.pop();
349 continue;
350 }
351 path_stack.push(part);
352 }
353 while (!path_stack.empty()) {
354 path_convert = path_stack.top() + '/' + path_convert;
355 path_stack.pop();
356 }
357 path_convert = path_convert.substr(0, path_convert.size() - 1);
358 }
359 else {
360 path_convert = path;
361 }
362 zip_entry_open(zip, path_convert.c_str());
363 {
364 char* buf = nullptr;
365 size_t bufsize = 0;
366
367 zip_entry_read(zip, (void**) &buf, &bufsize);
368 result = std::string(buf, bufsize);
369 free(buf);
370 }
371 zip_entry_close(zip);
372 return result;
373}
374
375std::string AssetMgr::GetAssetHash(const std::string& path) {
376 std::string meta = LoadAssetFile(path + ".meta");
377 std::string&& hash = "";
378 if (!meta.empty()) {
379 const XNode* root = XFILE().loadBuffer(std::move(meta));
380 const auto& hashData = root->getNode("hash-data");
381 hash = hashData.getAttribute("hash").value;
382 SAFE_DELETE(root);
383 } else {
384 hash = GetRandomHash(16);
385 std::string meta = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
386 "<CSEMETA version=\"1.0.0\">\n"
387 "<hash-data hash=\"" + hash + "\">\n"
388 "\n</hash-data>\n</CSEMETA>";
389 if (!Settings::IsAssetsPacked())
390 SaveTxtFile(path + ".meta", meta);
391 }
392 return hash;
393}
394
395
396#ifdef __ANDROID__
397
398void AssetMgr::SetAssetManager(AAssetManager* obj) {
399 m_assetManager = obj;
400}
401
402
403AAssetManager * AssetMgr::GetAssetManager() {
404 return m_assetManager;
405}
406
407void AssetMgr::SetEnv(JNIEnv *obj) {
408 m_env = obj;
409}
410
411JNIEnv *AssetMgr::GetEnv() {
412 return m_env;
413}
414
415#endif
Definition XML.h:77
Definition XML.h:43
int zip_entry_isdir(struct zip_t *zip)
Definition zip.cpp:1186
const char * zip_entry_name(struct zip_t *zip)
Definition zip.cpp:1168
struct zip_t * zip_open(const char *zipname, int level, char mode)
Definition zip.cpp:779
struct zip_t * zip_stream_open(const char *stream, size_t size, int level, char mode)
Definition zip.cpp:1481
void zip_close(struct zip_t *zip)
Definition zip.cpp:836
int zip_entry_open(struct zip_t *zip, const char *entryname)
Definition zip.cpp:858
int zip_entry_openbyindex(struct zip_t *zip, int index)
Definition zip.cpp:1014
int zip_entries_total(struct zip_t *zip)
Definition zip.cpp:1417
int zip_entry_close(struct zip_t *zip)
Definition zip.cpp:1087
ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize)
Definition zip.cpp:1295