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 // Get an asset by hash
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#ifdef __CSE_EDITOR__
112 CreateAssetFolder(path, name);
113#endif
114 ReadDirectory(path + name + '/');
115 continue;
116 }
117
118 AssetReference* asset = CreateAsset(path, name);
119 if (asset == nullptr) continue;
120 std::cout << "[pkg] " << asset->name << " (" << asset->extension << ")\n";
121 }
122 closedir(dirp);
123
124 return;
125
126#endif //================================================
127#ifdef _WIN32 //==========================================
128 WIN32_FIND_DATA data;
129 HANDLE hFind = FindFirstFile(std::string(path + '*').c_str(), &data);
130 if (hFind != INVALID_HANDLE_VALUE) {
131 do {
132 std::string name = data.cFileName;
133
134 if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
135 if (name == "." || name == "..") continue;
136#ifdef __CSE_EDITOR__
137 CreateAssetFolder(path, name);
138#endif
139 ReadDirectory(path + name + '/');
140 continue;
141 }
142
143 AssetReference* asset = CreateAsset(path, name);
144 if (asset == nullptr) continue;
145 std::cout << "[pkg] " << asset->name << " (" << asset->extension << ")\n";
146
147 } while (FindNextFile(hFind, &data) != 0);
148 FindClose(hFind);
149 }
150#endif //================================================
151}
152
153void AssetMgr::ReadPackage(const std::string& path) {
154#if defined(__ANDROID__) || defined(IOS)
155 if(m_zip == nullptr) {
156 SafeLog::Log(path.c_str());
157 m_package_raw = OpenNativeAssetsTxtFile(path);
158 m_zip = zip_stream_open(m_package_raw.c_str(), m_package_raw.length(), 0, 'r');
159 }
160#else
161 if (m_zip == nullptr) m_zip = zip_open(path.c_str(), 0, 'r');
162#endif
163 int zipSize = zip_entries_total(m_zip);
164 for (int i = 0; i < zipSize; ++i) {
165 zip_entry_openbyindex(m_zip, i);
166 {
167 const char* name = zip_entry_name(m_zip);
168 int isdir = zip_entry_isdir(m_zip);
169
170 std::string name_str = name;
171 if(name_str.find("__MACOSX/") != std::string::npos) continue;
172 if(isdir != 0) name_str = name_str.substr(0, name_str.size() - 1);
173 auto rFindIndex = name_str.rfind('/');
174 std::string name_cropped = name_str;
175 std::string path_str = "";
176 if (rFindIndex != std::string::npos) {
177 name_cropped = name_str.substr(rFindIndex + 1);
178 path_str = name_str.substr(0, rFindIndex + 1);
179 }
180 if (isdir != 0) {
181#ifdef __CSE_EDITOR__
182 CreateAssetFolder(path_str, name_cropped);
183#endif
184 continue;
185 }
186 AssetReference* asset = CreateAsset(path_str, name_cropped);
187 if (asset == nullptr) continue;
188 std::cout << "(Packed)[pkg] " << asset->name << " (" << asset->extension << ")\n";
189 }
190 zip_entry_close(m_zip);
191 }
192}
193
195AssetMgr::CreateAsset(const std::string& path, const std::string& name_full, std::string name) {
196 auto asset = new AssetReference();
197 asset->path = path;
198 asset->name_path = path + name_full;
199 asset->id = "File:" + asset->name_path.substr(CSE::AssetsPath().size());
200 asset->name_full = name_full;
201
202 if (name.empty()) {
203 name = name_full;
204 auto name_strs = split(name, '.');
205 asset->extension = name_strs[name_strs.size() - 1];
206 asset->name = name.substr(0, name.rfind('.'));
207 } else {
208 asset->name = name;
209 }
210
211 // Ignore meta files
212 if (asset->extension == "meta") {
213 SAFE_DELETE(asset);
214 return nullptr;
215 }
216
217 asset->hash = GetAssetHash(asset->name_path);
218
219 m_assets.insert(std::pair<std::string, AssetReference*>(asset->hash, asset));
220 m_assetsList.push_back(asset);
221
222 return asset;
223}
224
225AssetMgr::AssetReference* AssetMgr::CreateAssetFolder(const std::string& path, const std::string& name_full) {
226 auto asset = new AssetReference();
227 asset->path = path;
228 asset->name_path = path + name_full;
229 asset->extension = "/\\?folder";
230 asset->id = "Folder:" + asset->name_path.substr(CSE::AssetsPath().size());
231 asset->name_full = name_full;
232 asset->name = name_full;
233
234 asset->hash = "FOLDER" + GetRandomHash(10);
235
236 m_assets.insert(std::pair<std::string, AssetReference*>(asset->hash, asset));
237 m_assetsList.push_back(asset);
238
239 return asset;
240}
241
242void AssetMgr::SetType() {
243
244 for (const auto asset: m_assetsList) {
245 std::string type_str = asset->extension;
246 make_lower(type_str);
247
248 //차후 확장자 리스트를 제작하여 최적화
249 //texture data
250 if (type_str == "jpg" || type_str == "png" || type_str == "dds" || type_str == "hdr") {
251 asset->type = TEX_2D;
252 asset->name += ".texture";
253 asset->class_type = "STexture";
254 continue;
255 }
256
257 //cube map texture data
258 if (type_str == "cbmap") {
259 asset->type = TEX_CUBEMAP;
260 asset->name += ".textureCubeMap";
261 asset->class_type = "STexture";
262 continue;
263 }
264
265 // framebuffer data
266 if (type_str == "framebuffer") {
267 asset->type = FRAMEBUFFER;
268 asset->name += ".frameBuffer";
269 asset->class_type = "SFrameBuffer";
270 continue;
271 }
272
273 //material data
274 if (type_str == "mat") {
275 asset->type = MATERIAL;
276 asset->name += ".material";
277 asset->class_type = "SMaterial";
278 continue;
279 }
280
281 //DAE data
282 if (type_str == "dae") {
283 asset->type = DAE;
284 asset->name += ".prefab";
285 asset->class_type = "SPrefab";
286 {
287 const auto& ani = AppendSubName(CreateAsset(asset->path, asset->name_full, asset->name),
288 "animation");
289 const auto& ske = AppendSubName(CreateAsset(asset->path, asset->name_full, asset->name),
290 "skeleton");
291 const auto& mes = AppendSubName(CreateAsset(asset->path, asset->name_full, asset->name), "mesh");
292
293 ani->type = DAE;
294 ske->type = DAE;
295 mes->type = DAE;
296 ani->class_type = "Animation";
297 ske->class_type = "Skeleton";
298 mes->class_type = "MeshSurface";
299 }
300 continue;
301 }
302
303 //script data
304 if (type_str == "nut") {
305 asset->type = SCRIPT;
306 asset->name += ".script";
307 asset->class_type = "SScriptObject";
308 continue;
309 }
310
311 //shader part data
312 if (type_str == "vert" || type_str == "vs") {
313 asset->type = SHADER;
314 asset->name += ".vert";
315 asset->class_type = "GLProgramHandle";
316 continue;
317 }
318 if (type_str == "frag" || type_str == "fs") {
319 asset->type = SHADER;
320 asset->name += ".frag";
321 asset->class_type = "GLProgramHandle";
322 continue;
323 }
324
325 //shader part data
326 if (type_str == "shader") {
327 asset->type = SHADER_HANDLE;
328 asset->name += ".shader";
329 asset->class_type = "SShaderGroup";
330 continue;
331 }
332
333 //prefab data
334 if (type_str == "prefab") {
335 asset->type = PREFAB;
336 asset->name += ".prefab";
337 asset->class_type = "SPrefab";
338 continue;
339 }
340
341 //scene data
342 if (type_str == "scene") {
343 asset->type = SCENE;
344 asset->name += ".scene";
345 continue;
346 }
347
348 //ini data
349 if (type_str == "ini") {
350 asset->type = INI;
351 asset->name += ".ini";
352 continue;
353 }
354
355 if (asset->type == NONE) {
356 //txt data
357 asset->type = TXT;
358 asset->name += ".text";
359 }
360
361 }
362
363}
364
365AssetMgr::AssetReference* AssetMgr::AppendSubName(AssetMgr::AssetReference* asset, const std::string& sub_name) {
366 std::string sub = '?' + sub_name;
367 asset->id += sub;
368 asset->name += sub;
369 return asset;
370}
371
372std::list<AssetMgr::AssetReference*> AssetMgr::GetAssets(TYPE type) const {
373 std::list<AssetReference*> result;
374
375 for (const auto& asset: m_assetsList) {
376 if (asset->type == type) {
377 result.push_back(asset);
378 }
379 }
380
381 return result;
382}
383
384std::string AssetMgr::LoadAssetFile(const std::string& path) {
385 if (Settings::IsAssetsPacked() == false)
386 return OpenNativeAssetsTxtFile(path);
387
388 std::string result;
389 std::string path_convert;
390 const auto& zip = CORE->GetResMgrCore()->m_assetManager->m_zip;
391 if (path.find("/../") != std::string::npos) {
392 auto path_split = split(path, '/');
393 std::stack<std::string> path_stack;
394 for (const auto& part: path_split) {
395 if (part == "..") {
396 path_stack.pop();
397 continue;
398 }
399 path_stack.push(part);
400 }
401 while (!path_stack.empty()) {
402 path_convert = path_stack.top() + '/' + path_convert;
403 path_stack.pop();
404 }
405 path_convert = path_convert.substr(0, path_convert.size() - 1);
406 } else {
407 path_convert = path;
408 }
409 zip_entry_open(zip, path_convert.c_str());
410 {
411 char* buf = nullptr;
412 size_t bufsize = 0;
413
414 zip_entry_read(zip, (void**) &buf, &bufsize);
415 result = std::string(buf, bufsize);
416 free(buf);
417 }
418 zip_entry_close(zip);
419 return result;
420}
421
422std::string AssetMgr::GetAssetHash(const std::string& path) {
423 std::string meta = LoadAssetFile(path + ".meta");
424 std::string&& hash = "";
425 if (!meta.empty()) {
426 const XNode* root = XFILE().loadBuffer(std::move(meta));
427 const auto& hashData = root->getNode("hash-data");
428 hash = hashData.getAttribute("hash").value;
429 SAFE_DELETE(root);
430 } else {
431 hash = GetRandomHash(16);
432 std::string meta = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
433 "<CSEMETA version=\"1.0.0\">\n"
434 "<hash-data hash=\"" + hash + "\">\n"
435 "\n</hash-data>\n</CSEMETA>";
436 if (!Settings::IsAssetsPacked())
437 SaveTxtFile(path + ".meta", meta);
438 }
439 return hash;
440}
441
442
443#ifdef __ANDROID__
444
445void AssetMgr::SetAssetManager(AAssetManager* obj) {
446 m_assetManager = obj;
447}
448
449
450AAssetManager * AssetMgr::GetAssetManager() {
451 return m_assetManager;
452}
453
454void AssetMgr::SetEnv(JNIEnv *obj) {
455 m_env = obj;
456}
457
458JNIEnv *AssetMgr::GetEnv() {
459 return m_env;
460}
461
462#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